1*31056Sminshall /* 2*31056Sminshall * Copyright (c) 1984, 1985, 1986 by the Regents of the 3*31056Sminshall * University of California and by Gregory Glenn Minshall. 4*31056Sminshall * 5*31056Sminshall * Permission to use, copy, modify, and distribute these 6*31056Sminshall * programs and their documentation for any purpose and 7*31056Sminshall * without fee is hereby granted, provided that this 8*31056Sminshall * copyright and permission appear on all copies and 9*31056Sminshall * supporting documentation, the name of the Regents of 10*31056Sminshall * the University of California not be used in advertising 11*31056Sminshall * or publicity pertaining to distribution of the programs 12*31056Sminshall * without specific prior permission, and notice be given in 13*31056Sminshall * supporting documentation that copying and distribution is 14*31056Sminshall * by permission of the Regents of the University of California 15*31056Sminshall * and by Gregory Glenn Minshall. Neither the Regents of the 16*31056Sminshall * University of California nor Gregory Glenn Minshall make 17*31056Sminshall * representations about the suitability of this software 18*31056Sminshall * for any purpose. It is provided "as is" without 19*31056Sminshall * express or implied warranty. 20*31056Sminshall */ 21*31056Sminshall 22*31056Sminshall #ifndef lint 23*31056Sminshall static char sccsid[] = "@(#)mset.c 3.1 10/29/86"; 24*31056Sminshall #endif /* ndef lint */ 25*31056Sminshall 26*31056Sminshall /* 27*31056Sminshall * this program outputs the user's 3270 mapping table in a form suitable 28*31056Sminshall * for inclusion in the environment. Typically, this might be used 29*31056Sminshall * by: 30*31056Sminshall * setenv MAP3270 "`mset`" 31*31056Sminshall */ 32*31056Sminshall 33*31056Sminshall #include <curses.h> 34*31056Sminshall #include <strings.h> 35*31056Sminshall #include "keyboard/state.h" 36*31056Sminshall #define LETS_SEE_ASCII 37*31056Sminshall #include "keyboard/m4.out" 38*31056Sminshall 39*31056Sminshall #include "../system/globals.h" 40*31056Sminshall #include "keyboard/map3270.ext" 41*31056Sminshall 42*31056Sminshall struct regstate { 43*31056Sminshall char *result; 44*31056Sminshall char *match_start; 45*31056Sminshall char *match_end; /* start of NEXT state's match string */ 46*31056Sminshall struct regstate *forward; 47*31056Sminshall struct regstate *backward; 48*31056Sminshall }; 49*31056Sminshall 50*31056Sminshall static struct regstate regstates[500], *rptr= 0; /* for sorting states */ 51*31056Sminshall static char array[5000]; /* lot's of room */ 52*31056Sminshall static int toshell = 0; /* export to shell */ 53*31056Sminshall static int numbchars = 0; /* number of chars in envir. var */ 54*31056Sminshall 55*31056Sminshall static void 56*31056Sminshall forwRegister(regptr, sptr) 57*31056Sminshall struct regstate *regptr, *sptr; 58*31056Sminshall { 59*31056Sminshall 60*31056Sminshall regptr->forward = sptr->forward; 61*31056Sminshall regptr->backward = sptr; 62*31056Sminshall (sptr->forward)->backward = regptr; 63*31056Sminshall sptr->forward = regptr; 64*31056Sminshall } 65*31056Sminshall 66*31056Sminshall static void 67*31056Sminshall backRegister(regptr, sptr) 68*31056Sminshall struct regstate *regptr, *sptr; 69*31056Sminshall { 70*31056Sminshall 71*31056Sminshall regptr->forward = sptr; 72*31056Sminshall regptr->backward = sptr->backward; 73*31056Sminshall (sptr->backward)->forward = regptr; 74*31056Sminshall sptr->backward = regptr; 75*31056Sminshall } 76*31056Sminshall 77*31056Sminshall static struct regstate * 78*31056Sminshall doRegister(regptr) 79*31056Sminshall register struct regstate *regptr; 80*31056Sminshall { 81*31056Sminshall static struct regstate *pivot = regstates; 82*31056Sminshall register struct regstate *sptr = pivot; 83*31056Sminshall int check; 84*31056Sminshall 85*31056Sminshall if (pivot == regstates) { /* first time called */ 86*31056Sminshall pivot->forward = regptr; 87*31056Sminshall regptr->backward = pivot++; 88*31056Sminshall pivot->backward = regptr; 89*31056Sminshall regptr->forward = pivot++; 90*31056Sminshall return(++regptr); 91*31056Sminshall } 92*31056Sminshall if ((check = strcmp(regptr->result, pivot->result)) < 0) { 93*31056Sminshall while (check < 0) { 94*31056Sminshall if (sptr->backward == regstates) { 95*31056Sminshall backRegister(regptr, sptr); 96*31056Sminshall pivot = pivot->backward; 97*31056Sminshall return(++regptr); 98*31056Sminshall } 99*31056Sminshall sptr = sptr->backward; 100*31056Sminshall check = strcmp(regptr->result, sptr->result); 101*31056Sminshall } 102*31056Sminshall forwRegister(regptr, sptr); 103*31056Sminshall pivot = pivot->backward; 104*31056Sminshall return(++regptr); 105*31056Sminshall } 106*31056Sminshall while (check > 0) { 107*31056Sminshall if ((sptr->forward)->result == 0) { 108*31056Sminshall forwRegister(regptr, sptr); 109*31056Sminshall pivot = pivot->forward; 110*31056Sminshall return(++regptr); 111*31056Sminshall } 112*31056Sminshall sptr = sptr->forward; 113*31056Sminshall check = strcmp(regptr->result, sptr->result); 114*31056Sminshall } 115*31056Sminshall backRegister(regptr, sptr); 116*31056Sminshall pivot = pivot->forward; 117*31056Sminshall return(++regptr); 118*31056Sminshall } 119*31056Sminshall 120*31056Sminshall static char * 121*31056Sminshall addString(strcount, character) 122*31056Sminshall int strcount; 123*31056Sminshall char character; 124*31056Sminshall { 125*31056Sminshall static char *string = array; 126*31056Sminshall int i; 127*31056Sminshall 128*31056Sminshall if (rptr->match_start == 0) { 129*31056Sminshall rptr->match_start = string; 130*31056Sminshall for (i=0; i < strcount; i++) { 131*31056Sminshall *string++ = *((rptr-1)->match_start+i); 132*31056Sminshall } 133*31056Sminshall } 134*31056Sminshall *string++ = character; 135*31056Sminshall return(string); 136*31056Sminshall } 137*31056Sminshall 138*31056Sminshall static char savename[20] = " "; /* for deciding if name is new */ 139*31056Sminshall 140*31056Sminshall static void 141*31056Sminshall printString(string, begin, tc_name) 142*31056Sminshall register char *string; 143*31056Sminshall char *begin, *tc_name; 144*31056Sminshall { 145*31056Sminshall register char *st1, *st2; 146*31056Sminshall register int pchar; 147*31056Sminshall static char suffix = 'A'; 148*31056Sminshall int new = strcmp(savename, tc_name); 149*31056Sminshall char delim = new ? ';' : '|'; 150*31056Sminshall 151*31056Sminshall st1 = begin; 152*31056Sminshall 153*31056Sminshall numbchars += 5 + (new ? strlen(tc_name) : -1); 154*31056Sminshall if (toshell && numbchars > 1011) { 155*31056Sminshall new = 1; 156*31056Sminshall delim = ';'; 157*31056Sminshall numbchars = 5 + strlen(tc_name); 158*31056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 159*31056Sminshall } 160*31056Sminshall if (strcmp(" ", savename)) { 161*31056Sminshall if (toshell) { 162*31056Sminshall printf("%c%c", '\\', delim); 163*31056Sminshall } 164*31056Sminshall else { 165*31056Sminshall printf("%c", delim); 166*31056Sminshall } 167*31056Sminshall } 168*31056Sminshall else { 169*31056Sminshall numbchars -= 2; 170*31056Sminshall } 171*31056Sminshall if (toshell && new) { 172*31056Sminshall printf("%s=%c'", tc_name,'\\'); 173*31056Sminshall } 174*31056Sminshall else if (new) { 175*31056Sminshall printf("%s='", tc_name); 176*31056Sminshall } 177*31056Sminshall else if (toshell) { 178*31056Sminshall printf("%c'", '\\'); 179*31056Sminshall } 180*31056Sminshall else { 181*31056Sminshall printf("'"); 182*31056Sminshall } 183*31056Sminshall (void) strcpy(savename, tc_name); 184*31056Sminshall while (st1 != string) { 185*31056Sminshall if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */ 186*31056Sminshall numbchars = 0; 187*31056Sminshall printf(";\nsetenv MAP3270%c ", suffix++); 188*31056Sminshall } 189*31056Sminshall pchar = 0xff&(*st1++); 190*31056Sminshall switch (pchar) { 191*31056Sminshall case '"': 192*31056Sminshall case '!': 193*31056Sminshall case '$': 194*31056Sminshall case '(': 195*31056Sminshall case ')': 196*31056Sminshall case ' ': 197*31056Sminshall case ';': 198*31056Sminshall case '&': 199*31056Sminshall case '|': 200*31056Sminshall case '>': 201*31056Sminshall case '<': 202*31056Sminshall case '`': 203*31056Sminshall case '#': 204*31056Sminshall numbchars += 2; 205*31056Sminshall if (toshell) { 206*31056Sminshall printf("%c%c", '\\', pchar); 207*31056Sminshall } 208*31056Sminshall else { 209*31056Sminshall printf("%c", pchar); 210*31056Sminshall } 211*31056Sminshall break; 212*31056Sminshall case '\\': 213*31056Sminshall case '\'': 214*31056Sminshall numbchars += 4; 215*31056Sminshall if (toshell) { 216*31056Sminshall printf("%c%c%c%c", '\\', '\\', '\\', pchar); 217*31056Sminshall } 218*31056Sminshall else { 219*31056Sminshall printf("%c%c", '\\', pchar); 220*31056Sminshall } 221*31056Sminshall break; 222*31056Sminshall case '^': 223*31056Sminshall numbchars += 3; 224*31056Sminshall if (toshell) { 225*31056Sminshall printf("%c%c%c", '\\', '\\', pchar); 226*31056Sminshall } 227*31056Sminshall else { 228*31056Sminshall printf("%c%c", '\\', pchar); 229*31056Sminshall } 230*31056Sminshall break; 231*31056Sminshall default: 232*31056Sminshall st2 = unctrl(pchar); 233*31056Sminshall while ((pchar = *st2++) != 0) { 234*31056Sminshall switch (pchar) { 235*31056Sminshall case '"': 236*31056Sminshall case '!': 237*31056Sminshall case '$': 238*31056Sminshall case '(': 239*31056Sminshall case ')': 240*31056Sminshall case ' ': 241*31056Sminshall case ';': 242*31056Sminshall case '&': 243*31056Sminshall case '|': 244*31056Sminshall case '>': 245*31056Sminshall case '<': 246*31056Sminshall case '`': 247*31056Sminshall case '#': 248*31056Sminshall case '\\': 249*31056Sminshall case '\'': 250*31056Sminshall if (toshell) { 251*31056Sminshall numbchars += 2; 252*31056Sminshall printf("%c%c", '\\', pchar); 253*31056Sminshall } 254*31056Sminshall else { 255*31056Sminshall printf("%c", pchar); 256*31056Sminshall } 257*31056Sminshall break; 258*31056Sminshall default: 259*31056Sminshall numbchars++; 260*31056Sminshall printf("%c", pchar); 261*31056Sminshall break; 262*31056Sminshall } 263*31056Sminshall } 264*31056Sminshall break; 265*31056Sminshall } 266*31056Sminshall } 267*31056Sminshall numbchars += 2; 268*31056Sminshall if (toshell) { 269*31056Sminshall printf("%c'", '\\'); 270*31056Sminshall } 271*31056Sminshall else { 272*31056Sminshall printf("'"); 273*31056Sminshall } 274*31056Sminshall } 275*31056Sminshall 276*31056Sminshall static void 277*31056Sminshall recurse(strcount, head) 278*31056Sminshall state *head; 279*31056Sminshall int strcount; 280*31056Sminshall { 281*31056Sminshall /* if there is a left, 282*31056Sminshall * recurse on left, 283*31056Sminshall * if there is no down, 284*31056Sminshall * print the string to here 285*31056Sminshall * else, 286*31056Sminshall * add the current match to the string, 287*31056Sminshall * recurse. 288*31056Sminshall * exit. 289*31056Sminshall */ 290*31056Sminshall 291*31056Sminshall if (head->next) { 292*31056Sminshall recurse(strcount, head->next); 293*31056Sminshall } 294*31056Sminshall if (head->result != TC_GOTO) { 295*31056Sminshall rptr->match_end = addString(strcount, head->match); 296*31056Sminshall rptr->result = TC_Ascii[head->result - TC_LOWEST].tc_name; 297*31056Sminshall rptr = doRegister(rptr); 298*31056Sminshall } else { 299*31056Sminshall (void) addString(strcount, head->match); 300*31056Sminshall recurse(strcount+1, head->address); 301*31056Sminshall strcount--; 302*31056Sminshall } 303*31056Sminshall return; 304*31056Sminshall } 305*31056Sminshall 306*31056Sminshall 307*31056Sminshall main(argc, argv) 308*31056Sminshall int argc; 309*31056Sminshall char *argv[]; 310*31056Sminshall { 311*31056Sminshall state *head; 312*31056Sminshall char *keybdPointer = (char *) 0; 313*31056Sminshall char *commandName = argv[0]; 314*31056Sminshall extern char *getenv(); 315*31056Sminshall int picky = 0; 316*31056Sminshall 317*31056Sminshall while ((argc > 1) && (argv[1][0] == '-')) { 318*31056Sminshall if (!strcmp(argv[1], "-picky")) { 319*31056Sminshall picky++; 320*31056Sminshall } else if (!strcmp(argv[1], "-shell")) { 321*31056Sminshall toshell++; 322*31056Sminshall } else { 323*31056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 324*31056Sminshall commandName); 325*31056Sminshall exit(1); 326*31056Sminshall /*NOTREACHED*/ 327*31056Sminshall } 328*31056Sminshall argv++; 329*31056Sminshall argc--; 330*31056Sminshall } 331*31056Sminshall if (argc == 2) { 332*31056Sminshall keybdPointer = argv[1]; 333*31056Sminshall } else if (argc > 2) { 334*31056Sminshall fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 335*31056Sminshall commandName); 336*31056Sminshall exit(1); 337*31056Sminshall /*NOTREACHED*/ 338*31056Sminshall } 339*31056Sminshall head = InitControl(keybdPointer, picky); 340*31056Sminshall if (!head) { 341*31056Sminshall return(1); 342*31056Sminshall } 343*31056Sminshall if (keybdPointer == 0) { 344*31056Sminshall keybdPointer = getenv("KEYBD"); 345*31056Sminshall } 346*31056Sminshall if (keybdPointer == 0) { 347*31056Sminshall keybdPointer = getenv("TERM"); 348*31056Sminshall } 349*31056Sminshall if (keybdPointer == 0) { 350*31056Sminshall keybdPointer = "3a"; /* use 3a as the terminal */ 351*31056Sminshall } 352*31056Sminshall if (toshell) { 353*31056Sminshall printf("set noglob;\nsetenv MAP3270 "); 354*31056Sminshall } 355*31056Sminshall printf("%s{", keybdPointer); 356*31056Sminshall numbchars = 2 + strlen(keybdPointer); 357*31056Sminshall /* now, run through the table registering entries */ 358*31056Sminshall rptr = regstates + 2; 359*31056Sminshall recurse(0, head); 360*31056Sminshall /* now print them out */ 361*31056Sminshall for (rptr = regstates[0].forward; rptr->result != 0; 362*31056Sminshall rptr = rptr->forward) { 363*31056Sminshall printString(rptr->match_end, rptr->match_start, rptr->result); 364*31056Sminshall } 365*31056Sminshall if (toshell) { 366*31056Sminshall printf("%c;};\nunset noglob;\n", '\\'); 367*31056Sminshall } 368*31056Sminshall else { 369*31056Sminshall printf(";}\n"); 370*31056Sminshall } 371*31056Sminshall return(0); 372*31056Sminshall } 373