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