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) */ 3931245Sminshall #include "../ctlr/function.h" 4031245Sminshall 4131176Sminshall #include "state.h" 4231245Sminshall #include "astosc.h" 4331056Sminshall 4431176Sminshall #include "../general/globals.h" 4531176Sminshall #include "map3270.ext" 4631056Sminshall 4731056Sminshall struct regstate { 4831056Sminshall char *result; 4931056Sminshall char *match_start; 5031056Sminshall char *match_end; /* start of NEXT state's match string */ 5131056Sminshall struct regstate *forward; 5231056Sminshall struct regstate *backward; 5331056Sminshall }; 5431056Sminshall 5531056Sminshall static struct regstate regstates[500], *rptr= 0; /* for sorting states */ 5631056Sminshall static char array[5000]; /* lot's of room */ 5731056Sminshall static int toshell = 0; /* export to shell */ 5831056Sminshall static int numbchars = 0; /* number of chars in envir. var */ 5931056Sminshall 60*31445Sminshall static int 61*31445Sminshall MyStrcmp(str1, str2) 62*31445Sminshall char *str1, *str2; 63*31445Sminshall { 64*31445Sminshall if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0 65*31445Sminshall && strlen(str1) != strlen(str2)) { 66*31445Sminshall return(strlen(str1) - strlen(str2)); 67*31445Sminshall } 68*31445Sminshall return(strcmp(str1, str2)); 69*31445Sminshall } 70*31445Sminshall 7131056Sminshall static void 7231056Sminshall forwRegister(regptr, sptr) 7331056Sminshall struct regstate *regptr, *sptr; 7431056Sminshall { 7531056Sminshall 7631056Sminshall regptr->forward = sptr->forward; 7731056Sminshall regptr->backward = sptr; 7831056Sminshall (sptr->forward)->backward = regptr; 7931056Sminshall sptr->forward = regptr; 8031056Sminshall } 8131056Sminshall 8231056Sminshall static void 8331056Sminshall backRegister(regptr, sptr) 8431056Sminshall struct regstate *regptr, *sptr; 8531056Sminshall { 8631056Sminshall 8731056Sminshall regptr->forward = sptr; 8831056Sminshall regptr->backward = sptr->backward; 8931056Sminshall (sptr->backward)->forward = regptr; 9031056Sminshall sptr->backward = regptr; 9131056Sminshall } 9231056Sminshall 9331056Sminshall static struct regstate * 9431056Sminshall doRegister(regptr) 9531056Sminshall register struct regstate *regptr; 9631056Sminshall { 9731056Sminshall static struct regstate *pivot = regstates; 9831056Sminshall register struct regstate *sptr = pivot; 9931056Sminshall int check; 10031056Sminshall 10131056Sminshall if (pivot == regstates) { /* first time called */ 10231056Sminshall pivot->forward = regptr; 10331056Sminshall regptr->backward = pivot++; 10431056Sminshall pivot->backward = regptr; 10531056Sminshall regptr->forward = pivot++; 10631056Sminshall return(++regptr); 10731056Sminshall } 108*31445Sminshall if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) { 10931056Sminshall while (check < 0) { 11031056Sminshall if (sptr->backward == regstates) { 11131056Sminshall backRegister(regptr, sptr); 11231056Sminshall pivot = pivot->backward; 11331056Sminshall return(++regptr); 11431056Sminshall } 11531056Sminshall sptr = sptr->backward; 116*31445Sminshall check = MyStrcmp(regptr->result, sptr->result); 11731056Sminshall } 11831056Sminshall forwRegister(regptr, sptr); 11931056Sminshall pivot = pivot->backward; 12031056Sminshall return(++regptr); 12131056Sminshall } 12231056Sminshall while (check > 0) { 12331056Sminshall if ((sptr->forward)->result == 0) { 12431056Sminshall forwRegister(regptr, sptr); 12531056Sminshall pivot = pivot->forward; 12631056Sminshall return(++regptr); 12731056Sminshall } 12831056Sminshall sptr = sptr->forward; 129*31445Sminshall check = MyStrcmp(regptr->result, sptr->result); 13031056Sminshall } 13131056Sminshall backRegister(regptr, sptr); 132*31445Sminshall if (pivot->forward->result) { 133*31445Sminshall pivot = pivot->forward; 134*31445Sminshall } 13531056Sminshall return(++regptr); 13631056Sminshall } 13731056Sminshall 13831056Sminshall static char * 13931056Sminshall addString(strcount, character) 14031056Sminshall int strcount; 14131056Sminshall char character; 14231056Sminshall { 14331056Sminshall static char *string = array; 14431056Sminshall int i; 14531056Sminshall 14631056Sminshall if (rptr->match_start == 0) { 14731056Sminshall rptr->match_start = string; 14831056Sminshall for (i=0; i < strcount; i++) { 14931056Sminshall *string++ = *((rptr-1)->match_start+i); 15031056Sminshall } 15131056Sminshall } 15231056Sminshall *string++ = character; 15331056Sminshall return(string); 15431056Sminshall } 15531056Sminshall 15631056Sminshall static char savename[20] = " "; /* for deciding if name is new */ 15731056Sminshall 15831056Sminshall static void 15931056Sminshall printString(string, begin, tc_name) 16031056Sminshall register char *string; 16131056Sminshall char *begin, *tc_name; 16231056Sminshall { 16331056Sminshall register char *st1, *st2; 16431056Sminshall register int pchar; 16531056Sminshall static char suffix = 'A'; 16631056Sminshall int new = strcmp(savename, tc_name); 16731056Sminshall char delim = new ? ';' : '|'; 16831100Sminshall char *uncontrol(); 16931056Sminshall 17031056Sminshall st1 = begin; 17131056Sminshall 17231056Sminshall numbchars += 5 + (new ? strlen(tc_name) : -1); 17331056Sminshall if (toshell && numbchars > 1011) { 17431056Sminshall new = 1; 17531056Sminshall delim = ';'; 17631056Sminshall numbchars = 5 + strlen(tc_name); 17731056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 17831056Sminshall } 17931056Sminshall if (strcmp(" ", savename)) { 18031056Sminshall if (toshell) { 18131056Sminshall printf("%c%c", '\\', delim); 18231056Sminshall } 18331056Sminshall else { 18431056Sminshall printf("%c", delim); 18531056Sminshall } 18631056Sminshall } 18731056Sminshall else { 18831056Sminshall numbchars -= 2; 18931056Sminshall } 19031056Sminshall if (toshell && new) { 19131056Sminshall printf("%s=%c'", tc_name,'\\'); 19231056Sminshall } 19331056Sminshall else if (new) { 19431056Sminshall printf("%s='", tc_name); 19531056Sminshall } 19631056Sminshall else if (toshell) { 19731056Sminshall printf("%c'", '\\'); 19831056Sminshall } 19931056Sminshall else { 20031056Sminshall printf("'"); 20131056Sminshall } 20231056Sminshall (void) strcpy(savename, tc_name); 20331056Sminshall while (st1 != string) { 20431056Sminshall if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */ 20531056Sminshall numbchars = 0; 20631056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 20731056Sminshall } 20831056Sminshall pchar = 0xff&(*st1++); 20931056Sminshall switch (pchar) { 21031056Sminshall case '"': 21131056Sminshall case '!': 21231056Sminshall case '$': 21331056Sminshall case '(': 21431056Sminshall case ')': 21531056Sminshall case ' ': 21631056Sminshall case ';': 21731056Sminshall case '&': 21831056Sminshall case '|': 21931056Sminshall case '>': 22031056Sminshall case '<': 22131056Sminshall case '`': 22231056Sminshall case '#': 22331056Sminshall numbchars += 2; 22431056Sminshall if (toshell) { 22531056Sminshall printf("%c%c", '\\', pchar); 22631056Sminshall } 22731056Sminshall else { 22831056Sminshall printf("%c", pchar); 22931056Sminshall } 23031056Sminshall break; 23131056Sminshall case '\\': 23231056Sminshall case '\'': 23331056Sminshall numbchars += 4; 23431056Sminshall if (toshell) { 23531056Sminshall printf("%c%c%c%c", '\\', '\\', '\\', pchar); 23631056Sminshall } 23731056Sminshall else { 23831056Sminshall printf("%c%c", '\\', pchar); 23931056Sminshall } 24031056Sminshall break; 24131056Sminshall case '^': 24231056Sminshall numbchars += 3; 24331056Sminshall if (toshell) { 24431056Sminshall printf("%c%c%c", '\\', '\\', pchar); 24531056Sminshall } 24631056Sminshall else { 24731056Sminshall printf("%c%c", '\\', pchar); 24831056Sminshall } 24931056Sminshall break; 25031056Sminshall default: 25131100Sminshall st2 = uncontrol(pchar); 25231056Sminshall while ((pchar = *st2++) != 0) { 25331056Sminshall switch (pchar) { 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 case '#': 26731056Sminshall case '\\': 26831056Sminshall case '\'': 26931056Sminshall if (toshell) { 27031056Sminshall numbchars += 2; 27131056Sminshall printf("%c%c", '\\', pchar); 27231056Sminshall } 27331056Sminshall else { 27431056Sminshall printf("%c", pchar); 27531056Sminshall } 27631056Sminshall break; 27731056Sminshall default: 27831056Sminshall numbchars++; 27931056Sminshall printf("%c", pchar); 28031056Sminshall break; 28131056Sminshall } 28231056Sminshall } 28331056Sminshall break; 28431056Sminshall } 28531056Sminshall } 28631056Sminshall numbchars += 2; 28731056Sminshall if (toshell) { 28831056Sminshall printf("%c'", '\\'); 28931056Sminshall } 29031056Sminshall else { 29131056Sminshall printf("'"); 29231056Sminshall } 29331056Sminshall } 29431056Sminshall 29531056Sminshall static void 29631056Sminshall recurse(strcount, head) 29731056Sminshall state *head; 29831056Sminshall int strcount; 29931056Sminshall { 30031056Sminshall /* if there is a left, 30131056Sminshall * recurse on left, 30231056Sminshall * if there is no down, 30331056Sminshall * print the string to here 30431056Sminshall * else, 30531056Sminshall * add the current match to the string, 30631056Sminshall * recurse. 30731056Sminshall * exit. 30831056Sminshall */ 30931056Sminshall 31031056Sminshall if (head->next) { 31131056Sminshall recurse(strcount, head->next); 31231056Sminshall } 31331245Sminshall if (head->result != STATE_GOTO) { 31431056Sminshall rptr->match_end = addString(strcount, head->match); 31531245Sminshall rptr->result = astosc[head->result].name; 31631056Sminshall rptr = doRegister(rptr); 31731056Sminshall } else { 31831056Sminshall (void) addString(strcount, head->match); 31931056Sminshall recurse(strcount+1, head->address); 32031056Sminshall strcount--; 32131056Sminshall } 32231056Sminshall return; 32331056Sminshall } 32431056Sminshall 32531056Sminshall 32631056Sminshall main(argc, argv) 32731056Sminshall int argc; 32831056Sminshall char *argv[]; 32931056Sminshall { 33031056Sminshall state *head; 33131056Sminshall char *keybdPointer = (char *) 0; 33231056Sminshall char *commandName = argv[0]; 33331056Sminshall extern char *getenv(); 33431056Sminshall int picky = 0; 33531056Sminshall 33631056Sminshall while ((argc > 1) && (argv[1][0] == '-')) { 33731056Sminshall if (!strcmp(argv[1], "-picky")) { 33831056Sminshall picky++; 33931056Sminshall } else if (!strcmp(argv[1], "-shell")) { 34031056Sminshall toshell++; 34131056Sminshall } else { 34231056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 34331056Sminshall commandName); 34431056Sminshall exit(1); 34531056Sminshall /*NOTREACHED*/ 34631056Sminshall } 34731056Sminshall argv++; 34831056Sminshall argc--; 34931056Sminshall } 35031056Sminshall if (argc == 2) { 35131056Sminshall keybdPointer = argv[1]; 35231056Sminshall } else if (argc > 2) { 35331056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 35431056Sminshall commandName); 35531056Sminshall exit(1); 35631056Sminshall /*NOTREACHED*/ 35731056Sminshall } 35831245Sminshall head = InitControl(keybdPointer, picky, ascii_to_index); 35931056Sminshall if (!head) { 36031056Sminshall return(1); 36131056Sminshall } 36231056Sminshall if (keybdPointer == 0) { 36331056Sminshall keybdPointer = getenv("KEYBD"); 36431056Sminshall } 36531056Sminshall if (keybdPointer == 0) { 36631056Sminshall keybdPointer = getenv("TERM"); 36731056Sminshall } 36831056Sminshall if (keybdPointer == 0) { 36931056Sminshall keybdPointer = "3a"; /* use 3a as the terminal */ 37031056Sminshall } 37131056Sminshall if (toshell) { 37231056Sminshall printf("set noglob;\nsetenv MAP3270 "); 37331056Sminshall } 37431056Sminshall printf("%s{", keybdPointer); 37531056Sminshall numbchars = 2 + strlen(keybdPointer); 37631056Sminshall /* now, run through the table registering entries */ 37731056Sminshall rptr = regstates + 2; 37831056Sminshall recurse(0, head); 37931056Sminshall /* now print them out */ 38031056Sminshall for (rptr = regstates[0].forward; rptr->result != 0; 38131056Sminshall rptr = rptr->forward) { 38231056Sminshall printString(rptr->match_end, rptr->match_start, rptr->result); 38331056Sminshall } 38431056Sminshall if (toshell) { 38531056Sminshall printf("%c;};\nunset noglob;\n", '\\'); 38631056Sminshall } 38731056Sminshall else { 38831056Sminshall printf(";}\n"); 38931056Sminshall } 39031056Sminshall return(0); 39131056Sminshall } 392