1*48755Sbostic /*- 2*48755Sbostic * Copyright (c) 1988 The Regents of the University of California. 333817Sbostic * All rights reserved. 431056Sminshall * 5*48755Sbostic * %sccs.include.redist.c% 631056Sminshall */ 731056Sminshall 833817Sbostic #ifndef lint 933817Sbostic char copyright[] = 10*48755Sbostic "@(#) Copyright (c) 1988 The Regents of the University of California.\n\ 1133817Sbostic All rights reserved.\n"; 1233817Sbostic #endif /* not lint */ 1331056Sminshall 1433817Sbostic #ifndef lint 15*48755Sbostic static char sccsid[] = "@(#)mset.c 4.2 (Berkeley) 04/26/91"; 1633817Sbostic #endif /* not lint */ 1733817Sbostic 1831056Sminshall /* 1931056Sminshall * this program outputs the user's 3270 mapping table in a form suitable 2031056Sminshall * for inclusion in the environment. Typically, this might be used 2131056Sminshall * by: 2231056Sminshall * setenv MAP3270 "`mset`" 2331056Sminshall */ 2431056Sminshall 2531100Sminshall #include <stdio.h> 2631100Sminshall #if defined(unix) 2731056Sminshall #include <strings.h> 2831100Sminshall #else /* defined(unix) */ 2931100Sminshall #include <string.h> 3031100Sminshall #endif /* defined(unix) */ 3131245Sminshall #include "../ctlr/function.h" 3231245Sminshall 3331176Sminshall #include "state.h" 3435419Sminshall #include "map3270.h" 3535419Sminshall 3631870Sminshall #include "../api/astosc.h" 3731056Sminshall 3831176Sminshall #include "../general/globals.h" 3931056Sminshall 4031056Sminshall struct regstate { 4131056Sminshall char *result; 4231056Sminshall char *match_start; 4331056Sminshall char *match_end; /* start of NEXT state's match string */ 4431056Sminshall struct regstate *forward; 4531056Sminshall struct regstate *backward; 4631056Sminshall }; 4731056Sminshall 4831056Sminshall static struct regstate regstates[500], *rptr= 0; /* for sorting states */ 4931056Sminshall static char array[5000]; /* lot's of room */ 5031056Sminshall static int toshell = 0; /* export to shell */ 5131056Sminshall static int numbchars = 0; /* number of chars in envir. var */ 5231056Sminshall 5331445Sminshall static int 5431445Sminshall MyStrcmp(str1, str2) 5531445Sminshall char *str1, *str2; 5631445Sminshall { 5731445Sminshall if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0 5831445Sminshall && strlen(str1) != strlen(str2)) { 5931445Sminshall return(strlen(str1) - strlen(str2)); 6031445Sminshall } 6131445Sminshall return(strcmp(str1, str2)); 6231445Sminshall } 6331445Sminshall 6431056Sminshall static void 6531056Sminshall forwRegister(regptr, sptr) 6631056Sminshall struct regstate *regptr, *sptr; 6731056Sminshall { 6831056Sminshall 6931056Sminshall regptr->forward = sptr->forward; 7031056Sminshall regptr->backward = sptr; 7131056Sminshall (sptr->forward)->backward = regptr; 7231056Sminshall sptr->forward = regptr; 7331056Sminshall } 7431056Sminshall 7531056Sminshall static void 7631056Sminshall backRegister(regptr, sptr) 7731056Sminshall struct regstate *regptr, *sptr; 7831056Sminshall { 7931056Sminshall 8031056Sminshall regptr->forward = sptr; 8131056Sminshall regptr->backward = sptr->backward; 8231056Sminshall (sptr->backward)->forward = regptr; 8331056Sminshall sptr->backward = regptr; 8431056Sminshall } 8531056Sminshall 8631056Sminshall static struct regstate * 8731056Sminshall doRegister(regptr) 8831056Sminshall register struct regstate *regptr; 8931056Sminshall { 9031056Sminshall static struct regstate *pivot = regstates; 9131056Sminshall register struct regstate *sptr = pivot; 9231056Sminshall int check; 9331056Sminshall 9431056Sminshall if (pivot == regstates) { /* first time called */ 9531056Sminshall pivot->forward = regptr; 9631056Sminshall regptr->backward = pivot++; 9731056Sminshall pivot->backward = regptr; 9831056Sminshall regptr->forward = pivot++; 9931056Sminshall return(++regptr); 10031056Sminshall } 10131445Sminshall if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) { 10231056Sminshall while (check < 0) { 10331056Sminshall if (sptr->backward == regstates) { 10431056Sminshall backRegister(regptr, sptr); 10531056Sminshall pivot = pivot->backward; 10631056Sminshall return(++regptr); 10731056Sminshall } 10831056Sminshall sptr = sptr->backward; 10931445Sminshall check = MyStrcmp(regptr->result, sptr->result); 11031056Sminshall } 11131056Sminshall forwRegister(regptr, sptr); 11231056Sminshall pivot = pivot->backward; 11331056Sminshall return(++regptr); 11431056Sminshall } 11531056Sminshall while (check > 0) { 11631056Sminshall if ((sptr->forward)->result == 0) { 11731056Sminshall forwRegister(regptr, sptr); 11831056Sminshall pivot = pivot->forward; 11931056Sminshall return(++regptr); 12031056Sminshall } 12131056Sminshall sptr = sptr->forward; 12231445Sminshall check = MyStrcmp(regptr->result, sptr->result); 12331056Sminshall } 12431056Sminshall backRegister(regptr, sptr); 12531445Sminshall if (pivot->forward->result) { 12631445Sminshall pivot = pivot->forward; 12731445Sminshall } 12831056Sminshall return(++regptr); 12931056Sminshall } 13031056Sminshall 13131056Sminshall static char * 13231056Sminshall addString(strcount, character) 13331056Sminshall int strcount; 13431056Sminshall char character; 13531056Sminshall { 13631056Sminshall static char *string = array; 13731056Sminshall int i; 13831056Sminshall 13931056Sminshall if (rptr->match_start == 0) { 14031056Sminshall rptr->match_start = string; 14131056Sminshall for (i=0; i < strcount; i++) { 14231056Sminshall *string++ = *((rptr-1)->match_start+i); 14331056Sminshall } 14431056Sminshall } 14531056Sminshall *string++ = character; 14631056Sminshall return(string); 14731056Sminshall } 14831056Sminshall 14931056Sminshall static char savename[20] = " "; /* for deciding if name is new */ 15031056Sminshall 15131056Sminshall static void 15231056Sminshall printString(string, begin, tc_name) 15331056Sminshall register char *string; 15431056Sminshall char *begin, *tc_name; 15531056Sminshall { 15631056Sminshall register char *st1, *st2; 15731056Sminshall register int pchar; 15831056Sminshall static char suffix = 'A'; 15931056Sminshall int new = strcmp(savename, tc_name); 16031056Sminshall char delim = new ? ';' : '|'; 16131100Sminshall char *uncontrol(); 16231056Sminshall 16331056Sminshall st1 = begin; 16431056Sminshall 16531056Sminshall numbchars += 5 + (new ? strlen(tc_name) : -1); 16631056Sminshall if (toshell && numbchars > 1011) { 16731056Sminshall new = 1; 16831056Sminshall delim = ';'; 16931056Sminshall numbchars = 5 + strlen(tc_name); 17031056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 17131056Sminshall } 17231056Sminshall if (strcmp(" ", savename)) { 17331056Sminshall if (toshell) { 17431056Sminshall printf("%c%c", '\\', delim); 17531056Sminshall } 17631056Sminshall else { 17731056Sminshall printf("%c", delim); 17831056Sminshall } 17931056Sminshall } 18031056Sminshall else { 18131056Sminshall numbchars -= 2; 18231056Sminshall } 18331056Sminshall if (toshell && new) { 18431056Sminshall printf("%s=%c'", tc_name,'\\'); 18531056Sminshall } 18631056Sminshall else if (new) { 18731056Sminshall printf("%s='", tc_name); 18831056Sminshall } 18931056Sminshall else if (toshell) { 19031056Sminshall printf("%c'", '\\'); 19131056Sminshall } 19231056Sminshall else { 19331056Sminshall printf("'"); 19431056Sminshall } 19531056Sminshall (void) strcpy(savename, tc_name); 19631056Sminshall while (st1 != string) { 19731056Sminshall if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */ 19831056Sminshall numbchars = 0; 19931056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 20031056Sminshall } 20131056Sminshall pchar = 0xff&(*st1++); 20231056Sminshall switch (pchar) { 20331056Sminshall case '"': 20431056Sminshall case '!': 20531056Sminshall case '$': 20631056Sminshall case '(': 20731056Sminshall case ')': 20831056Sminshall case ' ': 20931056Sminshall case ';': 21031056Sminshall case '&': 21131056Sminshall case '|': 21231056Sminshall case '>': 21331056Sminshall case '<': 21431056Sminshall case '`': 21531056Sminshall case '#': 21631056Sminshall numbchars += 2; 21731056Sminshall if (toshell) { 21831056Sminshall printf("%c%c", '\\', pchar); 21931056Sminshall } 22031056Sminshall else { 22131056Sminshall printf("%c", pchar); 22231056Sminshall } 22331056Sminshall break; 22431056Sminshall case '\\': 22531056Sminshall case '\'': 22631056Sminshall numbchars += 4; 22731056Sminshall if (toshell) { 22831056Sminshall printf("%c%c%c%c", '\\', '\\', '\\', pchar); 22931056Sminshall } 23031056Sminshall else { 23131056Sminshall printf("%c%c", '\\', pchar); 23231056Sminshall } 23331056Sminshall break; 23431056Sminshall case '^': 23531056Sminshall numbchars += 3; 23631056Sminshall if (toshell) { 23731056Sminshall printf("%c%c%c", '\\', '\\', pchar); 23831056Sminshall } 23931056Sminshall else { 24031056Sminshall printf("%c%c", '\\', pchar); 24131056Sminshall } 24231056Sminshall break; 24331056Sminshall default: 24431100Sminshall st2 = uncontrol(pchar); 24531056Sminshall while ((pchar = *st2++) != 0) { 24631056Sminshall switch (pchar) { 24731056Sminshall case '"': 24831056Sminshall case '!': 24931056Sminshall case '$': 25031056Sminshall case '(': 25131056Sminshall case ')': 25231056Sminshall case ' ': 25331056Sminshall case ';': 25431056Sminshall case '&': 25531056Sminshall case '|': 25631056Sminshall case '>': 25731056Sminshall case '<': 25831056Sminshall case '`': 25931056Sminshall case '#': 26031056Sminshall case '\\': 26131056Sminshall case '\'': 26231056Sminshall if (toshell) { 26331056Sminshall numbchars += 2; 26431056Sminshall printf("%c%c", '\\', pchar); 26531056Sminshall } 26631056Sminshall else { 26731056Sminshall printf("%c", pchar); 26831056Sminshall } 26931056Sminshall break; 27031056Sminshall default: 27131056Sminshall numbchars++; 27231056Sminshall printf("%c", pchar); 27331056Sminshall break; 27431056Sminshall } 27531056Sminshall } 27631056Sminshall break; 27731056Sminshall } 27831056Sminshall } 27931056Sminshall numbchars += 2; 28031056Sminshall if (toshell) { 28131056Sminshall printf("%c'", '\\'); 28231056Sminshall } 28331056Sminshall else { 28431056Sminshall printf("'"); 28531056Sminshall } 28631056Sminshall } 28731056Sminshall 28831056Sminshall static void 28931056Sminshall recurse(strcount, head) 29031056Sminshall state *head; 29131056Sminshall int strcount; 29231056Sminshall { 29331056Sminshall /* if there is a left, 29431056Sminshall * recurse on left, 29531056Sminshall * if there is no down, 29631056Sminshall * print the string to here 29731056Sminshall * else, 29831056Sminshall * add the current match to the string, 29931056Sminshall * recurse. 30031056Sminshall * exit. 30131056Sminshall */ 30231056Sminshall 30331056Sminshall if (head->next) { 30431056Sminshall recurse(strcount, head->next); 30531056Sminshall } 30631245Sminshall if (head->result != STATE_GOTO) { 30731056Sminshall rptr->match_end = addString(strcount, head->match); 30831245Sminshall rptr->result = astosc[head->result].name; 30931056Sminshall rptr = doRegister(rptr); 31031056Sminshall } else { 31131056Sminshall (void) addString(strcount, head->match); 31231056Sminshall recurse(strcount+1, head->address); 31331056Sminshall strcount--; 31431056Sminshall } 31531056Sminshall return; 31631056Sminshall } 31731056Sminshall 31831056Sminshall 31931056Sminshall main(argc, argv) 32031056Sminshall int argc; 32131056Sminshall char *argv[]; 32231056Sminshall { 32331056Sminshall state *head; 32431056Sminshall char *keybdPointer = (char *) 0; 32531056Sminshall char *commandName = argv[0]; 32631056Sminshall extern char *getenv(); 32731056Sminshall int picky = 0; 32831056Sminshall 32931056Sminshall while ((argc > 1) && (argv[1][0] == '-')) { 33031056Sminshall if (!strcmp(argv[1], "-picky")) { 33131056Sminshall picky++; 33231056Sminshall } else if (!strcmp(argv[1], "-shell")) { 33331056Sminshall toshell++; 33431056Sminshall } else { 33531056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 33631056Sminshall commandName); 33731056Sminshall exit(1); 33831056Sminshall /*NOTREACHED*/ 33931056Sminshall } 34031056Sminshall argv++; 34131056Sminshall argc--; 34231056Sminshall } 34331056Sminshall if (argc == 2) { 34431056Sminshall keybdPointer = argv[1]; 34531056Sminshall } else if (argc > 2) { 34631056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 34731056Sminshall commandName); 34831056Sminshall exit(1); 34931056Sminshall /*NOTREACHED*/ 35031056Sminshall } 35131245Sminshall head = InitControl(keybdPointer, picky, ascii_to_index); 35231056Sminshall if (!head) { 35331056Sminshall return(1); 35431056Sminshall } 35531056Sminshall if (keybdPointer == 0) { 35631056Sminshall keybdPointer = getenv("KEYBD"); 35731056Sminshall } 35831056Sminshall if (keybdPointer == 0) { 35931056Sminshall keybdPointer = getenv("TERM"); 36031056Sminshall } 36131056Sminshall if (keybdPointer == 0) { 36231056Sminshall keybdPointer = "3a"; /* use 3a as the terminal */ 36331056Sminshall } 36431056Sminshall if (toshell) { 36531056Sminshall printf("set noglob;\nsetenv MAP3270 "); 36631056Sminshall } 36731056Sminshall printf("%s{", keybdPointer); 36831056Sminshall numbchars = 2 + strlen(keybdPointer); 36931056Sminshall /* now, run through the table registering entries */ 37031056Sminshall rptr = regstates + 2; 37131056Sminshall recurse(0, head); 37231056Sminshall /* now print them out */ 37331056Sminshall for (rptr = regstates[0].forward; rptr->result != 0; 37431056Sminshall rptr = rptr->forward) { 37531056Sminshall printString(rptr->match_end, rptr->match_start, rptr->result); 37631056Sminshall } 37731056Sminshall if (toshell) { 37831056Sminshall printf("%c;};\nunset noglob;\n", '\\'); 37931056Sminshall } 38031056Sminshall else { 38131056Sminshall printf(";}\n"); 38231056Sminshall } 38331056Sminshall return(0); 38431056Sminshall } 385