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 "../ctlr/function.h" 40 41 #include "state.h" 42 #include "astosc.h" 43 44 #include "../general/globals.h" 45 #include "map3270.ext" 46 47 struct regstate { 48 char *result; 49 char *match_start; 50 char *match_end; /* start of NEXT state's match string */ 51 struct regstate *forward; 52 struct regstate *backward; 53 }; 54 55 static struct regstate regstates[500], *rptr= 0; /* for sorting states */ 56 static char array[5000]; /* lot's of room */ 57 static int toshell = 0; /* export to shell */ 58 static int numbchars = 0; /* number of chars in envir. var */ 59 60 static void 61 forwRegister(regptr, sptr) 62 struct regstate *regptr, *sptr; 63 { 64 65 regptr->forward = sptr->forward; 66 regptr->backward = sptr; 67 (sptr->forward)->backward = regptr; 68 sptr->forward = regptr; 69 } 70 71 static void 72 backRegister(regptr, sptr) 73 struct regstate *regptr, *sptr; 74 { 75 76 regptr->forward = sptr; 77 regptr->backward = sptr->backward; 78 (sptr->backward)->forward = regptr; 79 sptr->backward = regptr; 80 } 81 82 static struct regstate * 83 doRegister(regptr) 84 register struct regstate *regptr; 85 { 86 static struct regstate *pivot = regstates; 87 register struct regstate *sptr = pivot; 88 int check; 89 90 if (pivot == regstates) { /* first time called */ 91 pivot->forward = regptr; 92 regptr->backward = pivot++; 93 pivot->backward = regptr; 94 regptr->forward = pivot++; 95 return(++regptr); 96 } 97 if ((check = strcmp(regptr->result, pivot->result)) < 0) { 98 while (check < 0) { 99 if (sptr->backward == regstates) { 100 backRegister(regptr, sptr); 101 pivot = pivot->backward; 102 return(++regptr); 103 } 104 sptr = sptr->backward; 105 check = strcmp(regptr->result, sptr->result); 106 } 107 forwRegister(regptr, sptr); 108 pivot = pivot->backward; 109 return(++regptr); 110 } 111 while (check > 0) { 112 if ((sptr->forward)->result == 0) { 113 forwRegister(regptr, sptr); 114 pivot = pivot->forward; 115 return(++regptr); 116 } 117 sptr = sptr->forward; 118 check = strcmp(regptr->result, sptr->result); 119 } 120 backRegister(regptr, sptr); 121 pivot = pivot->forward; 122 return(++regptr); 123 } 124 125 static char * 126 addString(strcount, character) 127 int strcount; 128 char character; 129 { 130 static char *string = array; 131 int i; 132 133 if (rptr->match_start == 0) { 134 rptr->match_start = string; 135 for (i=0; i < strcount; i++) { 136 *string++ = *((rptr-1)->match_start+i); 137 } 138 } 139 *string++ = character; 140 return(string); 141 } 142 143 static char savename[20] = " "; /* for deciding if name is new */ 144 145 static void 146 printString(string, begin, tc_name) 147 register char *string; 148 char *begin, *tc_name; 149 { 150 register char *st1, *st2; 151 register int pchar; 152 static char suffix = 'A'; 153 int new = strcmp(savename, tc_name); 154 char delim = new ? ';' : '|'; 155 char *uncontrol(); 156 157 st1 = begin; 158 159 numbchars += 5 + (new ? strlen(tc_name) : -1); 160 if (toshell && numbchars > 1011) { 161 new = 1; 162 delim = ';'; 163 numbchars = 5 + strlen(tc_name); 164 printf(";\nsetenv MAP3270%c ", suffix++); 165 } 166 if (strcmp(" ", savename)) { 167 if (toshell) { 168 printf("%c%c", '\\', delim); 169 } 170 else { 171 printf("%c", delim); 172 } 173 } 174 else { 175 numbchars -= 2; 176 } 177 if (toshell && new) { 178 printf("%s=%c'", tc_name,'\\'); 179 } 180 else if (new) { 181 printf("%s='", tc_name); 182 } 183 else if (toshell) { 184 printf("%c'", '\\'); 185 } 186 else { 187 printf("'"); 188 } 189 (void) strcpy(savename, tc_name); 190 while (st1 != string) { 191 if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */ 192 numbchars = 0; 193 printf(";\nsetenv MAP3270%c ", suffix++); 194 } 195 pchar = 0xff&(*st1++); 196 switch (pchar) { 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 case '#': 210 numbchars += 2; 211 if (toshell) { 212 printf("%c%c", '\\', pchar); 213 } 214 else { 215 printf("%c", pchar); 216 } 217 break; 218 case '\\': 219 case '\'': 220 numbchars += 4; 221 if (toshell) { 222 printf("%c%c%c%c", '\\', '\\', '\\', pchar); 223 } 224 else { 225 printf("%c%c", '\\', pchar); 226 } 227 break; 228 case '^': 229 numbchars += 3; 230 if (toshell) { 231 printf("%c%c%c", '\\', '\\', pchar); 232 } 233 else { 234 printf("%c%c", '\\', pchar); 235 } 236 break; 237 default: 238 st2 = uncontrol(pchar); 239 while ((pchar = *st2++) != 0) { 240 switch (pchar) { 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 case '\'': 256 if (toshell) { 257 numbchars += 2; 258 printf("%c%c", '\\', pchar); 259 } 260 else { 261 printf("%c", pchar); 262 } 263 break; 264 default: 265 numbchars++; 266 printf("%c", pchar); 267 break; 268 } 269 } 270 break; 271 } 272 } 273 numbchars += 2; 274 if (toshell) { 275 printf("%c'", '\\'); 276 } 277 else { 278 printf("'"); 279 } 280 } 281 282 static void 283 recurse(strcount, head) 284 state *head; 285 int strcount; 286 { 287 /* if there is a left, 288 * recurse on left, 289 * if there is no down, 290 * print the string to here 291 * else, 292 * add the current match to the string, 293 * recurse. 294 * exit. 295 */ 296 297 if (head->next) { 298 recurse(strcount, head->next); 299 } 300 if (head->result != STATE_GOTO) { 301 rptr->match_end = addString(strcount, head->match); 302 rptr->result = astosc[head->result].name; 303 rptr = doRegister(rptr); 304 } else { 305 (void) addString(strcount, head->match); 306 recurse(strcount+1, head->address); 307 strcount--; 308 } 309 return; 310 } 311 312 313 main(argc, argv) 314 int argc; 315 char *argv[]; 316 { 317 state *head; 318 char *keybdPointer = (char *) 0; 319 char *commandName = argv[0]; 320 extern char *getenv(); 321 int picky = 0; 322 323 while ((argc > 1) && (argv[1][0] == '-')) { 324 if (!strcmp(argv[1], "-picky")) { 325 picky++; 326 } else if (!strcmp(argv[1], "-shell")) { 327 toshell++; 328 } else { 329 fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 330 commandName); 331 exit(1); 332 /*NOTREACHED*/ 333 } 334 argv++; 335 argc--; 336 } 337 if (argc == 2) { 338 keybdPointer = argv[1]; 339 } else if (argc > 2) { 340 fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n", 341 commandName); 342 exit(1); 343 /*NOTREACHED*/ 344 } 345 head = InitControl(keybdPointer, picky, ascii_to_index); 346 if (!head) { 347 return(1); 348 } 349 if (keybdPointer == 0) { 350 keybdPointer = getenv("KEYBD"); 351 } 352 if (keybdPointer == 0) { 353 keybdPointer = getenv("TERM"); 354 } 355 if (keybdPointer == 0) { 356 keybdPointer = "3a"; /* use 3a as the terminal */ 357 } 358 if (toshell) { 359 printf("set noglob;\nsetenv MAP3270 "); 360 } 361 printf("%s{", keybdPointer); 362 numbchars = 2 + strlen(keybdPointer); 363 /* now, run through the table registering entries */ 364 rptr = regstates + 2; 365 recurse(0, head); 366 /* now print them out */ 367 for (rptr = regstates[0].forward; rptr->result != 0; 368 rptr = rptr->forward) { 369 printString(rptr->match_end, rptr->match_start, rptr->result); 370 } 371 if (toshell) { 372 printf("%c;};\nunset noglob;\n", '\\'); 373 } 374 else { 375 printf(";}\n"); 376 } 377 return(0); 378 } 379