|
|
1.1 ! root 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: static char sccsid[] = "@(#)map3270.c 4.1 (Berkeley) 12/4/88"; ! 20: #endif /* not lint */ ! 21: ! 22: /* This program reads a description file, somewhat like /etc/termcap, ! 23: that describes the mapping between the current terminal's keyboard and ! 24: a 3270 keyboard. ! 25: */ ! 26: #ifdef DOCUMENTATION_ONLY ! 27: /* here is a sample (very small) entry... ! 28: ! 29: # this table is sensitive to position on a line. In particular, ! 30: # a terminal definition for a terminal is terminated whenever a ! 31: # (non-comment) line beginning in column one is found. ! 32: # ! 33: # this is an entry to map tvi924 to 3270 keys... ! 34: v8|tvi924|924|televideo model 924 { ! 35: pfk1 = '\E1'; ! 36: pfk2 = '\E2'; ! 37: clear = '^z'; # clear the screen ! 38: } ! 39: */ ! 40: #endif /* DOCUMENTATION_ONLY */ ! 41: ! 42: #include <stdio.h> ! 43: #include <ctype.h> ! 44: #if defined(unix) ! 45: #include <strings.h> ! 46: #else /* defined(unix) */ ! 47: #include <string.h> ! 48: #endif /* defined(unix) */ ! 49: ! 50: #define IsPrint(c) ((isprint(c) && !isspace(c)) || ((c) == ' ')) ! 51: ! 52: #include "state.h" ! 53: #include "map3270.h" ! 54: ! 55: #include "../general/globals.h" ! 56: ! 57: /* this is the list of types returned by the lex processor */ ! 58: #define LEX_CHAR 400 /* plain unadorned character */ ! 59: #define LEX_ESCAPED LEX_CHAR+1 /* escaped with \ */ ! 60: #define LEX_CARETED LEX_ESCAPED+1 /* escaped with ^ */ ! 61: #define LEX_END_OF_FILE LEX_CARETED+1 /* end of file encountered */ ! 62: #define LEX_ILLEGAL LEX_END_OF_FILE+1 /* trailing escape character */ ! 63: ! 64: /* the following is part of our character set dependancy... */ ! 65: #define ESCAPE 0x1b ! 66: #define TAB 0x09 ! 67: #define NEWLINE 0x0a ! 68: #define CARRIAGE_RETURN 0x0d ! 69: ! 70: typedef struct { ! 71: int type; /* LEX_* - type of character */ ! 72: int value; /* character this was */ ! 73: } lexicon; ! 74: ! 75: typedef struct { ! 76: int length; /* length of character string */ ! 77: char array[500]; /* character string */ ! 78: } stringWithLength; ! 79: ! 80: #define panic(s) { fprintf(stderr, s); exit(1); } ! 81: ! 82: static state firstentry = { 0, STATE_NULL, 0, 0 }; ! 83: static state *headOfQueue = &firstentry; ! 84: ! 85: /* the following is a primitive adm3a table, to be used when nothing ! 86: * else seems to be avaliable. ! 87: */ ! 88: ! 89: #ifdef DEBUG ! 90: static int debug = 0; /* debug flag (for debuggin tables) */ ! 91: #endif /* DEBUG */ ! 92: ! 93: static int (*GetTc)(); ! 94: static int doPaste = 1; /* should we have side effects */ ! 95: static int picky = 0; /* do we complain of unknown functions? */ ! 96: static char usePointer = 0; /* use pointer, or file */ ! 97: static FILE *ourFile= 0; ! 98: static char *environPointer = 0;/* if non-zero, point to input ! 99: * string in core. ! 100: */ ! 101: static char **whichkey = 0; ! 102: static char *keysgeneric[] = { ! 103: #include "default.map" /* Define the default default */ ! 104: ! 105: 0, /* Terminate list of entries */ ! 106: }; ! 107: ; ! 108: ! 109: static int Empty = 1, /* is the unget lifo empty? */ ! 110: Full = 0; /* is the unget lifo full? */ ! 111: static lexicon lifo[200] = { 0 }; /* character stack for parser */ ! 112: static int rp = 0, /* read pointer into lifo */ ! 113: wp = 0; /* write pointer into lifo */ ! 114: ! 115: static int ! 116: GetC() ! 117: { ! 118: int character; ! 119: ! 120: if (usePointer) { ! 121: if ((*environPointer) == 0) { ! 122: /* ! 123: * If we have reached the end of this string, go on to ! 124: * the next (if there is a next). ! 125: */ ! 126: if (whichkey == 0) { ! 127: static char suffix = 'A'; /* From environment */ ! 128: char envname[9]; ! 129: extern char *getenv(); ! 130: ! 131: (void) sprintf(envname, "MAP3270%c", suffix++); ! 132: environPointer = getenv(envname); ! 133: } else { ! 134: whichkey++; /* default map */ ! 135: environPointer = *whichkey; ! 136: } ! 137: } ! 138: if (*environPointer) { ! 139: character = 0xff&*environPointer++; ! 140: } else { ! 141: character = EOF; ! 142: } ! 143: } else { ! 144: character = getc(ourFile); ! 145: } ! 146: return(character); ! 147: } ! 148: ! 149: static lexicon ! 150: Get() ! 151: { ! 152: lexicon c; ! 153: register lexicon *pC = &c; ! 154: register int character; ! 155: ! 156: if (!Empty) { ! 157: *pC = lifo[rp]; ! 158: rp++; ! 159: if (rp == sizeof lifo/sizeof (lexicon)) { ! 160: rp = 0; ! 161: } ! 162: if (rp == wp) { ! 163: Empty = 1; ! 164: } ! 165: Full = 0; ! 166: } else { ! 167: character = GetC(); ! 168: switch (character) { ! 169: case EOF: ! 170: pC->type = LEX_END_OF_FILE; ! 171: break; ! 172: case '^': ! 173: character = GetC(); ! 174: if (!IsPrint(character)) { ! 175: pC->type = LEX_ILLEGAL; ! 176: } else { ! 177: pC->type = LEX_CARETED; ! 178: if (character == '?') { ! 179: character |= 0x40; /* rubout */ ! 180: } else { ! 181: character &= 0x1f; ! 182: } ! 183: } ! 184: break; ! 185: case '\\': ! 186: character = GetC(); ! 187: if (!IsPrint(character)) { ! 188: pC->type = LEX_ILLEGAL; ! 189: } else { ! 190: pC->type = LEX_ESCAPED; ! 191: switch (character) { ! 192: case 'E': case 'e': ! 193: character = ESCAPE; ! 194: break; ! 195: case 't': ! 196: character = TAB; ! 197: break; ! 198: case 'n': ! 199: character = NEWLINE; ! 200: break; ! 201: case 'r': ! 202: character = CARRIAGE_RETURN; ! 203: break; ! 204: default: ! 205: pC->type = LEX_ILLEGAL; ! 206: break; ! 207: } ! 208: } ! 209: break; ! 210: default: ! 211: if ((IsPrint(character)) || isspace(character)) { ! 212: pC->type = LEX_CHAR; ! 213: } else { ! 214: pC->type = LEX_ILLEGAL; ! 215: } ! 216: break; ! 217: } ! 218: pC->value = character; ! 219: } ! 220: return(*pC); ! 221: } ! 222: ! 223: static void ! 224: UnGet(c) ! 225: lexicon c; /* character to unget */ ! 226: { ! 227: if (Full) { ! 228: fprintf(stderr, "attempt to put too many characters in lifo\n"); ! 229: panic("map3270"); ! 230: /* NOTREACHED */ ! 231: } else { ! 232: lifo[wp] = c; ! 233: wp++; ! 234: if (wp == sizeof lifo/sizeof (lexicon)) { ! 235: wp = 0; ! 236: } ! 237: if (wp == rp) { ! 238: Full = 1; ! 239: } ! 240: Empty = 0; ! 241: } ! 242: } ! 243: ! 244: /* ! 245: * Construct a control character sequence ! 246: * for a special character. ! 247: */ ! 248: char * ! 249: uncontrol(c) ! 250: register int c; ! 251: { ! 252: static char buf[3]; ! 253: ! 254: if (c == 0x7f) ! 255: return ("^?"); ! 256: if (c == '\377') { ! 257: return "-1"; ! 258: } ! 259: if (c >= 0x20) { ! 260: buf[0] = c; ! 261: buf[1] = 0; ! 262: } else { ! 263: buf[0] = '^'; ! 264: buf[1] = '@'+c; ! 265: buf[2] = 0; ! 266: } ! 267: return (buf); ! 268: } ! 269: ! 270: /* compare two strings, ignoring case */ ! 271: ! 272: ustrcmp(string1, string2) ! 273: register char *string1; ! 274: register char *string2; ! 275: { ! 276: register int c1, c2; ! 277: ! 278: while ((c1 = (unsigned char) *string1++) != 0) { ! 279: if (isupper(c1)) { ! 280: c1 = tolower(c1); ! 281: } ! 282: if (isupper(c2 = (unsigned char) *string2++)) { ! 283: c2 = tolower(c2); ! 284: } ! 285: if (c1 < c2) { ! 286: return(-1); ! 287: } else if (c1 > c2) { ! 288: return(1); ! 289: } ! 290: } ! 291: if (*string2) { ! 292: return(-1); ! 293: } else { ! 294: return(0); ! 295: } ! 296: } ! 297: ! 298: ! 299: static stringWithLength * ! 300: GetQuotedString() ! 301: { ! 302: lexicon lex; ! 303: static stringWithLength output = { 0 }; /* where return value is held */ ! 304: char *pointer = output.array; ! 305: ! 306: lex = Get(); ! 307: if ((lex.type != LEX_CHAR) || (lex.value != '\'')) { ! 308: UnGet(lex); ! 309: return(0); ! 310: } ! 311: while (1) { ! 312: lex = Get(); ! 313: if ((lex.type == LEX_CHAR) && (lex.value == '\'')) { ! 314: break; ! 315: } ! 316: if ((lex.type == LEX_CHAR) && !IsPrint(lex.value)) { ! 317: UnGet(lex); ! 318: return(0); /* illegal character in quoted string */ ! 319: } ! 320: if (pointer >= output.array+sizeof output.array) { ! 321: return(0); /* too long */ ! 322: } ! 323: *pointer++ = lex.value; ! 324: } ! 325: output.length = pointer-output.array; ! 326: return(&output); ! 327: } ! 328: ! 329: #ifdef NOTUSED ! 330: static stringWithLength * ! 331: GetCharString() ! 332: { ! 333: lexicon lex; ! 334: static stringWithLength output; ! 335: char *pointer = output.array; ! 336: ! 337: lex = Get(); ! 338: ! 339: while ((lex.type == LEX_CHAR) && ! 340: !isspace(lex.value) && (lex.value != '=')) { ! 341: *pointer++ = lex.value; ! 342: lex = Get(); ! 343: if (pointer >= output.array + sizeof output.array) { ! 344: return(0); /* too long */ ! 345: } ! 346: } ! 347: UnGet(lex); ! 348: output.length = pointer-output.array; ! 349: return(&output); ! 350: } ! 351: #endif /* NOTUSED */ ! 352: ! 353: static ! 354: GetCharacter(character) ! 355: int character; /* desired character */ ! 356: { ! 357: lexicon lex; ! 358: ! 359: lex = Get(); ! 360: ! 361: if ((lex.type != LEX_CHAR) || (lex.value != character)) { ! 362: UnGet(lex); ! 363: return(0); ! 364: } ! 365: return(1); ! 366: } ! 367: ! 368: #ifdef NOTUSED ! 369: static ! 370: GetString(string) ! 371: char *string; /* string to get */ ! 372: { ! 373: lexicon lex; ! 374: ! 375: while (*string) { ! 376: lex = Get(); ! 377: if ((lex.type != LEX_CHAR) || (lex.value != *string&0xff)) { ! 378: UnGet(lex); ! 379: return(0); /* XXX restore to state on entry */ ! 380: } ! 381: string++; ! 382: } ! 383: return(1); ! 384: } ! 385: #endif /* NOTUSED */ ! 386: ! 387: ! 388: static stringWithLength * ! 389: GetAlphaMericString() ! 390: { ! 391: lexicon lex; ! 392: static stringWithLength output = { 0 }; ! 393: char *pointer = output.array; ! 394: # define IsAlnum(c) (isalnum(c) || (c == '_') \ ! 395: || (c == '-') || (c == '.')) ! 396: ! 397: lex = Get(); ! 398: ! 399: if ((lex.type != LEX_CHAR) || !IsAlnum(lex.value)) { ! 400: UnGet(lex); ! 401: return(0); ! 402: } ! 403: ! 404: while ((lex.type == LEX_CHAR) && IsAlnum(lex.value)) { ! 405: *pointer++ = lex.value; ! 406: lex = Get(); ! 407: } ! 408: UnGet(lex); ! 409: *pointer = 0; ! 410: output.length = pointer-output.array; ! 411: return(&output); ! 412: } ! 413: ! 414: ! 415: /* eat up characters until a new line, or end of file. returns terminating ! 416: character. ! 417: */ ! 418: ! 419: static lexicon ! 420: EatToNL() ! 421: { ! 422: lexicon lex; ! 423: ! 424: lex = Get(); ! 425: ! 426: while (!((lex.type != LEX_ESCAPED) && (lex.type != LEX_CARETED) && ! 427: (lex.value == '\n')) && (!(lex.type == LEX_END_OF_FILE))) { ! 428: lex = Get(); ! 429: } ! 430: if (lex.type != LEX_END_OF_FILE) { ! 431: return(Get()); ! 432: } else { ! 433: return(lex); ! 434: } ! 435: } ! 436: ! 437: ! 438: static void ! 439: GetWS() ! 440: { ! 441: lexicon lex; ! 442: ! 443: lex = Get(); ! 444: ! 445: while ((lex.type == LEX_CHAR) && ! 446: (isspace(lex.value) || (lex.value == '#'))) { ! 447: if (lex.value == '#') { ! 448: lex = EatToNL(); ! 449: } else { ! 450: lex = Get(); ! 451: } ! 452: } ! 453: UnGet(lex); ! 454: } ! 455: ! 456: static void ! 457: FreeState(pState) ! 458: state *pState; ! 459: { ! 460: extern int free(); ! 461: ! 462: free((char *)pState); ! 463: } ! 464: ! 465: ! 466: static state * ! 467: GetState() ! 468: { ! 469: state *pState; ! 470: extern char *malloc(); ! 471: ! 472: pState = (state *) malloc(sizeof (state)); ! 473: ! 474: pState->result = STATE_NULL; ! 475: pState->next = 0; ! 476: ! 477: return(pState); ! 478: } ! 479: ! 480: ! 481: static state * ! 482: FindMatchAtThisLevel(pState, character) ! 483: state *pState; ! 484: int character; ! 485: { ! 486: while (pState) { ! 487: if (pState->match == character) { ! 488: return(pState); ! 489: } ! 490: pState = pState->next; ! 491: } ! 492: return(0); ! 493: } ! 494: ! 495: ! 496: static state * ! 497: PasteEntry(head, string, count, identifier) ! 498: state *head; /* points to who should point here... */ ! 499: char *string; /* which characters to paste */ ! 500: int count; /* number of character to do */ ! 501: char *identifier; /* for error messages */ ! 502: { ! 503: state *pState, *other; ! 504: ! 505: if (!doPaste) { /* flag to not have any side effects */ ! 506: return((state *)1); ! 507: } ! 508: if (!count) { ! 509: return(head); /* return pointer to the parent */ ! 510: } ! 511: if ((head->result != STATE_NULL) && (head->result != STATE_GOTO)) { ! 512: /* this means that a previously defined sequence is an initial ! 513: * part of this one. ! 514: */ ! 515: fprintf(stderr, "Conflicting entries found when scanning %s\n", ! 516: identifier); ! 517: return(0); ! 518: } ! 519: # ifdef DEBUG ! 520: if (debug) { ! 521: fprintf(stderr, "%s", uncontrol(*string)); ! 522: } ! 523: # endif /* DEBUG */ ! 524: pState = GetState(); ! 525: pState->match = *string; ! 526: if (head->result == STATE_NULL) { ! 527: head->result = STATE_GOTO; ! 528: head->address = pState; ! 529: other = pState; ! 530: } else { /* search for same character */ ! 531: if ((other = FindMatchAtThisLevel(head->address, *string)) != 0) { ! 532: FreeState(pState); ! 533: } else { ! 534: pState->next = head->address; ! 535: head->address = pState; ! 536: other = pState; ! 537: } ! 538: } ! 539: return(PasteEntry(other, string+1, count-1, identifier)); ! 540: } ! 541: ! 542: static ! 543: GetInput(tc, identifier) ! 544: int tc; ! 545: char *identifier; /* entry being parsed (for error messages) */ ! 546: { ! 547: stringWithLength *outputString; ! 548: state *head; ! 549: state fakeQueue; ! 550: ! 551: if (doPaste) { ! 552: head = headOfQueue; /* always points to level above this one */ ! 553: } else { ! 554: head = &fakeQueue; /* don't have any side effects... */ ! 555: } ! 556: ! 557: if ((outputString = GetQuotedString()) == 0) { ! 558: return(0); ! 559: } else if (IsPrint(outputString->array[0])) { ! 560: fprintf(stderr, ! 561: "first character of sequence for %s is not a control type character\n", ! 562: identifier); ! 563: return(0); ! 564: } else { ! 565: if ((head = PasteEntry(head, outputString->array, ! 566: outputString->length, identifier)) == 0) { ! 567: return(0); ! 568: } ! 569: GetWS(); ! 570: while ((outputString = GetQuotedString()) != 0) { ! 571: if ((head = PasteEntry(head, outputString->array, ! 572: outputString->length, identifier)) == 0) { ! 573: return(0); ! 574: } ! 575: GetWS(); ! 576: } ! 577: } ! 578: if (!doPaste) { ! 579: return(1); ! 580: } ! 581: if ((head->result != STATE_NULL) && (head->result != tc)) { ! 582: /* this means that this sequence is an initial part ! 583: * of a previously defined one. ! 584: */ ! 585: fprintf(stderr, "Conflicting entries found when scanning %s\n", ! 586: identifier); ! 587: return(0); ! 588: } else { ! 589: head->result = tc; ! 590: return(1); /* done */ ! 591: } ! 592: } ! 593: ! 594: static ! 595: GetDefinition() ! 596: { ! 597: stringWithLength *string; ! 598: int Tc; ! 599: ! 600: GetWS(); ! 601: if ((string = GetAlphaMericString()) == 0) { ! 602: return(0); ! 603: } ! 604: string->array[string->length] = 0; ! 605: if (doPaste) { ! 606: if ((Tc = (*GetTc)(string->array)) == -1) { ! 607: if (picky) { ! 608: fprintf(stderr, "%s: unknown 3270 key identifier\n", ! 609: string->array); ! 610: } ! 611: Tc = STATE_NULL; ! 612: } ! 613: } else { ! 614: Tc = STATE_NULL; /* XXX ? */ ! 615: } ! 616: GetWS(); ! 617: if (!GetCharacter('=')) { ! 618: fprintf(stderr, ! 619: "Required equal sign after 3270 key identifier %s missing\n", ! 620: string->array); ! 621: return(0); ! 622: } ! 623: GetWS(); ! 624: if (!GetInput(Tc, string->array)) { ! 625: fprintf(stderr, "Missing definition part for 3270 key %s\n", ! 626: string->array); ! 627: return(0); ! 628: } else { ! 629: GetWS(); ! 630: while (GetCharacter('|')) { ! 631: # ifdef DEBUG ! 632: if (debug) { ! 633: fprintf(stderr, " or "); ! 634: } ! 635: # endif /* DEBUG */ ! 636: GetWS(); ! 637: if (!GetInput(Tc, string->array)) { ! 638: fprintf(stderr, "Missing definition part for 3270 key %s\n", ! 639: string->array); ! 640: return(0); ! 641: } ! 642: GetWS(); ! 643: } ! 644: } ! 645: GetWS(); ! 646: if (!GetCharacter(';')) { ! 647: fprintf(stderr, "Missing semi-colon for 3270 key %s\n", string->array); ! 648: return(0); ! 649: } ! 650: # ifdef DEBUG ! 651: if (debug) { ! 652: fprintf(stderr, ";\n"); ! 653: } ! 654: # endif /* DEBUG */ ! 655: return(1); ! 656: } ! 657: ! 658: ! 659: static ! 660: GetDefinitions() ! 661: { ! 662: if (!GetDefinition()) { ! 663: return(0); ! 664: } else { ! 665: while (GetDefinition()) { ! 666: ; ! 667: } ! 668: } ! 669: return(1); ! 670: } ! 671: ! 672: static ! 673: GetBegin() ! 674: { ! 675: GetWS(); ! 676: if (!GetCharacter('{')) { ! 677: return(0); ! 678: } ! 679: return(1); ! 680: } ! 681: ! 682: static ! 683: GetEnd() ! 684: { ! 685: GetWS(); ! 686: if (!GetCharacter('}')) { ! 687: return(0); ! 688: } ! 689: return(1); ! 690: } ! 691: ! 692: static ! 693: GetName() ! 694: { ! 695: if (!GetAlphaMericString()) { ! 696: return(0); ! 697: } ! 698: GetWS(); ! 699: while (GetAlphaMericString()) { ! 700: GetWS(); ! 701: } ! 702: return(1); ! 703: } ! 704: ! 705: static ! 706: GetNames() ! 707: { ! 708: GetWS(); ! 709: if (!GetName()) { ! 710: return(0); ! 711: } else { ! 712: GetWS(); ! 713: while (GetCharacter('|')) { ! 714: GetWS(); ! 715: if (!GetName()) { ! 716: return(0); ! 717: } ! 718: } ! 719: } ! 720: return(1); ! 721: } ! 722: ! 723: static ! 724: GetEntry0() ! 725: { ! 726: if (!GetBegin()) { ! 727: fprintf(stderr, "no '{'\n"); ! 728: return(0); ! 729: } else if (!GetDefinitions()) { ! 730: fprintf(stderr, "unable to parse the definitions\n"); ! 731: return(0); ! 732: } else if (!GetEnd()) { ! 733: fprintf(stderr, "No '}' or scanning stopped early due to error.\n"); ! 734: return(0); ! 735: } else { ! 736: /* done */ ! 737: return(1); ! 738: } ! 739: } ! 740: ! 741: ! 742: static ! 743: GetEntry() ! 744: { ! 745: if (!GetNames()) { ! 746: fprintf(stderr, "Invalid name field in entry.\n"); ! 747: return(0); ! 748: } else { ! 749: return(GetEntry0()); ! 750: } ! 751: } ! 752: ! 753: /* position ourselves within a given filename to the entry for the current ! 754: * KEYBD (or TERM) variable ! 755: */ ! 756: ! 757: Position(filename, keybdPointer) ! 758: char *filename; ! 759: char *keybdPointer; ! 760: { ! 761: lexicon lex; ! 762: stringWithLength *name = 0; ! 763: stringWithLength *oldName; ! 764: # define Return(x) {doPaste = 1; return(x);} ! 765: ! 766: doPaste = 0; ! 767: ! 768: if ((ourFile = fopen(filename, "r")) == NULL) { ! 769: # if !defined(MSDOS) ! 770: fprintf(stderr, "Unable to open file %s\n", filename); ! 771: # endif /* !defined(MSDOS) */ ! 772: Return(0); ! 773: } ! 774: lex = Get(); ! 775: while (lex.type != LEX_END_OF_FILE) { ! 776: UnGet(lex); ! 777: /* now, find an entry that is our type. */ ! 778: GetWS(); ! 779: oldName = name; ! 780: if ((name = GetAlphaMericString()) != 0) { ! 781: if (!ustrcmp(name->array, keybdPointer)) { ! 782: /* need to make sure there is a name here... */ ! 783: lex.type = LEX_CHAR; ! 784: lex.value = 'a'; ! 785: UnGet(lex); ! 786: Return(1); ! 787: } ! 788: } else if (GetCharacter('|')) { ! 789: ; /* more names coming */ ! 790: } else { ! 791: lex = Get(); ! 792: UnGet(lex); ! 793: if (lex.type != LEX_END_OF_FILE) { ! 794: if (!GetEntry0()) { /* start of an entry */ ! 795: fprintf(stderr, ! 796: "error was in entry for %s in file %s\n", ! 797: (oldName)? oldName->array:"(unknown)", filename); ! 798: Return(0); ! 799: } ! 800: } ! 801: } ! 802: lex = Get(); ! 803: } ! 804: #if !defined(MSDOS) ! 805: fprintf(stderr, "Unable to find entry for %s in file %s\n", keybdPointer, ! 806: filename); ! 807: #endif /* !defined(MSDOS) */ ! 808: Return(0); ! 809: } ! 810: ! 811: char * ! 812: strsave(string) ! 813: char *string; ! 814: { ! 815: char *p; ! 816: extern char *malloc(); ! 817: ! 818: p = malloc((unsigned int)strlen(string)+1); ! 819: if (p != 0) { ! 820: strcpy(p, string); ! 821: } ! 822: return(p); ! 823: } ! 824: ! 825: ! 826: /* ! 827: * InitControl - our interface to the outside. What we should ! 828: * do is figure out keyboard (or terminal) type, set up file pointer ! 829: * (or string pointer), etc. ! 830: */ ! 831: ! 832: state * ! 833: InitControl(keybdPointer, pickyarg, translator) ! 834: char *keybdPointer; ! 835: int pickyarg; /* Should we be picky? */ ! 836: int (*translator)(); /* Translates ascii string to integer */ ! 837: { ! 838: extern char *getenv(); ! 839: int GotIt; ! 840: ! 841: picky = pickyarg; ! 842: GetTc = translator; ! 843: ! 844: if (keybdPointer == 0) { ! 845: keybdPointer = getenv("KEYBD"); ! 846: } ! 847: if (keybdPointer == 0) { ! 848: keybdPointer = getenv("TERM"); ! 849: } ! 850: ! 851: /* ! 852: * Some environments have getenv() return ! 853: * out of a static area. So, save the keyboard name. ! 854: */ ! 855: if (keybdPointer) { ! 856: keybdPointer = strsave(keybdPointer); ! 857: } ! 858: environPointer = getenv("MAP3270"); ! 859: if (environPointer ! 860: && (environPointer[0] != '/') ! 861: #if defined(MSDOS) ! 862: && (environPointer[0] != '\\') ! 863: #endif /* defined(MSDOS) */ ! 864: && (strncmp(keybdPointer, environPointer, ! 865: strlen(keybdPointer) != 0) ! 866: || (environPointer[strlen(keybdPointer)] != '{'))) /* } */ ! 867: { ! 868: environPointer = 0; ! 869: } ! 870: ! 871: if ((!environPointer) ! 872: #if defined(MSDOS) ! 873: || (*environPointer == '\\') ! 874: #endif /* defined(MSDOS) */ ! 875: || (*environPointer == '/')) { ! 876: usePointer = 0; ! 877: GotIt = 0; ! 878: if (!keybdPointer) { ! 879: #if !defined(MSDOS) ! 880: fprintf(stderr, "%s%s%s%s", ! 881: "Neither the KEYBD environment variable nor the TERM ", ! 882: "environment variable\n(one of which is needed to determine ", ! 883: "the type of keyboard you are using)\n", ! 884: "is set. To set it, say 'setenv KEYBD <type>'\n"); ! 885: #endif /* !defined(MSDOS) */ ! 886: } else { ! 887: if (environPointer) { ! 888: GotIt = Position(environPointer, keybdPointer); ! 889: } ! 890: if (!GotIt) { ! 891: GotIt = Position("/etc/map3270", keybdPointer); ! 892: } ! 893: } ! 894: if (!GotIt) { ! 895: if (environPointer) { ! 896: GotIt = Position(environPointer, "unknown"); ! 897: } ! 898: if (!GotIt) { ! 899: GotIt = Position("/etc/map3270", keybdPointer); ! 900: } ! 901: } ! 902: if (!GotIt) { ! 903: #if !defined(MSDOS) ! 904: fprintf(stderr, "Using default key mappings.\n"); ! 905: #endif /* !defined(MSDOS) */ ! 906: usePointer = 1; /* flag use of non-file */ ! 907: whichkey = keysgeneric; ! 908: environPointer = *whichkey; /* use default table */ ! 909: } ! 910: } else { ! 911: usePointer = 1; ! 912: } ! 913: (void) GetEntry(); ! 914: return(firstentry.address); ! 915: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.