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

Defined functions

EatToNL defined in line 373; used 1 times
FindMatchAtThisLevel defined in line 433; used 1 times
FreeState defined in line 410; used 1 times
Get defined in line 130; used 16 times
GetAlphaMericString defined in line 343; used 4 times
GetBegin defined in line 644; used 1 times
GetC defined in line 113; used 3 times
GetCharString defined in line 285; never used
GetCharacter defined in line 308; used 7 times
GetDefinition defined in line 564; used 2 times
GetDefinitions defined in line 631; used 1 times
GetEnd defined in line 654; used 1 times
GetEntry defined in line 714; used 1 times
GetEntry0 defined in line 695; used 2 times
GetInput defined in line 494; used 2 times
GetName defined in line 664; used 2 times
GetNames defined in line 677; used 1 times
GetQuotedString defined in line 254; used 2 times
GetState defined in line 418; used 1 times
GetString defined in line 324; never used
GetTc defined in line 545; used 1 times
GetWS defined in line 392; used 17 times
InitControl defined in line 782; used 4 times
PasteEntry defined in line 448; used 3 times
Position defined in line 729; used 4 times
UnGet defined in line 204; used 11 times
ustrcmp defined in line 227; used 2 times

Defined variables

Empty defined in line 107; used 3 times
Map3270 defined in line 95; used 2 times
debug defined in line 92; used 4 times
doPaste defined in line 97; used 6 times
environPointer defined in line 100; used 10 times
keys3a defined in line 103; used 1 times
lexicon defined in line 130; used 16 times
rp defined in line 110; used 6 times
sccsid defined in line 24; never used
usePointer defined in line 98; used 4 times

Defined macros

CARRIAGE_RETURN defined in line 70; used 1 times
ESCAPE defined in line 67; used 1 times
IsAlnum defined in line 349; used 2 times
IsPrint defined in line 52; used 5 times
LETS_SEE_ASCII defined in line 54; never used
LEX_CARETED defined in line 62; used 2 times
LEX_CHAR defined in line 60; used 12 times
LEX_END_OF_FILE defined in line 63; used 6 times
LEX_ESCAPED defined in line 61; used 3 times
LEX_ILLEGAL defined in line 64; used 4 times
NEWLINE defined in line 69; used 1 times
Return defined in line 736; used 4 times
TAB defined in line 68; used 1 times
panic defined in line 82; used 1 times
Last modified: 1996-11-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5092
Valid CSS Valid XHTML 1.0 Strict