131056Sminshall /* 2*33817Sbostic * Copyright (c) 1988 Regents of the University of California. 3*33817Sbostic * All rights reserved. 431056Sminshall * 5*33817Sbostic * Redistribution and use in source and binary forms are permitted 6*33817Sbostic * provided that this notice is preserved and that due credit is given 7*33817Sbostic * to the University of California at Berkeley. The name of the University 8*33817Sbostic * may not be used to endorse or promote products derived from this 9*33817Sbostic * software without specific prior written permission. This software 10*33817Sbostic * is provided ``as is'' without express or implied warranty. 1131056Sminshall */ 1231056Sminshall 13*33817Sbostic #ifndef lint 14*33817Sbostic char copyright[] = 15*33817Sbostic "@(#) Copyright (c) 1988 Regents of the University of California.\n\ 16*33817Sbostic All rights reserved.\n"; 17*33817Sbostic #endif /* not lint */ 1831056Sminshall 19*33817Sbostic #ifndef lint 20*33817Sbostic static char sccsid[] = "@(#)mset.c 3.2 (Berkeley) 03/28/88"; 21*33817Sbostic #endif /* not lint */ 22*33817Sbostic 2331056Sminshall /* 2431056Sminshall * this program outputs the user's 3270 mapping table in a form suitable 2531056Sminshall * for inclusion in the environment. Typically, this might be used 2631056Sminshall * by: 2731056Sminshall * setenv MAP3270 "`mset`" 2831056Sminshall */ 2931056Sminshall 3031100Sminshall #include <stdio.h> 3131100Sminshall #if defined(unix) 3231056Sminshall #include <strings.h> 3331100Sminshall #else /* defined(unix) */ 3431100Sminshall #include <string.h> 3531100Sminshall #endif /* defined(unix) */ 3631245Sminshall #include "../ctlr/function.h" 3731245Sminshall 3831176Sminshall #include "state.h" 3931870Sminshall #include "../api/astosc.h" 4031056Sminshall 4131176Sminshall #include "../general/globals.h" 4231176Sminshall #include "map3270.ext" 4331056Sminshall 4431056Sminshall struct regstate { 4531056Sminshall char *result; 4631056Sminshall char *match_start; 4731056Sminshall char *match_end; /* start of NEXT state's match string */ 4831056Sminshall struct regstate *forward; 4931056Sminshall struct regstate *backward; 5031056Sminshall }; 5131056Sminshall 5231056Sminshall static struct regstate regstates[500], *rptr= 0; /* for sorting states */ 5331056Sminshall static char array[5000]; /* lot's of room */ 5431056Sminshall static int toshell = 0; /* export to shell */ 5531056Sminshall static int numbchars = 0; /* number of chars in envir. var */ 5631056Sminshall 5731445Sminshall static int 5831445Sminshall MyStrcmp(str1, str2) 5931445Sminshall char *str1, *str2; 6031445Sminshall { 6131445Sminshall if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0 6231445Sminshall && strlen(str1) != strlen(str2)) { 6331445Sminshall return(strlen(str1) - strlen(str2)); 6431445Sminshall } 6531445Sminshall return(strcmp(str1, str2)); 6631445Sminshall } 6731445Sminshall 6831056Sminshall static void 6931056Sminshall forwRegister(regptr, sptr) 7031056Sminshall struct regstate *regptr, *sptr; 7131056Sminshall { 7231056Sminshall 7331056Sminshall regptr->forward = sptr->forward; 7431056Sminshall regptr->backward = sptr; 7531056Sminshall (sptr->forward)->backward = regptr; 7631056Sminshall sptr->forward = regptr; 7731056Sminshall } 7831056Sminshall 7931056Sminshall static void 8031056Sminshall backRegister(regptr, sptr) 8131056Sminshall struct regstate *regptr, *sptr; 8231056Sminshall { 8331056Sminshall 8431056Sminshall regptr->forward = sptr; 8531056Sminshall regptr->backward = sptr->backward; 8631056Sminshall (sptr->backward)->forward = regptr; 8731056Sminshall sptr->backward = regptr; 8831056Sminshall } 8931056Sminshall 9031056Sminshall static struct regstate * 9131056Sminshall doRegister(regptr) 9231056Sminshall register struct regstate *regptr; 9331056Sminshall { 9431056Sminshall static struct regstate *pivot = regstates; 9531056Sminshall register struct regstate *sptr = pivot; 9631056Sminshall int check; 9731056Sminshall 9831056Sminshall if (pivot == regstates) { /* first time called */ 9931056Sminshall pivot->forward = regptr; 10031056Sminshall regptr->backward = pivot++; 10131056Sminshall pivot->backward = regptr; 10231056Sminshall regptr->forward = pivot++; 10331056Sminshall return(++regptr); 10431056Sminshall } 10531445Sminshall if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) { 10631056Sminshall while (check < 0) { 10731056Sminshall if (sptr->backward == regstates) { 10831056Sminshall backRegister(regptr, sptr); 10931056Sminshall pivot = pivot->backward; 11031056Sminshall return(++regptr); 11131056Sminshall } 11231056Sminshall sptr = sptr->backward; 11331445Sminshall check = MyStrcmp(regptr->result, sptr->result); 11431056Sminshall } 11531056Sminshall forwRegister(regptr, sptr); 11631056Sminshall pivot = pivot->backward; 11731056Sminshall return(++regptr); 11831056Sminshall } 11931056Sminshall while (check > 0) { 12031056Sminshall if ((sptr->forward)->result == 0) { 12131056Sminshall forwRegister(regptr, sptr); 12231056Sminshall pivot = pivot->forward; 12331056Sminshall return(++regptr); 12431056Sminshall } 12531056Sminshall sptr = sptr->forward; 12631445Sminshall check = MyStrcmp(regptr->result, sptr->result); 12731056Sminshall } 12831056Sminshall backRegister(regptr, sptr); 12931445Sminshall if (pivot->forward->result) { 13031445Sminshall pivot = pivot->forward; 13131445Sminshall } 13231056Sminshall return(++regptr); 13331056Sminshall } 13431056Sminshall 13531056Sminshall static char * 13631056Sminshall addString(strcount, character) 13731056Sminshall int strcount; 13831056Sminshall char character; 13931056Sminshall { 14031056Sminshall static char *string = array; 14131056Sminshall int i; 14231056Sminshall 14331056Sminshall if (rptr->match_start == 0) { 14431056Sminshall rptr->match_start = string; 14531056Sminshall for (i=0; i < strcount; i++) { 14631056Sminshall *string++ = *((rptr-1)->match_start+i); 14731056Sminshall } 14831056Sminshall } 14931056Sminshall *string++ = character; 15031056Sminshall return(string); 15131056Sminshall } 15231056Sminshall 15331056Sminshall static char savename[20] = " "; /* for deciding if name is new */ 15431056Sminshall 15531056Sminshall static void 15631056Sminshall printString(string, begin, tc_name) 15731056Sminshall register char *string; 15831056Sminshall char *begin, *tc_name; 15931056Sminshall { 16031056Sminshall register char *st1, *st2; 16131056Sminshall register int pchar; 16231056Sminshall static char suffix = 'A'; 16331056Sminshall int new = strcmp(savename, tc_name); 16431056Sminshall char delim = new ? ';' : '|'; 16531100Sminshall char *uncontrol(); 16631056Sminshall 16731056Sminshall st1 = begin; 16831056Sminshall 16931056Sminshall numbchars += 5 + (new ? strlen(tc_name) : -1); 17031056Sminshall if (toshell && numbchars > 1011) { 17131056Sminshall new = 1; 17231056Sminshall delim = ';'; 17331056Sminshall numbchars = 5 + strlen(tc_name); 17431056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 17531056Sminshall } 17631056Sminshall if (strcmp(" ", savename)) { 17731056Sminshall if (toshell) { 17831056Sminshall printf("%c%c", '\\', delim); 17931056Sminshall } 18031056Sminshall else { 18131056Sminshall printf("%c", delim); 18231056Sminshall } 18331056Sminshall } 18431056Sminshall else { 18531056Sminshall numbchars -= 2; 18631056Sminshall } 18731056Sminshall if (toshell && new) { 18831056Sminshall printf("%s=%c'", tc_name,'\\'); 18931056Sminshall } 19031056Sminshall else if (new) { 19131056Sminshall printf("%s='", tc_name); 19231056Sminshall } 19331056Sminshall else if (toshell) { 19431056Sminshall printf("%c'", '\\'); 19531056Sminshall } 19631056Sminshall else { 19731056Sminshall printf("'"); 19831056Sminshall } 19931056Sminshall (void) strcpy(savename, tc_name); 20031056Sminshall while (st1 != string) { 20131056Sminshall if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */ 20231056Sminshall numbchars = 0; 20331056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 20431056Sminshall } 20531056Sminshall pchar = 0xff&(*st1++); 20631056Sminshall switch (pchar) { 20731056Sminshall case '"': 20831056Sminshall case '!': 20931056Sminshall case '$': 21031056Sminshall case '(': 21131056Sminshall case ')': 21231056Sminshall case ' ': 21331056Sminshall case ';': 21431056Sminshall case '&': 21531056Sminshall case '|': 21631056Sminshall case '>': 21731056Sminshall case '<': 21831056Sminshall case '`': 21931056Sminshall case '#': 22031056Sminshall numbchars += 2; 22131056Sminshall if (toshell) { 22231056Sminshall printf("%c%c", '\\', pchar); 22331056Sminshall } 22431056Sminshall else { 22531056Sminshall printf("%c", pchar); 22631056Sminshall } 22731056Sminshall break; 22831056Sminshall case '\\': 22931056Sminshall case '\'': 23031056Sminshall numbchars += 4; 23131056Sminshall if (toshell) { 23231056Sminshall printf("%c%c%c%c", '\\', '\\', '\\', pchar); 23331056Sminshall } 23431056Sminshall else { 23531056Sminshall printf("%c%c", '\\', pchar); 23631056Sminshall } 23731056Sminshall break; 23831056Sminshall case '^': 23931056Sminshall numbchars += 3; 24031056Sminshall if (toshell) { 24131056Sminshall printf("%c%c%c", '\\', '\\', pchar); 24231056Sminshall } 24331056Sminshall else { 24431056Sminshall printf("%c%c", '\\', pchar); 24531056Sminshall } 24631056Sminshall break; 24731056Sminshall default: 24831100Sminshall st2 = uncontrol(pchar); 24931056Sminshall while ((pchar = *st2++) != 0) { 25031056Sminshall switch (pchar) { 25131056Sminshall case '"': 25231056Sminshall case '!': 25331056Sminshall case '$': 25431056Sminshall case '(': 25531056Sminshall case ')': 25631056Sminshall case ' ': 25731056Sminshall case ';': 25831056Sminshall case '&': 25931056Sminshall case '|': 26031056Sminshall case '>': 26131056Sminshall case '<': 26231056Sminshall case '`': 26331056Sminshall case '#': 26431056Sminshall case '\\': 26531056Sminshall case '\'': 26631056Sminshall if (toshell) { 26731056Sminshall numbchars += 2; 26831056Sminshall printf("%c%c", '\\', pchar); 26931056Sminshall } 27031056Sminshall else { 27131056Sminshall printf("%c", pchar); 27231056Sminshall } 27331056Sminshall break; 27431056Sminshall default: 27531056Sminshall numbchars++; 27631056Sminshall printf("%c", pchar); 27731056Sminshall break; 27831056Sminshall } 27931056Sminshall } 28031056Sminshall break; 28131056Sminshall } 28231056Sminshall } 28331056Sminshall numbchars += 2; 28431056Sminshall if (toshell) { 28531056Sminshall printf("%c'", '\\'); 28631056Sminshall } 28731056Sminshall else { 28831056Sminshall printf("'"); 28931056Sminshall } 29031056Sminshall } 29131056Sminshall 29231056Sminshall static void 29331056Sminshall recurse(strcount, head) 29431056Sminshall state *head; 29531056Sminshall int strcount; 29631056Sminshall { 29731056Sminshall /* if there is a left, 29831056Sminshall * recurse on left, 29931056Sminshall * if there is no down, 30031056Sminshall * print the string to here 30131056Sminshall * else, 30231056Sminshall * add the current match to the string, 30331056Sminshall * recurse. 30431056Sminshall * exit. 30531056Sminshall */ 30631056Sminshall 30731056Sminshall if (head->next) { 30831056Sminshall recurse(strcount, head->next); 30931056Sminshall } 31031245Sminshall if (head->result != STATE_GOTO) { 31131056Sminshall rptr->match_end = addString(strcount, head->match); 31231245Sminshall rptr->result = astosc[head->result].name; 31331056Sminshall rptr = doRegister(rptr); 31431056Sminshall } else { 31531056Sminshall (void) addString(strcount, head->match); 31631056Sminshall recurse(strcount+1, head->address); 31731056Sminshall strcount--; 31831056Sminshall } 31931056Sminshall return; 32031056Sminshall } 32131056Sminshall 32231056Sminshall 32331056Sminshall main(argc, argv) 32431056Sminshall int argc; 32531056Sminshall char *argv[]; 32631056Sminshall { 32731056Sminshall state *head; 32831056Sminshall char *keybdPointer = (char *) 0; 32931056Sminshall char *commandName = argv[0]; 33031056Sminshall extern char *getenv(); 33131056Sminshall int picky = 0; 33231056Sminshall 33331056Sminshall while ((argc > 1) && (argv[1][0] == '-')) { 33431056Sminshall if (!strcmp(argv[1], "-picky")) { 33531056Sminshall picky++; 33631056Sminshall } else if (!strcmp(argv[1], "-shell")) { 33731056Sminshall toshell++; 33831056Sminshall } else { 33931056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 34031056Sminshall commandName); 34131056Sminshall exit(1); 34231056Sminshall /*NOTREACHED*/ 34331056Sminshall } 34431056Sminshall argv++; 34531056Sminshall argc--; 34631056Sminshall } 34731056Sminshall if (argc == 2) { 34831056Sminshall keybdPointer = argv[1]; 34931056Sminshall } else if (argc > 2) { 35031056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 35131056Sminshall commandName); 35231056Sminshall exit(1); 35331056Sminshall /*NOTREACHED*/ 35431056Sminshall } 35531245Sminshall head = InitControl(keybdPointer, picky, ascii_to_index); 35631056Sminshall if (!head) { 35731056Sminshall return(1); 35831056Sminshall } 35931056Sminshall if (keybdPointer == 0) { 36031056Sminshall keybdPointer = getenv("KEYBD"); 36131056Sminshall } 36231056Sminshall if (keybdPointer == 0) { 36331056Sminshall keybdPointer = getenv("TERM"); 36431056Sminshall } 36531056Sminshall if (keybdPointer == 0) { 36631056Sminshall keybdPointer = "3a"; /* use 3a as the terminal */ 36731056Sminshall } 36831056Sminshall if (toshell) { 36931056Sminshall printf("set noglob;\nsetenv MAP3270 "); 37031056Sminshall } 37131056Sminshall printf("%s{", keybdPointer); 37231056Sminshall numbchars = 2 + strlen(keybdPointer); 37331056Sminshall /* now, run through the table registering entries */ 37431056Sminshall rptr = regstates + 2; 37531056Sminshall recurse(0, head); 37631056Sminshall /* now print them out */ 37731056Sminshall for (rptr = regstates[0].forward; rptr->result != 0; 37831056Sminshall rptr = rptr->forward) { 37931056Sminshall printString(rptr->match_end, rptr->match_start, rptr->result); 38031056Sminshall } 38131056Sminshall if (toshell) { 38231056Sminshall printf("%c;};\nunset noglob;\n", '\\'); 38331056Sminshall } 38431056Sminshall else { 38531056Sminshall printf(";}\n"); 38631056Sminshall } 38731056Sminshall return(0); 38831056Sminshall } 389