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