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