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