|
|
1.1 root 1: /*
2: * Copyright (c) 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that this notice is preserved and that due credit is given
7: * to the University of California at Berkeley. The name of the University
8: * may not be used to endorse or promote products derived from this
9: * software without specific prior written permission. This software
10: * is provided ``as is'' without express or implied warranty.
11: */
12:
13: #ifndef lint
14: char copyright[] =
15: "@(#) Copyright (c) 1988 Regents of the University of California.\n\
16: All rights reserved.\n";
17: #endif /* not lint */
18:
19: #ifndef lint
20: static char sccsid[] = "@(#)mset.c 3.2 (Berkeley) 3/28/88";
21: #endif /* not lint */
22:
23: /*
24: * this program outputs the user's 3270 mapping table in a form suitable
25: * for inclusion in the environment. Typically, this might be used
26: * by:
27: * setenv MAP3270 "`mset`"
28: */
29:
30: #include <stdio.h>
31: #if defined(unix)
32: #include <strings.h>
33: #else /* defined(unix) */
34: #include <string.h>
35: #endif /* defined(unix) */
36: #include "../ctlr/function.h"
37:
38: #include "state.h"
39: #include "../api/astosc.h"
40:
41: #include "../general/globals.h"
42: #include "map3270.ext"
43:
44: struct regstate {
45: char *result;
46: char *match_start;
47: char *match_end; /* start of NEXT state's match string */
48: struct regstate *forward;
49: struct regstate *backward;
50: };
51:
52: static struct regstate regstates[500], *rptr= 0; /* for sorting states */
53: static char array[5000]; /* lot's of room */
54: static int toshell = 0; /* export to shell */
55: static int numbchars = 0; /* number of chars in envir. var */
56:
57: static int
58: MyStrcmp(str1, str2)
59: char *str1, *str2;
60: {
61: if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0
62: && strlen(str1) != strlen(str2)) {
63: return(strlen(str1) - strlen(str2));
64: }
65: return(strcmp(str1, str2));
66: }
67:
68: static void
69: forwRegister(regptr, sptr)
70: struct regstate *regptr, *sptr;
71: {
72:
73: regptr->forward = sptr->forward;
74: regptr->backward = sptr;
75: (sptr->forward)->backward = regptr;
76: sptr->forward = regptr;
77: }
78:
79: static void
80: backRegister(regptr, sptr)
81: struct regstate *regptr, *sptr;
82: {
83:
84: regptr->forward = sptr;
85: regptr->backward = sptr->backward;
86: (sptr->backward)->forward = regptr;
87: sptr->backward = regptr;
88: }
89:
90: static struct regstate *
91: doRegister(regptr)
92: register struct regstate *regptr;
93: {
94: static struct regstate *pivot = regstates;
95: register struct regstate *sptr = pivot;
96: int check;
97:
98: if (pivot == regstates) { /* first time called */
99: pivot->forward = regptr;
100: regptr->backward = pivot++;
101: pivot->backward = regptr;
102: regptr->forward = pivot++;
103: return(++regptr);
104: }
105: if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) {
106: while (check < 0) {
107: if (sptr->backward == regstates) {
108: backRegister(regptr, sptr);
109: pivot = pivot->backward;
110: return(++regptr);
111: }
112: sptr = sptr->backward;
113: check = MyStrcmp(regptr->result, sptr->result);
114: }
115: forwRegister(regptr, sptr);
116: pivot = pivot->backward;
117: return(++regptr);
118: }
119: while (check > 0) {
120: if ((sptr->forward)->result == 0) {
121: forwRegister(regptr, sptr);
122: pivot = pivot->forward;
123: return(++regptr);
124: }
125: sptr = sptr->forward;
126: check = MyStrcmp(regptr->result, sptr->result);
127: }
128: backRegister(regptr, sptr);
129: if (pivot->forward->result) {
130: pivot = pivot->forward;
131: }
132: return(++regptr);
133: }
134:
135: static char *
136: addString(strcount, character)
137: int strcount;
138: char character;
139: {
140: static char *string = array;
141: int i;
142:
143: if (rptr->match_start == 0) {
144: rptr->match_start = string;
145: for (i=0; i < strcount; i++) {
146: *string++ = *((rptr-1)->match_start+i);
147: }
148: }
149: *string++ = character;
150: return(string);
151: }
152:
153: static char savename[20] = " "; /* for deciding if name is new */
154:
155: static void
156: printString(string, begin, tc_name)
157: register char *string;
158: char *begin, *tc_name;
159: {
160: register char *st1, *st2;
161: register int pchar;
162: static char suffix = 'A';
163: int new = strcmp(savename, tc_name);
164: char delim = new ? ';' : '|';
165: char *uncontrol();
166:
167: st1 = begin;
168:
169: numbchars += 5 + (new ? strlen(tc_name) : -1);
170: if (toshell && numbchars > 1011) {
171: new = 1;
172: delim = ';';
173: numbchars = 5 + strlen(tc_name);
174: printf(";\nsetenv MAP3270%c ", suffix++);
175: }
176: if (strcmp(" ", savename)) {
177: if (toshell) {
178: printf("%c%c", '\\', delim);
179: }
180: else {
181: printf("%c", delim);
182: }
183: }
184: else {
185: numbchars -= 2;
186: }
187: if (toshell && new) {
188: printf("%s=%c'", tc_name,'\\');
189: }
190: else if (new) {
191: printf("%s='", tc_name);
192: }
193: else if (toshell) {
194: printf("%c'", '\\');
195: }
196: else {
197: printf("'");
198: }
199: (void) strcpy(savename, tc_name);
200: while (st1 != string) {
201: if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */
202: numbchars = 0;
203: printf(";\nsetenv MAP3270%c ", suffix++);
204: }
205: pchar = 0xff&(*st1++);
206: switch (pchar) {
207: case '"':
208: case '!':
209: case '$':
210: case '(':
211: case ')':
212: case ' ':
213: case ';':
214: case '&':
215: case '|':
216: case '>':
217: case '<':
218: case '`':
219: case '#':
220: numbchars += 2;
221: if (toshell) {
222: printf("%c%c", '\\', pchar);
223: }
224: else {
225: printf("%c", pchar);
226: }
227: break;
228: case '\\':
229: case '\'':
230: numbchars += 4;
231: if (toshell) {
232: printf("%c%c%c%c", '\\', '\\', '\\', pchar);
233: }
234: else {
235: printf("%c%c", '\\', pchar);
236: }
237: break;
238: case '^':
239: numbchars += 3;
240: if (toshell) {
241: printf("%c%c%c", '\\', '\\', pchar);
242: }
243: else {
244: printf("%c%c", '\\', pchar);
245: }
246: break;
247: default:
248: st2 = uncontrol(pchar);
249: while ((pchar = *st2++) != 0) {
250: switch (pchar) {
251: case '"':
252: case '!':
253: case '$':
254: case '(':
255: case ')':
256: case ' ':
257: case ';':
258: case '&':
259: case '|':
260: case '>':
261: case '<':
262: case '`':
263: case '#':
264: case '\\':
265: case '\'':
266: if (toshell) {
267: numbchars += 2;
268: printf("%c%c", '\\', pchar);
269: }
270: else {
271: printf("%c", pchar);
272: }
273: break;
274: default:
275: numbchars++;
276: printf("%c", pchar);
277: break;
278: }
279: }
280: break;
281: }
282: }
283: numbchars += 2;
284: if (toshell) {
285: printf("%c'", '\\');
286: }
287: else {
288: printf("'");
289: }
290: }
291:
292: static void
293: recurse(strcount, head)
294: state *head;
295: int strcount;
296: {
297: /* if there is a left,
298: * recurse on left,
299: * if there is no down,
300: * print the string to here
301: * else,
302: * add the current match to the string,
303: * recurse.
304: * exit.
305: */
306:
307: if (head->next) {
308: recurse(strcount, head->next);
309: }
310: if (head->result != STATE_GOTO) {
311: rptr->match_end = addString(strcount, head->match);
312: rptr->result = astosc[head->result].name;
313: rptr = doRegister(rptr);
314: } else {
315: (void) addString(strcount, head->match);
316: recurse(strcount+1, head->address);
317: strcount--;
318: }
319: return;
320: }
321:
322:
323: main(argc, argv)
324: int argc;
325: char *argv[];
326: {
327: state *head;
328: char *keybdPointer = (char *) 0;
329: char *commandName = argv[0];
330: extern char *getenv();
331: int picky = 0;
332:
333: while ((argc > 1) && (argv[1][0] == '-')) {
334: if (!strcmp(argv[1], "-picky")) {
335: picky++;
336: } else if (!strcmp(argv[1], "-shell")) {
337: toshell++;
338: } else {
339: fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
340: commandName);
341: exit(1);
342: /*NOTREACHED*/
343: }
344: argv++;
345: argc--;
346: }
347: if (argc == 2) {
348: keybdPointer = argv[1];
349: } else if (argc > 2) {
350: fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
351: commandName);
352: exit(1);
353: /*NOTREACHED*/
354: }
355: head = InitControl(keybdPointer, picky, ascii_to_index);
356: if (!head) {
357: return(1);
358: }
359: if (keybdPointer == 0) {
360: keybdPointer = getenv("KEYBD");
361: }
362: if (keybdPointer == 0) {
363: keybdPointer = getenv("TERM");
364: }
365: if (keybdPointer == 0) {
366: keybdPointer = "3a"; /* use 3a as the terminal */
367: }
368: if (toshell) {
369: printf("set noglob;\nsetenv MAP3270 ");
370: }
371: printf("%s{", keybdPointer);
372: numbchars = 2 + strlen(keybdPointer);
373: /* now, run through the table registering entries */
374: rptr = regstates + 2;
375: recurse(0, head);
376: /* now print them out */
377: for (rptr = regstates[0].forward; rptr->result != 0;
378: rptr = rptr->forward) {
379: printString(rptr->match_end, rptr->match_start, rptr->result);
380: }
381: if (toshell) {
382: printf("%c;};\nunset noglob;\n", '\\');
383: }
384: else {
385: printf(";}\n");
386: }
387: return(0);
388: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.