xref: /csrg-svn/usr.bin/tn3270/ascii/mset.c (revision 34891)
131056Sminshall /*
233817Sbostic  * Copyright (c) 1988 Regents of the University of California.
333817Sbostic  * All rights reserved.
431056Sminshall  *
533817Sbostic  * Redistribution and use in source and binary forms are permitted
6*34891Sbostic  * provided that the above copyright notice and this paragraph are
7*34891Sbostic  * duplicated in all such forms and that any documentation,
8*34891Sbostic  * advertising materials, and other materials related to such
9*34891Sbostic  * distribution and use acknowledge that the software was developed
10*34891Sbostic  * by the University of California, Berkeley.  The name of the
11*34891Sbostic  * University may not be used to endorse or promote products derived
12*34891Sbostic  * from this software without specific prior written permission.
13*34891Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34891Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34891Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1631056Sminshall  */
1731056Sminshall 
1833817Sbostic #ifndef lint
1933817Sbostic char copyright[] =
2033817Sbostic "@(#) Copyright (c) 1988 Regents of the University of California.\n\
2133817Sbostic  All rights reserved.\n";
2233817Sbostic #endif /* not lint */
2331056Sminshall 
2433817Sbostic #ifndef lint
25*34891Sbostic static char sccsid[] = "@(#)mset.c	3.3 (Berkeley) 06/29/88";
2633817Sbostic #endif /* not lint */
2733817Sbostic 
2831056Sminshall /*
2931056Sminshall  * this program outputs the user's 3270 mapping table in a form suitable
3031056Sminshall  *	for inclusion in the environment.  Typically, this might be used
3131056Sminshall  *	by:
3231056Sminshall  *		setenv MAP3270 "`mset`"
3331056Sminshall  */
3431056Sminshall 
3531100Sminshall #include <stdio.h>
3631100Sminshall #if	defined(unix)
3731056Sminshall #include <strings.h>
3831100Sminshall #else	/* defined(unix) */
3931100Sminshall #include <string.h>
4031100Sminshall #endif	/* defined(unix) */
4131245Sminshall #include "../ctlr/function.h"
4231245Sminshall 
4331176Sminshall #include "state.h"
4431870Sminshall #include "../api/astosc.h"
4531056Sminshall 
4631176Sminshall #include "../general/globals.h"
4731176Sminshall #include "map3270.ext"
4831056Sminshall 
4931056Sminshall struct regstate {
5031056Sminshall 	char *result;
5131056Sminshall 	char *match_start;
5231056Sminshall 	char *match_end;		/* start of NEXT state's match string */
5331056Sminshall 	struct regstate *forward;
5431056Sminshall 	struct regstate *backward;
5531056Sminshall };
5631056Sminshall 
5731056Sminshall static struct regstate regstates[500], *rptr= 0;	/* for sorting states */
5831056Sminshall static char array[5000];		/* lot's of room */
5931056Sminshall static int toshell = 0;			/* export to shell */
6031056Sminshall static int numbchars = 0;		/* number of chars in envir. var */
6131056Sminshall 
6231445Sminshall static int
6331445Sminshall MyStrcmp(str1, str2)
6431445Sminshall char *str1, *str2;
6531445Sminshall {
6631445Sminshall 	if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0
6731445Sminshall 	    && strlen(str1) != strlen(str2)) {
6831445Sminshall 	   return(strlen(str1) - strlen(str2));
6931445Sminshall 	}
7031445Sminshall 	return(strcmp(str1, str2));
7131445Sminshall }
7231445Sminshall 
7331056Sminshall static void
7431056Sminshall forwRegister(regptr, sptr)
7531056Sminshall struct regstate *regptr, *sptr;
7631056Sminshall {
7731056Sminshall 
7831056Sminshall     regptr->forward = sptr->forward;
7931056Sminshall     regptr->backward = sptr;
8031056Sminshall     (sptr->forward)->backward = regptr;
8131056Sminshall     sptr->forward = regptr;
8231056Sminshall }
8331056Sminshall 
8431056Sminshall static void
8531056Sminshall backRegister(regptr, sptr)
8631056Sminshall struct regstate *regptr, *sptr;
8731056Sminshall {
8831056Sminshall 
8931056Sminshall     regptr->forward = sptr;
9031056Sminshall     regptr->backward = sptr->backward;
9131056Sminshall     (sptr->backward)->forward = regptr;
9231056Sminshall     sptr->backward = regptr;
9331056Sminshall }
9431056Sminshall 
9531056Sminshall static struct regstate *
9631056Sminshall doRegister(regptr)
9731056Sminshall register struct regstate *regptr;
9831056Sminshall {
9931056Sminshall     static struct regstate *pivot = regstates;
10031056Sminshall     register struct regstate *sptr = pivot;
10131056Sminshall     int check;
10231056Sminshall 
10331056Sminshall     if (pivot == regstates) {		/* first time called */
10431056Sminshall 	pivot->forward = regptr;
10531056Sminshall 	regptr->backward = pivot++;
10631056Sminshall 	pivot->backward = regptr;
10731056Sminshall 	regptr->forward = pivot++;
10831056Sminshall 	return(++regptr);
10931056Sminshall     }
11031445Sminshall     if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) {
11131056Sminshall 	while (check < 0) {
11231056Sminshall 	    if (sptr->backward == regstates) {
11331056Sminshall 		backRegister(regptr, sptr);
11431056Sminshall 		pivot = pivot->backward;
11531056Sminshall 		return(++regptr);
11631056Sminshall 	     }
11731056Sminshall 	     sptr = sptr->backward;
11831445Sminshall 	     check = MyStrcmp(regptr->result, sptr->result);
11931056Sminshall 	}
12031056Sminshall 	forwRegister(regptr, sptr);
12131056Sminshall 	pivot = pivot->backward;
12231056Sminshall 	return(++regptr);
12331056Sminshall     }
12431056Sminshall     while (check > 0) {
12531056Sminshall 	if ((sptr->forward)->result == 0) {
12631056Sminshall 	    forwRegister(regptr, sptr);
12731056Sminshall     	    pivot = pivot->forward;
12831056Sminshall 	    return(++regptr);
12931056Sminshall 	}
13031056Sminshall 	sptr = sptr->forward;
13131445Sminshall 	check = MyStrcmp(regptr->result, sptr->result);
13231056Sminshall     }
13331056Sminshall     backRegister(regptr, sptr);
13431445Sminshall     if (pivot->forward->result) {
13531445Sminshall 	pivot = pivot->forward;
13631445Sminshall     }
13731056Sminshall     return(++regptr);
13831056Sminshall }
13931056Sminshall 
14031056Sminshall static char *
14131056Sminshall addString(strcount, character)
14231056Sminshall int strcount;
14331056Sminshall char character;
14431056Sminshall {
14531056Sminshall     static char *string = array;
14631056Sminshall     int i;
14731056Sminshall 
14831056Sminshall     if (rptr->match_start == 0) {
14931056Sminshall 	rptr->match_start = string;
15031056Sminshall 	for (i=0; i < strcount; i++) {
15131056Sminshall 	    *string++ = *((rptr-1)->match_start+i);
15231056Sminshall 	}
15331056Sminshall     }
15431056Sminshall     *string++ = character;
15531056Sminshall     return(string);
15631056Sminshall }
15731056Sminshall 
15831056Sminshall static char savename[20] = " ";  /* for deciding if name is new */
15931056Sminshall 
16031056Sminshall static void
16131056Sminshall printString(string, begin, tc_name)
16231056Sminshall register char *string;
16331056Sminshall char *begin, *tc_name;
16431056Sminshall {
16531056Sminshall     register char *st1, *st2;
16631056Sminshall     register int pchar;
16731056Sminshall     static char suffix = 'A';
16831056Sminshall     int new = strcmp(savename, tc_name);
16931056Sminshall     char delim = new ? ';' : '|';
17031100Sminshall     char *uncontrol();
17131056Sminshall 
17231056Sminshall     st1 = begin;
17331056Sminshall 
17431056Sminshall     numbchars += 5 + (new ? strlen(tc_name) : -1);
17531056Sminshall     if (toshell && numbchars > 1011) {
17631056Sminshall         new = 1;
17731056Sminshall 	delim = ';';
17831056Sminshall         numbchars = 5 + strlen(tc_name);
17931056Sminshall         printf(";\nsetenv MAP3270%c ", suffix++);
18031056Sminshall     }
18131056Sminshall     if (strcmp(" ", savename)) {
18231056Sminshall 	if (toshell) {
18331056Sminshall 	   printf("%c%c", '\\', delim);
18431056Sminshall 	}
18531056Sminshall 	else {
18631056Sminshall 	   printf("%c", delim);
18731056Sminshall 	}
18831056Sminshall     }
18931056Sminshall     else {
19031056Sminshall 	numbchars -= 2;
19131056Sminshall     }
19231056Sminshall     if (toshell && new) {
19331056Sminshall         printf("%s=%c'", tc_name,'\\');
19431056Sminshall     }
19531056Sminshall     else if (new) {
19631056Sminshall         printf("%s='", tc_name);
19731056Sminshall     }
19831056Sminshall     else if (toshell) {
19931056Sminshall 	printf("%c'", '\\');
20031056Sminshall     }
20131056Sminshall     else {
20231056Sminshall 	printf("'");
20331056Sminshall     }
20431056Sminshall     (void) strcpy(savename, tc_name);
20531056Sminshall     while (st1 != string) {
20631056Sminshall 	if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */
20731056Sminshall 	   numbchars = 0;
20831056Sminshall            printf(";\nsetenv MAP3270%c ", suffix++);
20931056Sminshall 	}
21031056Sminshall 	pchar = 0xff&(*st1++);
21131056Sminshall 	switch (pchar) {
21231056Sminshall 	case '"':
21331056Sminshall 	case '!':
21431056Sminshall 	case '$':
21531056Sminshall 	case '(':
21631056Sminshall 	case ')':
21731056Sminshall 	case ' ':
21831056Sminshall 	case ';':
21931056Sminshall 	case '&':
22031056Sminshall 	case '|':
22131056Sminshall 	case '>':
22231056Sminshall 	case '<':
22331056Sminshall 	case '`':
22431056Sminshall 	case '#':
22531056Sminshall 	    numbchars += 2;
22631056Sminshall 	    if (toshell) {
22731056Sminshall 	       printf("%c%c", '\\', pchar);
22831056Sminshall 	    }
22931056Sminshall 	    else {
23031056Sminshall 	       printf("%c", pchar);
23131056Sminshall 	    }
23231056Sminshall 	    break;
23331056Sminshall 	case '\\':
23431056Sminshall 	case '\'':
23531056Sminshall 	    numbchars += 4;
23631056Sminshall 	    if (toshell) {
23731056Sminshall 	       printf("%c%c%c%c", '\\', '\\', '\\', pchar);
23831056Sminshall 	    }
23931056Sminshall 	    else {
24031056Sminshall 	       printf("%c%c", '\\', pchar);
24131056Sminshall 	    }
24231056Sminshall 	    break;
24331056Sminshall 	case '^':
24431056Sminshall 	    numbchars += 3;
24531056Sminshall 	    if (toshell) {
24631056Sminshall 	       printf("%c%c%c", '\\', '\\', pchar);
24731056Sminshall 	    }
24831056Sminshall 	    else {
24931056Sminshall 	       printf("%c%c", '\\', pchar);
25031056Sminshall 	    }
25131056Sminshall 	    break;
25231056Sminshall 	default:
25331100Sminshall 	    st2 = uncontrol(pchar);
25431056Sminshall 	    while ((pchar = *st2++) != 0) {
25531056Sminshall 		switch (pchar) {
25631056Sminshall 		case '"':
25731056Sminshall 		case '!':
25831056Sminshall 		case '$':
25931056Sminshall 		case '(':
26031056Sminshall 		case ')':
26131056Sminshall 		case ' ':
26231056Sminshall 		case ';':
26331056Sminshall 		case '&':
26431056Sminshall 		case '|':
26531056Sminshall 		case '>':
26631056Sminshall 		case '<':
26731056Sminshall 		case '`':
26831056Sminshall 		case '#':
26931056Sminshall 		case '\\':
27031056Sminshall 		case '\'':
27131056Sminshall 		   if (toshell) {
27231056Sminshall 	    	      numbchars += 2;
27331056Sminshall 	    	      printf("%c%c", '\\', pchar);
27431056Sminshall 		   }
27531056Sminshall 		   else {
27631056Sminshall 		      printf("%c", pchar);
27731056Sminshall 		   }
27831056Sminshall 		   break;
27931056Sminshall 		default:
28031056Sminshall 		   numbchars++;
28131056Sminshall 	    	   printf("%c", pchar);
28231056Sminshall 		   break;
28331056Sminshall 		}
28431056Sminshall 	    }
28531056Sminshall 	    break;
28631056Sminshall 	}
28731056Sminshall     }
28831056Sminshall     numbchars += 2;
28931056Sminshall     if (toshell) {
29031056Sminshall        printf("%c'", '\\');
29131056Sminshall     }
29231056Sminshall     else {
29331056Sminshall        printf("'");
29431056Sminshall     }
29531056Sminshall }
29631056Sminshall 
29731056Sminshall static void
29831056Sminshall recurse(strcount, head)
29931056Sminshall state *head;
30031056Sminshall int strcount;
30131056Sminshall {
30231056Sminshall 		/*	if there is a left,
30331056Sminshall 		 *	    recurse on left,
30431056Sminshall 		 *	if there is no down,
30531056Sminshall 		 *	    print the string to here
30631056Sminshall 		 *	else,
30731056Sminshall 		 *	     add the current match to the string,
30831056Sminshall 		 *	     recurse.
30931056Sminshall 		 *	exit.
31031056Sminshall 		 */
31131056Sminshall 
31231056Sminshall     if (head->next) {
31331056Sminshall 	recurse(strcount, head->next);
31431056Sminshall     }
31531245Sminshall     if (head->result != STATE_GOTO) {
31631056Sminshall 	rptr->match_end = addString(strcount, head->match);
31731245Sminshall 	rptr->result = astosc[head->result].name;
31831056Sminshall 	rptr = doRegister(rptr);
31931056Sminshall     } else {
32031056Sminshall 	(void) addString(strcount, head->match);
32131056Sminshall 	recurse(strcount+1, head->address);
32231056Sminshall 	strcount--;
32331056Sminshall     }
32431056Sminshall     return;
32531056Sminshall }
32631056Sminshall 
32731056Sminshall 
32831056Sminshall main(argc, argv)
32931056Sminshall int argc;
33031056Sminshall char *argv[];
33131056Sminshall {
33231056Sminshall     state *head;
33331056Sminshall     char *keybdPointer = (char *) 0;
33431056Sminshall     char *commandName = argv[0];
33531056Sminshall     extern char *getenv();
33631056Sminshall     int picky = 0;
33731056Sminshall 
33831056Sminshall     while ((argc > 1) && (argv[1][0] == '-')) {
33931056Sminshall 	if (!strcmp(argv[1], "-picky")) {
34031056Sminshall 	    picky++;
34131056Sminshall 	} else if (!strcmp(argv[1], "-shell")) {
34231056Sminshall 	    toshell++;
34331056Sminshall 	} else {
34431056Sminshall 	    fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
34531056Sminshall 		commandName);
34631056Sminshall 	    exit(1);
34731056Sminshall 	    /*NOTREACHED*/
34831056Sminshall 	}
34931056Sminshall 	argv++;
35031056Sminshall 	argc--;
35131056Sminshall     }
35231056Sminshall     if (argc == 2) {
35331056Sminshall         keybdPointer = argv[1];
35431056Sminshall     } else if (argc > 2) {
35531056Sminshall 	fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
35631056Sminshall 		commandName);
35731056Sminshall 	exit(1);
35831056Sminshall 	/*NOTREACHED*/
35931056Sminshall     }
36031245Sminshall     head = InitControl(keybdPointer, picky, ascii_to_index);
36131056Sminshall     if (!head) {
36231056Sminshall 	return(1);
36331056Sminshall     }
36431056Sminshall     if (keybdPointer == 0) {
36531056Sminshall         keybdPointer = getenv("KEYBD");
36631056Sminshall     }
36731056Sminshall     if (keybdPointer == 0) {
36831056Sminshall 	keybdPointer = getenv("TERM");
36931056Sminshall     }
37031056Sminshall     if (keybdPointer == 0) {
37131056Sminshall 	keybdPointer = "3a";	/* use 3a as the terminal */
37231056Sminshall     }
37331056Sminshall     if (toshell) {
37431056Sminshall        printf("set noglob;\nsetenv MAP3270 ");
37531056Sminshall     }
37631056Sminshall     printf("%s{", keybdPointer);
37731056Sminshall     numbchars = 2 + strlen(keybdPointer);
37831056Sminshall     /* now, run through the table registering entries */
37931056Sminshall     rptr = regstates + 2;
38031056Sminshall     recurse(0, head);
38131056Sminshall     /* now print them out */
38231056Sminshall     for (rptr = regstates[0].forward; rptr->result != 0;
38331056Sminshall 	 rptr = rptr->forward) {
38431056Sminshall 	printString(rptr->match_end, rptr->match_start, rptr->result);
38531056Sminshall     }
38631056Sminshall     if (toshell) {
38731056Sminshall        printf("%c;};\nunset noglob;\n", '\\');
38831056Sminshall     }
38931056Sminshall     else {
39031056Sminshall       printf(";}\n");
39131056Sminshall     }
39231056Sminshall     return(0);
39331056Sminshall }
394