xref: /csrg-svn/usr.bin/tn3270/ascii/mset.c (revision 31176)
131056Sminshall /*
231056Sminshall  *	Copyright (c) 1984, 1985, 1986 by the Regents of the
331056Sminshall  *	University of California and by Gregory Glenn Minshall.
431056Sminshall  *
531056Sminshall  *	Permission to use, copy, modify, and distribute these
631056Sminshall  *	programs and their documentation for any purpose and
731056Sminshall  *	without fee is hereby granted, provided that this
831056Sminshall  *	copyright and permission appear on all copies and
931056Sminshall  *	supporting documentation, the name of the Regents of
1031056Sminshall  *	the University of California not be used in advertising
1131056Sminshall  *	or publicity pertaining to distribution of the programs
1231056Sminshall  *	without specific prior permission, and notice be given in
1331056Sminshall  *	supporting documentation that copying and distribution is
1431056Sminshall  *	by permission of the Regents of the University of California
1531056Sminshall  *	and by Gregory Glenn Minshall.  Neither the Regents of the
1631056Sminshall  *	University of California nor Gregory Glenn Minshall make
1731056Sminshall  *	representations about the suitability of this software
1831056Sminshall  *	for any purpose.  It is provided "as is" without
1931056Sminshall  *	express or implied warranty.
2031056Sminshall  */
2131056Sminshall 
2231056Sminshall #ifndef	lint
2331056Sminshall static	char	sccsid[] = "@(#)mset.c	3.1  10/29/86";
2431056Sminshall #endif	/* ndef lint */
2531056Sminshall 
2631056Sminshall /*
2731056Sminshall  * this program outputs the user's 3270 mapping table in a form suitable
2831056Sminshall  *	for inclusion in the environment.  Typically, this might be used
2931056Sminshall  *	by:
3031056Sminshall  *		setenv MAP3270 "`mset`"
3131056Sminshall  */
3231056Sminshall 
3331100Sminshall #include <stdio.h>
3431100Sminshall #if	defined(unix)
3531056Sminshall #include <strings.h>
3631100Sminshall #else	/* defined(unix) */
3731100Sminshall #include <string.h>
3831100Sminshall #endif	/* defined(unix) */
39*31176Sminshall #include "state.h"
4031056Sminshall #define LETS_SEE_ASCII
41*31176Sminshall #include "m4.out"
4231056Sminshall 
43*31176Sminshall #include "../general/globals.h"
44*31176Sminshall #include "map3270.ext"
4531056Sminshall 
4631056Sminshall struct regstate {
4731056Sminshall 	char *result;
4831056Sminshall 	char *match_start;
4931056Sminshall 	char *match_end;		/* start of NEXT state's match string */
5031056Sminshall 	struct regstate *forward;
5131056Sminshall 	struct regstate *backward;
5231056Sminshall };
5331056Sminshall 
5431056Sminshall static struct regstate regstates[500], *rptr= 0;	/* for sorting states */
5531056Sminshall static char array[5000];		/* lot's of room */
5631056Sminshall static int toshell = 0;			/* export to shell */
5731056Sminshall static int numbchars = 0;		/* number of chars in envir. var */
5831056Sminshall 
5931056Sminshall static void
6031056Sminshall forwRegister(regptr, sptr)
6131056Sminshall struct regstate *regptr, *sptr;
6231056Sminshall {
6331056Sminshall 
6431056Sminshall     regptr->forward = sptr->forward;
6531056Sminshall     regptr->backward = sptr;
6631056Sminshall     (sptr->forward)->backward = regptr;
6731056Sminshall     sptr->forward = regptr;
6831056Sminshall }
6931056Sminshall 
7031056Sminshall static void
7131056Sminshall backRegister(regptr, sptr)
7231056Sminshall struct regstate *regptr, *sptr;
7331056Sminshall {
7431056Sminshall 
7531056Sminshall     regptr->forward = sptr;
7631056Sminshall     regptr->backward = sptr->backward;
7731056Sminshall     (sptr->backward)->forward = regptr;
7831056Sminshall     sptr->backward = regptr;
7931056Sminshall }
8031056Sminshall 
8131056Sminshall static struct regstate *
8231056Sminshall doRegister(regptr)
8331056Sminshall register struct regstate *regptr;
8431056Sminshall {
8531056Sminshall     static struct regstate *pivot = regstates;
8631056Sminshall     register struct regstate *sptr = pivot;
8731056Sminshall     int check;
8831056Sminshall 
8931056Sminshall     if (pivot == regstates) {		/* first time called */
9031056Sminshall 	pivot->forward = regptr;
9131056Sminshall 	regptr->backward = pivot++;
9231056Sminshall 	pivot->backward = regptr;
9331056Sminshall 	regptr->forward = pivot++;
9431056Sminshall 	return(++regptr);
9531056Sminshall     }
9631056Sminshall     if ((check = strcmp(regptr->result, pivot->result)) < 0) {
9731056Sminshall 	while (check < 0) {
9831056Sminshall 	    if (sptr->backward == regstates) {
9931056Sminshall 		backRegister(regptr, sptr);
10031056Sminshall 		pivot = pivot->backward;
10131056Sminshall 		return(++regptr);
10231056Sminshall 	     }
10331056Sminshall 	     sptr = sptr->backward;
10431056Sminshall 	     check = strcmp(regptr->result, sptr->result);
10531056Sminshall 	}
10631056Sminshall 	forwRegister(regptr, sptr);
10731056Sminshall 	pivot = pivot->backward;
10831056Sminshall 	return(++regptr);
10931056Sminshall     }
11031056Sminshall     while (check > 0) {
11131056Sminshall 	if ((sptr->forward)->result == 0) {
11231056Sminshall 	    forwRegister(regptr, sptr);
11331056Sminshall     	    pivot = pivot->forward;
11431056Sminshall 	    return(++regptr);
11531056Sminshall 	}
11631056Sminshall 	sptr = sptr->forward;
11731056Sminshall 	check = strcmp(regptr->result, sptr->result);
11831056Sminshall     }
11931056Sminshall     backRegister(regptr, sptr);
12031056Sminshall     pivot = pivot->forward;
12131056Sminshall     return(++regptr);
12231056Sminshall }
12331056Sminshall 
12431056Sminshall static char *
12531056Sminshall addString(strcount, character)
12631056Sminshall int strcount;
12731056Sminshall char character;
12831056Sminshall {
12931056Sminshall     static char *string = array;
13031056Sminshall     int i;
13131056Sminshall 
13231056Sminshall     if (rptr->match_start == 0) {
13331056Sminshall 	rptr->match_start = string;
13431056Sminshall 	for (i=0; i < strcount; i++) {
13531056Sminshall 	    *string++ = *((rptr-1)->match_start+i);
13631056Sminshall 	}
13731056Sminshall     }
13831056Sminshall     *string++ = character;
13931056Sminshall     return(string);
14031056Sminshall }
14131056Sminshall 
14231056Sminshall static char savename[20] = " ";  /* for deciding if name is new */
14331056Sminshall 
14431056Sminshall static void
14531056Sminshall printString(string, begin, tc_name)
14631056Sminshall register char *string;
14731056Sminshall char *begin, *tc_name;
14831056Sminshall {
14931056Sminshall     register char *st1, *st2;
15031056Sminshall     register int pchar;
15131056Sminshall     static char suffix = 'A';
15231056Sminshall     int new = strcmp(savename, tc_name);
15331056Sminshall     char delim = new ? ';' : '|';
15431100Sminshall     char *uncontrol();
15531056Sminshall 
15631056Sminshall     st1 = begin;
15731056Sminshall 
15831056Sminshall     numbchars += 5 + (new ? strlen(tc_name) : -1);
15931056Sminshall     if (toshell && numbchars > 1011) {
16031056Sminshall         new = 1;
16131056Sminshall 	delim = ';';
16231056Sminshall         numbchars = 5 + strlen(tc_name);
16331056Sminshall         printf(";\nsetenv MAP3270%c ", suffix++);
16431056Sminshall     }
16531056Sminshall     if (strcmp(" ", savename)) {
16631056Sminshall 	if (toshell) {
16731056Sminshall 	   printf("%c%c", '\\', delim);
16831056Sminshall 	}
16931056Sminshall 	else {
17031056Sminshall 	   printf("%c", delim);
17131056Sminshall 	}
17231056Sminshall     }
17331056Sminshall     else {
17431056Sminshall 	numbchars -= 2;
17531056Sminshall     }
17631056Sminshall     if (toshell && new) {
17731056Sminshall         printf("%s=%c'", tc_name,'\\');
17831056Sminshall     }
17931056Sminshall     else if (new) {
18031056Sminshall         printf("%s='", tc_name);
18131056Sminshall     }
18231056Sminshall     else if (toshell) {
18331056Sminshall 	printf("%c'", '\\');
18431056Sminshall     }
18531056Sminshall     else {
18631056Sminshall 	printf("'");
18731056Sminshall     }
18831056Sminshall     (void) strcpy(savename, tc_name);
18931056Sminshall     while (st1 != string) {
19031056Sminshall 	if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */
19131056Sminshall 	   numbchars = 0;
19231056Sminshall            printf(";\nsetenv MAP3270%c ", suffix++);
19331056Sminshall 	}
19431056Sminshall 	pchar = 0xff&(*st1++);
19531056Sminshall 	switch (pchar) {
19631056Sminshall 	case '"':
19731056Sminshall 	case '!':
19831056Sminshall 	case '$':
19931056Sminshall 	case '(':
20031056Sminshall 	case ')':
20131056Sminshall 	case ' ':
20231056Sminshall 	case ';':
20331056Sminshall 	case '&':
20431056Sminshall 	case '|':
20531056Sminshall 	case '>':
20631056Sminshall 	case '<':
20731056Sminshall 	case '`':
20831056Sminshall 	case '#':
20931056Sminshall 	    numbchars += 2;
21031056Sminshall 	    if (toshell) {
21131056Sminshall 	       printf("%c%c", '\\', pchar);
21231056Sminshall 	    }
21331056Sminshall 	    else {
21431056Sminshall 	       printf("%c", pchar);
21531056Sminshall 	    }
21631056Sminshall 	    break;
21731056Sminshall 	case '\\':
21831056Sminshall 	case '\'':
21931056Sminshall 	    numbchars += 4;
22031056Sminshall 	    if (toshell) {
22131056Sminshall 	       printf("%c%c%c%c", '\\', '\\', '\\', pchar);
22231056Sminshall 	    }
22331056Sminshall 	    else {
22431056Sminshall 	       printf("%c%c", '\\', pchar);
22531056Sminshall 	    }
22631056Sminshall 	    break;
22731056Sminshall 	case '^':
22831056Sminshall 	    numbchars += 3;
22931056Sminshall 	    if (toshell) {
23031056Sminshall 	       printf("%c%c%c", '\\', '\\', pchar);
23131056Sminshall 	    }
23231056Sminshall 	    else {
23331056Sminshall 	       printf("%c%c", '\\', pchar);
23431056Sminshall 	    }
23531056Sminshall 	    break;
23631056Sminshall 	default:
23731100Sminshall 	    st2 = uncontrol(pchar);
23831056Sminshall 	    while ((pchar = *st2++) != 0) {
23931056Sminshall 		switch (pchar) {
24031056Sminshall 		case '"':
24131056Sminshall 		case '!':
24231056Sminshall 		case '$':
24331056Sminshall 		case '(':
24431056Sminshall 		case ')':
24531056Sminshall 		case ' ':
24631056Sminshall 		case ';':
24731056Sminshall 		case '&':
24831056Sminshall 		case '|':
24931056Sminshall 		case '>':
25031056Sminshall 		case '<':
25131056Sminshall 		case '`':
25231056Sminshall 		case '#':
25331056Sminshall 		case '\\':
25431056Sminshall 		case '\'':
25531056Sminshall 		   if (toshell) {
25631056Sminshall 	    	      numbchars += 2;
25731056Sminshall 	    	      printf("%c%c", '\\', pchar);
25831056Sminshall 		   }
25931056Sminshall 		   else {
26031056Sminshall 		      printf("%c", pchar);
26131056Sminshall 		   }
26231056Sminshall 		   break;
26331056Sminshall 		default:
26431056Sminshall 		   numbchars++;
26531056Sminshall 	    	   printf("%c", pchar);
26631056Sminshall 		   break;
26731056Sminshall 		}
26831056Sminshall 	    }
26931056Sminshall 	    break;
27031056Sminshall 	}
27131056Sminshall     }
27231056Sminshall     numbchars += 2;
27331056Sminshall     if (toshell) {
27431056Sminshall        printf("%c'", '\\');
27531056Sminshall     }
27631056Sminshall     else {
27731056Sminshall        printf("'");
27831056Sminshall     }
27931056Sminshall }
28031056Sminshall 
28131056Sminshall static void
28231056Sminshall recurse(strcount, head)
28331056Sminshall state *head;
28431056Sminshall int strcount;
28531056Sminshall {
28631056Sminshall 		/*	if there is a left,
28731056Sminshall 		 *	    recurse on left,
28831056Sminshall 		 *	if there is no down,
28931056Sminshall 		 *	    print the string to here
29031056Sminshall 		 *	else,
29131056Sminshall 		 *	     add the current match to the string,
29231056Sminshall 		 *	     recurse.
29331056Sminshall 		 *	exit.
29431056Sminshall 		 */
29531056Sminshall 
29631056Sminshall     if (head->next) {
29731056Sminshall 	recurse(strcount, head->next);
29831056Sminshall     }
29931056Sminshall     if (head->result != TC_GOTO) {
30031056Sminshall 	rptr->match_end = addString(strcount, head->match);
30131056Sminshall 	rptr->result = TC_Ascii[head->result - TC_LOWEST].tc_name;
30231056Sminshall 	rptr = doRegister(rptr);
30331056Sminshall     } else {
30431056Sminshall 	(void) addString(strcount, head->match);
30531056Sminshall 	recurse(strcount+1, head->address);
30631056Sminshall 	strcount--;
30731056Sminshall     }
30831056Sminshall     return;
30931056Sminshall }
31031056Sminshall 
31131056Sminshall 
31231056Sminshall main(argc, argv)
31331056Sminshall int argc;
31431056Sminshall char *argv[];
31531056Sminshall {
31631056Sminshall     state *head;
31731056Sminshall     char *keybdPointer = (char *) 0;
31831056Sminshall     char *commandName = argv[0];
31931056Sminshall     extern char *getenv();
32031056Sminshall     int picky = 0;
32131056Sminshall 
32231056Sminshall     while ((argc > 1) && (argv[1][0] == '-')) {
32331056Sminshall 	if (!strcmp(argv[1], "-picky")) {
32431056Sminshall 	    picky++;
32531056Sminshall 	} else if (!strcmp(argv[1], "-shell")) {
32631056Sminshall 	    toshell++;
32731056Sminshall 	} else {
32831056Sminshall 	    fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
32931056Sminshall 		commandName);
33031056Sminshall 	    exit(1);
33131056Sminshall 	    /*NOTREACHED*/
33231056Sminshall 	}
33331056Sminshall 	argv++;
33431056Sminshall 	argc--;
33531056Sminshall     }
33631056Sminshall     if (argc == 2) {
33731056Sminshall         keybdPointer = argv[1];
33831056Sminshall     } else if (argc > 2) {
33931056Sminshall 	fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
34031056Sminshall 		commandName);
34131056Sminshall 	exit(1);
34231056Sminshall 	/*NOTREACHED*/
34331056Sminshall     }
34431056Sminshall     head = InitControl(keybdPointer, picky);
34531056Sminshall     if (!head) {
34631056Sminshall 	return(1);
34731056Sminshall     }
34831056Sminshall     if (keybdPointer == 0) {
34931056Sminshall         keybdPointer = getenv("KEYBD");
35031056Sminshall     }
35131056Sminshall     if (keybdPointer == 0) {
35231056Sminshall 	keybdPointer = getenv("TERM");
35331056Sminshall     }
35431056Sminshall     if (keybdPointer == 0) {
35531056Sminshall 	keybdPointer = "3a";	/* use 3a as the terminal */
35631056Sminshall     }
35731056Sminshall     if (toshell) {
35831056Sminshall        printf("set noglob;\nsetenv MAP3270 ");
35931056Sminshall     }
36031056Sminshall     printf("%s{", keybdPointer);
36131056Sminshall     numbchars = 2 + strlen(keybdPointer);
36231056Sminshall     /* now, run through the table registering entries */
36331056Sminshall     rptr = regstates + 2;
36431056Sminshall     recurse(0, head);
36531056Sminshall     /* now print them out */
36631056Sminshall     for (rptr = regstates[0].forward; rptr->result != 0;
36731056Sminshall 	 rptr = rptr->forward) {
36831056Sminshall 	printString(rptr->match_end, rptr->match_start, rptr->result);
36931056Sminshall     }
37031056Sminshall     if (toshell) {
37131056Sminshall        printf("%c;};\nunset noglob;\n", '\\');
37231056Sminshall     }
37331056Sminshall     else {
37431056Sminshall       printf(";}\n");
37531056Sminshall     }
37631056Sminshall     return(0);
37731056Sminshall }
378