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