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