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