131055Sminshall /* 231055Sminshall * Copyright (c) 1984, 1985, 1986 by the Regents of the 331055Sminshall * University of California and by Gregory Glenn Minshall. 431055Sminshall * 531055Sminshall * Permission to use, copy, modify, and distribute these 631055Sminshall * programs and their documentation for any purpose and 731055Sminshall * without fee is hereby granted, provided that this 831055Sminshall * copyright and permission appear on all copies and 931055Sminshall * supporting documentation, the name of the Regents of 1031055Sminshall * the University of California not be used in advertising 1131055Sminshall * or publicity pertaining to distribution of the programs 1231055Sminshall * without specific prior permission, and notice be given in 1331055Sminshall * supporting documentation that copying and distribution is 1431055Sminshall * by permission of the Regents of the University of California 1531055Sminshall * and by Gregory Glenn Minshall. Neither the Regents of the 1631055Sminshall * University of California nor Gregory Glenn Minshall make 1731055Sminshall * representations about the suitability of this software 1831055Sminshall * for any purpose. It is provided "as is" without 1931055Sminshall * express or implied warranty. 2031055Sminshall */ 2131055Sminshall 2231055Sminshall #ifndef lint 2331055Sminshall static char sccsid[] = "@(#)map3270.c 3.1 10/29/86"; 2431055Sminshall #endif /* ndef lint */ 2531055Sminshall 2631055Sminshall 2731055Sminshall /* This program reads a description file, somewhat like /etc/termcap, 2831055Sminshall that describes the mapping between the current terminal's keyboard and 2931055Sminshall a 3270 keyboard. 3031055Sminshall */ 3131055Sminshall #ifdef DOCUMENTATION_ONLY 3231055Sminshall /* here is a sample (very small) entry... 3331055Sminshall 3431055Sminshall # this table is sensitive to position on a line. In particular, 3531055Sminshall # a terminal definition for a terminal is terminated whenever a 3631055Sminshall # (non-comment) line beginning in column one is found. 3731055Sminshall # 3831055Sminshall # this is an entry to map tvi924 to 3270 keys... 3931055Sminshall v8|tvi924|924|televideo model 924 { 4031055Sminshall pfk1 = '\E1'; 4131055Sminshall pfk2 = '\E2'; 4231055Sminshall clear = '^z'; # clear the screen 4331055Sminshall } 4431055Sminshall */ 4531055Sminshall #endif /* DOCUMENTATION_ONLY */ 4631055Sminshall 4731055Sminshall #include <stdio.h> 4831055Sminshall #include <ctype.h> 4931100Sminshall #if defined(unix) 5031055Sminshall #include <strings.h> 5131100Sminshall #else /* defined(unix) */ 5231100Sminshall #include <string.h> 5331100Sminshall #endif /* defined(unix) */ 5431055Sminshall 5531055Sminshall #define IsPrint(c) ((isprint(c) && !isspace(c)) || ((c) == ' ')) 5631055Sminshall 5731055Sminshall #define LETS_SEE_ASCII 5831055Sminshall #include "m4.out" 5931055Sminshall 6031055Sminshall #include "state.h" 6131055Sminshall 62*31176Sminshall #include "../general/globals.h" 6331055Sminshall #include "map3270.ext" 6431055Sminshall 6531055Sminshall /* this is the list of types returned by the lex processor */ 6631055Sminshall #define LEX_CHAR TC_HIGHEST /* plain unadorned character */ 6731055Sminshall #define LEX_ESCAPED LEX_CHAR+1 /* escaped with \ */ 6831055Sminshall #define LEX_CARETED LEX_ESCAPED+1 /* escaped with ^ */ 6931055Sminshall #define LEX_END_OF_FILE LEX_CARETED+1 /* end of file encountered */ 7031055Sminshall #define LEX_ILLEGAL LEX_END_OF_FILE+1 /* trailing escape character */ 7131055Sminshall 7231055Sminshall /* the following is part of our character set dependancy... */ 7331055Sminshall #define ESCAPE 0x1b 7431055Sminshall #define TAB 0x09 7531055Sminshall #define NEWLINE 0x0a 7631055Sminshall #define CARRIAGE_RETURN 0x0d 7731055Sminshall 7831055Sminshall typedef struct { 7931055Sminshall int type; /* LEX_* - type of character */ 8031055Sminshall int value; /* character this was */ 8131055Sminshall } lexicon; 8231055Sminshall 8331055Sminshall typedef struct { 8431055Sminshall int length; /* length of character string */ 8531055Sminshall char array[500]; /* character string */ 8631055Sminshall } stringWithLength; 8731055Sminshall 8831055Sminshall #define panic(s) { fprintf(stderr, s); exit(1); } 8931055Sminshall 9031055Sminshall static state firstentry = { 0, TC_NULL, 0, 0 }; 9131055Sminshall static state *headOfQueue = &firstentry; 9231055Sminshall 9331055Sminshall /* the following is a primitive adm3a table, to be used when nothing 9431055Sminshall * else seems to be avaliable. 9531055Sminshall */ 9631055Sminshall 9731055Sminshall #ifdef DEBUG 9831055Sminshall static int debug = 0; /* debug flag (for debuggin tables) */ 9931055Sminshall #endif /* DEBUG */ 10031055Sminshall 10131055Sminshall static int doPaste = 1; /* should we have side effects */ 10231055Sminshall static int picky = 0; /* do we complain of unknown TC's? */ 10331055Sminshall static char usePointer = 0; /* use pointer, or file */ 10431055Sminshall static FILE *ourFile= 0; 10531055Sminshall static char *environPointer = 0; /* if non-zero, point to input 10631055Sminshall * string in core. 10731055Sminshall */ 10831135Sminshall static char **whichkey = 0; 10931135Sminshall static char *keysgeneric[] = { 11031055Sminshall #include "default.map" /* Define the default default */ 11131135Sminshall 11231135Sminshall 0, /* Terminate list of entries */ 11331135Sminshall }; 11431055Sminshall ; 11531055Sminshall 11631055Sminshall static int Empty = 1, /* is the unget lifo empty? */ 11731055Sminshall Full = 0; /* is the unget lifo full? */ 11831100Sminshall static lexicon lifo[200] = { 0 }; /* character stack for parser */ 11931055Sminshall static int rp = 0, /* read pointer into lifo */ 12031055Sminshall wp = 0; /* write pointer into lifo */ 12131055Sminshall 12231055Sminshall static int 12331055Sminshall GetC() 12431055Sminshall { 12531055Sminshall int character; 12631055Sminshall 12731055Sminshall if (usePointer) { 12831135Sminshall if ((*environPointer) == 0) { 12931135Sminshall /* 13031135Sminshall * If we have reached the end of this string, go on to 13131135Sminshall * the next (if there is a next). 13231135Sminshall */ 13331135Sminshall if (whichkey == 0) { 13431135Sminshall static char suffix = 'A'; /* From environment */ 13531135Sminshall char envname[9]; 13631135Sminshall extern char *getenv(); 13731055Sminshall 13831135Sminshall (void) sprintf(envname, "MAP3270%c", suffix++); 13931135Sminshall environPointer = getenv(envname); 14031055Sminshall } else { 14131135Sminshall whichkey++; /* default map */ 14231135Sminshall environPointer = *whichkey; 14331055Sminshall } 14431055Sminshall } 14531135Sminshall if (*environPointer) { 14631135Sminshall character = 0xff&*environPointer++; 14731135Sminshall } else { 14831135Sminshall character = EOF; 14931135Sminshall } 15031055Sminshall } else { 15131055Sminshall character = getc(ourFile); 15231055Sminshall } 15331055Sminshall return(character); 15431055Sminshall } 15531055Sminshall 15631055Sminshall static lexicon 15731055Sminshall Get() 15831055Sminshall { 15931055Sminshall lexicon c; 16031055Sminshall register lexicon *pC = &c; 16131055Sminshall register int character; 16231055Sminshall 16331055Sminshall if (!Empty) { 16431055Sminshall *pC = lifo[rp]; 16531055Sminshall rp++; 16631055Sminshall if (rp == sizeof lifo/sizeof (lexicon)) { 16731055Sminshall rp = 0; 16831055Sminshall } 16931055Sminshall if (rp == wp) { 17031055Sminshall Empty = 1; 17131055Sminshall } 17231055Sminshall Full = 0; 17331055Sminshall } else { 17431055Sminshall character = GetC(); 17531055Sminshall switch (character) { 17631055Sminshall case EOF: 17731055Sminshall pC->type = LEX_END_OF_FILE; 17831055Sminshall break; 17931055Sminshall case '^': 18031055Sminshall character = GetC(); 18131055Sminshall if (!IsPrint(character)) { 18231055Sminshall pC->type = LEX_ILLEGAL; 18331055Sminshall } else { 18431055Sminshall pC->type = LEX_CARETED; 18531055Sminshall if (character == '?') { 18631055Sminshall character |= 0x40; /* rubout */ 18731055Sminshall } else { 18831055Sminshall character &= 0x1f; 18931055Sminshall } 19031055Sminshall } 19131055Sminshall break; 19231055Sminshall case '\\': 19331055Sminshall character = GetC(); 19431055Sminshall if (!IsPrint(character)) { 19531055Sminshall pC->type = LEX_ILLEGAL; 19631055Sminshall } else { 19731055Sminshall pC->type = LEX_ESCAPED; 19831055Sminshall switch (character) { 19931055Sminshall case 'E': case 'e': 20031055Sminshall character = ESCAPE; 20131055Sminshall break; 20231055Sminshall case 't': 20331055Sminshall character = TAB; 20431055Sminshall break; 20531055Sminshall case 'n': 20631055Sminshall character = NEWLINE; 20731055Sminshall break; 20831055Sminshall case 'r': 20931055Sminshall character = CARRIAGE_RETURN; 21031055Sminshall break; 21131055Sminshall default: 21231055Sminshall pC->type = LEX_ILLEGAL; 21331055Sminshall break; 21431055Sminshall } 21531055Sminshall } 21631055Sminshall break; 21731055Sminshall default: 21831055Sminshall if ((IsPrint(character)) || isspace(character)) { 21931055Sminshall pC->type = LEX_CHAR; 22031055Sminshall } else { 22131055Sminshall pC->type = LEX_ILLEGAL; 22231055Sminshall } 22331055Sminshall break; 22431055Sminshall } 22531055Sminshall pC->value = character; 22631055Sminshall } 22731055Sminshall return(*pC); 22831055Sminshall } 22931055Sminshall 23031055Sminshall static void 23131055Sminshall UnGet(c) 23231055Sminshall lexicon c; /* character to unget */ 23331055Sminshall { 23431055Sminshall if (Full) { 23531055Sminshall fprintf(stderr, "attempt to put too many characters in lifo\n"); 23631055Sminshall panic("map3270"); 23731055Sminshall /* NOTREACHED */ 23831055Sminshall } else { 23931055Sminshall lifo[wp] = c; 24031055Sminshall wp++; 24131055Sminshall if (wp == sizeof lifo/sizeof (lexicon)) { 24231055Sminshall wp = 0; 24331055Sminshall } 24431055Sminshall if (wp == rp) { 24531055Sminshall Full = 1; 24631055Sminshall } 24731055Sminshall Empty = 0; 24831055Sminshall } 24931055Sminshall } 25031055Sminshall 25131100Sminshall /* 25231100Sminshall * Construct a control character sequence 25331100Sminshall * for a special character. 25431100Sminshall */ 25531100Sminshall char * 25631100Sminshall uncontrol(c) 25731100Sminshall register int c; 25831100Sminshall { 25931100Sminshall static char buf[3]; 26031100Sminshall 26131100Sminshall if (c == 0x7f) 26231100Sminshall return ("^?"); 26331100Sminshall if (c == '\377') { 26431100Sminshall return "-1"; 26531100Sminshall } 26631100Sminshall if (c >= 0x20) { 26731100Sminshall buf[0] = c; 26831100Sminshall buf[1] = 0; 26931100Sminshall } else { 27031100Sminshall buf[0] = '^'; 27131100Sminshall buf[1] = '@'+c; 27231100Sminshall buf[2] = 0; 27331100Sminshall } 27431100Sminshall return (buf); 27531100Sminshall } 27631100Sminshall 27731055Sminshall /* compare two strings, ignoring case */ 27831055Sminshall 27931055Sminshall ustrcmp(string1, string2) 28031055Sminshall register char *string1; 28131055Sminshall register char *string2; 28231055Sminshall { 28331055Sminshall register int c1, c2; 28431055Sminshall 28531055Sminshall while ((c1 = (unsigned char) *string1++) != 0) { 28631055Sminshall if (isupper(c1)) { 28731055Sminshall c1 = tolower(c1); 28831055Sminshall } 28931055Sminshall if (isupper(c2 = (unsigned char) *string2++)) { 29031055Sminshall c2 = tolower(c2); 29131055Sminshall } 29231055Sminshall if (c1 < c2) { 29331055Sminshall return(-1); 29431055Sminshall } else if (c1 > c2) { 29531055Sminshall return(1); 29631055Sminshall } 29731055Sminshall } 29831055Sminshall if (*string2) { 29931055Sminshall return(-1); 30031055Sminshall } else { 30131055Sminshall return(0); 30231055Sminshall } 30331055Sminshall } 30431055Sminshall 30531055Sminshall 30631055Sminshall static stringWithLength * 30731055Sminshall GetQuotedString() 30831055Sminshall { 30931055Sminshall lexicon lex; 31031055Sminshall static stringWithLength output = { 0 }; /* where return value is held */ 31131055Sminshall char *pointer = output.array; 31231055Sminshall 31331055Sminshall lex = Get(); 31431055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != '\'')) { 31531055Sminshall UnGet(lex); 31631055Sminshall return(0); 31731055Sminshall } 31831055Sminshall while (1) { 31931055Sminshall lex = Get(); 32031055Sminshall if ((lex.type == LEX_CHAR) && (lex.value == '\'')) { 32131055Sminshall break; 32231055Sminshall } 32331055Sminshall if ((lex.type == LEX_CHAR) && !IsPrint(lex.value)) { 32431055Sminshall UnGet(lex); 32531055Sminshall return(0); /* illegal character in quoted string */ 32631055Sminshall } 32731055Sminshall if (pointer >= output.array+sizeof output.array) { 32831055Sminshall return(0); /* too long */ 32931055Sminshall } 33031055Sminshall *pointer++ = lex.value; 33131055Sminshall } 33231055Sminshall output.length = pointer-output.array; 33331055Sminshall return(&output); 33431055Sminshall } 33531055Sminshall 33631055Sminshall #ifdef NOTUSED 33731055Sminshall static stringWithLength * 33831055Sminshall GetCharString() 33931055Sminshall { 34031055Sminshall lexicon lex; 34131055Sminshall static stringWithLength output; 34231055Sminshall char *pointer = output.array; 34331055Sminshall 34431055Sminshall lex = Get(); 34531055Sminshall 34631055Sminshall while ((lex.type == LEX_CHAR) && 34731055Sminshall !isspace(lex.value) && (lex.value != '=')) { 34831055Sminshall *pointer++ = lex.value; 34931055Sminshall lex = Get(); 35031055Sminshall if (pointer >= output.array + sizeof output.array) { 35131055Sminshall return(0); /* too long */ 35231055Sminshall } 35331055Sminshall } 35431055Sminshall UnGet(lex); 35531055Sminshall output.length = pointer-output.array; 35631055Sminshall return(&output); 35731055Sminshall } 35831055Sminshall #endif /* NOTUSED */ 35931055Sminshall 36031055Sminshall static 36131055Sminshall GetCharacter(character) 36231055Sminshall int character; /* desired character */ 36331055Sminshall { 36431055Sminshall lexicon lex; 36531055Sminshall 36631055Sminshall lex = Get(); 36731055Sminshall 36831055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != character)) { 36931055Sminshall UnGet(lex); 37031055Sminshall return(0); 37131055Sminshall } 37231055Sminshall return(1); 37331055Sminshall } 37431055Sminshall 37531055Sminshall #ifdef NOTUSED 37631055Sminshall static 37731055Sminshall GetString(string) 37831055Sminshall char *string; /* string to get */ 37931055Sminshall { 38031055Sminshall lexicon lex; 38131055Sminshall 38231055Sminshall while (*string) { 38331055Sminshall lex = Get(); 38431055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != *string&0xff)) { 38531055Sminshall UnGet(lex); 38631055Sminshall return(0); /* XXX restore to state on entry */ 38731055Sminshall } 38831055Sminshall string++; 38931055Sminshall } 39031055Sminshall return(1); 39131055Sminshall } 39231055Sminshall #endif /* NOTUSED */ 39331055Sminshall 39431055Sminshall 39531055Sminshall static stringWithLength * 39631055Sminshall GetAlphaMericString() 39731055Sminshall { 39831055Sminshall lexicon lex; 39931055Sminshall static stringWithLength output = { 0 }; 40031055Sminshall char *pointer = output.array; 40131055Sminshall # define IsAlnum(c) (isalnum(c) || (c == '_') \ 40231055Sminshall || (c == '-') || (c == '.')) 40331055Sminshall 40431055Sminshall lex = Get(); 40531055Sminshall 40631055Sminshall if ((lex.type != LEX_CHAR) || !IsAlnum(lex.value)) { 40731055Sminshall UnGet(lex); 40831055Sminshall return(0); 40931055Sminshall } 41031055Sminshall 41131055Sminshall while ((lex.type == LEX_CHAR) && IsAlnum(lex.value)) { 41231055Sminshall *pointer++ = lex.value; 41331055Sminshall lex = Get(); 41431055Sminshall } 41531055Sminshall UnGet(lex); 41631055Sminshall *pointer = 0; 41731055Sminshall output.length = pointer-output.array; 41831055Sminshall return(&output); 41931055Sminshall } 42031055Sminshall 42131055Sminshall 42231055Sminshall /* eat up characters until a new line, or end of file. returns terminating 42331055Sminshall character. 42431055Sminshall */ 42531055Sminshall 42631055Sminshall static lexicon 42731055Sminshall EatToNL() 42831055Sminshall { 42931055Sminshall lexicon lex; 43031055Sminshall 43131055Sminshall lex = Get(); 43231055Sminshall 43331055Sminshall while (!((lex.type != LEX_ESCAPED) && (lex.type != LEX_CARETED) && 43431055Sminshall (lex.value == '\n')) && (!(lex.type == LEX_END_OF_FILE))) { 43531055Sminshall lex = Get(); 43631055Sminshall } 43731055Sminshall if (lex.type != LEX_END_OF_FILE) { 43831055Sminshall return(Get()); 43931055Sminshall } else { 44031055Sminshall return(lex); 44131055Sminshall } 44231055Sminshall } 44331055Sminshall 44431055Sminshall 44531055Sminshall static void 44631055Sminshall GetWS() 44731055Sminshall { 44831055Sminshall lexicon lex; 44931055Sminshall 45031055Sminshall lex = Get(); 45131055Sminshall 45231055Sminshall while ((lex.type == LEX_CHAR) && 45331055Sminshall (isspace(lex.value) || (lex.value == '#'))) { 45431055Sminshall if (lex.value == '#') { 45531055Sminshall lex = EatToNL(); 45631055Sminshall } else { 45731055Sminshall lex = Get(); 45831055Sminshall } 45931055Sminshall } 46031055Sminshall UnGet(lex); 46131055Sminshall } 46231055Sminshall 46331055Sminshall static void 46431055Sminshall FreeState(pState) 46531055Sminshall state *pState; 46631055Sminshall { 46731055Sminshall extern void free(); 46831055Sminshall 46931055Sminshall free((char *)pState); 47031055Sminshall } 47131055Sminshall 47231055Sminshall 47331055Sminshall static state * 47431055Sminshall GetState() 47531055Sminshall { 47631055Sminshall state *pState; 47731055Sminshall extern char *malloc(); 47831055Sminshall 47931055Sminshall pState = (state *) malloc(sizeof (state)); 48031055Sminshall 48131055Sminshall pState->result = TC_NULL; 48231055Sminshall pState->next = 0; 48331055Sminshall 48431055Sminshall return(pState); 48531055Sminshall } 48631055Sminshall 48731055Sminshall 48831055Sminshall static state * 48931055Sminshall FindMatchAtThisLevel(pState, character) 49031055Sminshall state *pState; 49131055Sminshall int character; 49231055Sminshall { 49331055Sminshall while (pState) { 49431055Sminshall if (pState->match == character) { 49531055Sminshall return(pState); 49631055Sminshall } 49731055Sminshall pState = pState->next; 49831055Sminshall } 49931055Sminshall return(0); 50031055Sminshall } 50131055Sminshall 50231055Sminshall 50331055Sminshall static state * 50431055Sminshall PasteEntry(head, string, count, identifier) 50531055Sminshall state *head; /* points to who should point here... */ 50631055Sminshall char *string; /* which characters to paste */ 50731055Sminshall int count; /* number of character to do */ 50831055Sminshall char *identifier; /* for error messages */ 50931055Sminshall { 51031055Sminshall state *pState, *other; 51131055Sminshall 51231055Sminshall if (!doPaste) { /* flag to not have any side effects */ 51331055Sminshall return((state *)1); 51431055Sminshall } 51531055Sminshall if (!count) { 51631055Sminshall return(head); /* return pointer to the parent */ 51731055Sminshall } 51831055Sminshall if ((head->result != TC_NULL) && (head->result != TC_GOTO)) { 51931055Sminshall /* this means that a previously defined sequence is an initial 52031055Sminshall * part of this one. 52131055Sminshall */ 52231055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 52331055Sminshall identifier); 52431055Sminshall return(0); 52531055Sminshall } 52631055Sminshall # ifdef DEBUG 52731055Sminshall if (debug) { 52831100Sminshall fprintf(stderr, "%s", uncontrol(*string)); 52931055Sminshall } 53031055Sminshall # endif /* DEBUG */ 53131055Sminshall pState = GetState(); 53231055Sminshall pState->match = *string; 53331055Sminshall if (head->result == TC_NULL) { 53431055Sminshall head->result = TC_GOTO; 53531055Sminshall head->address = pState; 53631055Sminshall other = pState; 53731055Sminshall } else { /* search for same character */ 53831055Sminshall if ((other = FindMatchAtThisLevel(head->address, *string)) != 0) { 53931055Sminshall FreeState(pState); 54031055Sminshall } else { 54131055Sminshall pState->next = head->address; 54231055Sminshall head->address = pState; 54331055Sminshall other = pState; 54431055Sminshall } 54531055Sminshall } 54631055Sminshall return(PasteEntry(other, string+1, count-1, identifier)); 54731055Sminshall } 54831055Sminshall 54931055Sminshall static 55031055Sminshall GetInput(tc, identifier) 55131055Sminshall int tc; 55231055Sminshall char *identifier; /* entry being parsed (for error messages) */ 55331055Sminshall { 55431055Sminshall stringWithLength *outputString; 55531055Sminshall state *head; 55631055Sminshall state fakeQueue; 55731055Sminshall 55831055Sminshall if (doPaste) { 55931055Sminshall head = headOfQueue; /* always points to level above this one */ 56031055Sminshall } else { 56131055Sminshall head = &fakeQueue; /* don't have any side effects... */ 56231055Sminshall } 56331055Sminshall 56431055Sminshall if ((outputString = GetQuotedString()) == 0) { 56531055Sminshall return(0); 56631055Sminshall } else if (IsPrint(outputString->array[0])) { 56731055Sminshall fprintf(stderr, 56831055Sminshall "first character of sequence for %s is not a control type character\n", 56931055Sminshall identifier); 57031055Sminshall return(0); 57131055Sminshall } else { 57231055Sminshall if ((head = PasteEntry(head, outputString->array, 57331055Sminshall outputString->length, identifier)) == 0) { 57431055Sminshall return(0); 57531055Sminshall } 57631055Sminshall GetWS(); 57731055Sminshall while ((outputString = GetQuotedString()) != 0) { 57831055Sminshall if ((head = PasteEntry(head, outputString->array, 57931055Sminshall outputString->length, identifier)) == 0) { 58031055Sminshall return(0); 58131055Sminshall } 58231055Sminshall GetWS(); 58331055Sminshall } 58431055Sminshall } 58531055Sminshall if (!doPaste) { 58631055Sminshall return(1); 58731055Sminshall } 58831055Sminshall if ((head->result != TC_NULL) && (head->result != tc)) { 58931055Sminshall /* this means that this sequence is an initial part 59031055Sminshall * of a previously defined one. 59131055Sminshall */ 59231055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 59331055Sminshall identifier); 59431055Sminshall return(0); 59531055Sminshall } else { 59631055Sminshall head->result = tc; 59731055Sminshall return(1); /* done */ 59831055Sminshall } 59931055Sminshall } 60031055Sminshall 60131055Sminshall static 60231055Sminshall GetTc(string) 60331055Sminshall char *string; 60431055Sminshall { 60531055Sminshall register TC_Ascii_t *Tc; 60631055Sminshall 60731055Sminshall for (Tc = TC_Ascii; 60831055Sminshall Tc < TC_Ascii+sizeof TC_Ascii/sizeof (TC_Ascii_t); Tc++) { 60931055Sminshall if (!ustrcmp(string, Tc->tc_name)) { 61031055Sminshall # ifdef DEBUG 61131055Sminshall if (debug) { 61231055Sminshall fprintf(stderr, "%s = ", Tc->tc_name); 61331055Sminshall } 61431055Sminshall # endif /* DEBUG */ 61531055Sminshall return(Tc->tc_value&0xff); 61631055Sminshall } 61731055Sminshall } 61831055Sminshall return(0); 61931055Sminshall } 62031055Sminshall static 62131055Sminshall GetDefinition() 62231055Sminshall { 62331055Sminshall stringWithLength *string; 62431055Sminshall int Tc; 62531055Sminshall 62631055Sminshall GetWS(); 62731055Sminshall if ((string = GetAlphaMericString()) == 0) { 62831055Sminshall return(0); 62931055Sminshall } 63031055Sminshall string->array[string->length] = 0; 63131055Sminshall if (doPaste) { 63231055Sminshall if ((Tc = GetTc(string->array)) == 0) { 63331055Sminshall if (picky) { 63431055Sminshall fprintf(stderr, "%s: unknown 3270 key identifier\n", 63531055Sminshall string->array); 63631055Sminshall } 63731055Sminshall Tc = TC_NULL; 63831055Sminshall } else if (Tc < TC_LOWEST_USER) { 63931055Sminshall fprintf(stderr, "%s is not allowed to be specified by a user.\n", 64031055Sminshall string->array); 64131055Sminshall return(0); 64231055Sminshall } 64331055Sminshall } else { 64431055Sminshall Tc = TC_LOWEST_USER; 64531055Sminshall } 64631055Sminshall GetWS(); 64731055Sminshall if (!GetCharacter('=')) { 64831055Sminshall fprintf(stderr, 64931055Sminshall "Required equal sign after 3270 key identifier %s missing\n", 65031055Sminshall string->array); 65131055Sminshall return(0); 65231055Sminshall } 65331055Sminshall GetWS(); 65431055Sminshall if (!GetInput(Tc, string->array)) { 65531055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 65631055Sminshall string->array); 65731055Sminshall return(0); 65831055Sminshall } else { 65931055Sminshall GetWS(); 66031055Sminshall while (GetCharacter('|')) { 66131055Sminshall # ifdef DEBUG 66231055Sminshall if (debug) { 66331055Sminshall fprintf(stderr, " or "); 66431055Sminshall } 66531055Sminshall # endif /* DEBUG */ 66631055Sminshall GetWS(); 66731055Sminshall if (!GetInput(Tc, string->array)) { 66831055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 66931055Sminshall string->array); 67031055Sminshall return(0); 67131055Sminshall } 67231055Sminshall GetWS(); 67331055Sminshall } 67431055Sminshall } 67531055Sminshall GetWS(); 67631055Sminshall if (!GetCharacter(';')) { 67731055Sminshall fprintf(stderr, "Missing semi-colon for 3270 key %s\n", string->array); 67831055Sminshall return(0); 67931055Sminshall } 68031055Sminshall # ifdef DEBUG 68131055Sminshall if (debug) { 68231055Sminshall fprintf(stderr, ";\n"); 68331055Sminshall } 68431055Sminshall # endif /* DEBUG */ 68531055Sminshall return(1); 68631055Sminshall } 68731055Sminshall 68831055Sminshall 68931055Sminshall static 69031055Sminshall GetDefinitions() 69131055Sminshall { 69231055Sminshall if (!GetDefinition()) { 69331055Sminshall return(0); 69431055Sminshall } else { 69531055Sminshall while (GetDefinition()) { 69631055Sminshall ; 69731055Sminshall } 69831055Sminshall } 69931055Sminshall return(1); 70031055Sminshall } 70131055Sminshall 70231055Sminshall static 70331055Sminshall GetBegin() 70431055Sminshall { 70531055Sminshall GetWS(); 70631055Sminshall if (!GetCharacter('{')) { 70731055Sminshall return(0); 70831055Sminshall } 70931055Sminshall return(1); 71031055Sminshall } 71131055Sminshall 71231055Sminshall static 71331055Sminshall GetEnd() 71431055Sminshall { 71531055Sminshall GetWS(); 71631055Sminshall if (!GetCharacter('}')) { 71731055Sminshall return(0); 71831055Sminshall } 71931055Sminshall return(1); 72031055Sminshall } 72131055Sminshall 72231055Sminshall static 72331055Sminshall GetName() 72431055Sminshall { 72531055Sminshall if (!GetAlphaMericString()) { 72631055Sminshall return(0); 72731055Sminshall } 72831055Sminshall GetWS(); 72931055Sminshall while (GetAlphaMericString()) { 73031055Sminshall GetWS(); 73131055Sminshall } 73231055Sminshall return(1); 73331055Sminshall } 73431055Sminshall 73531055Sminshall static 73631055Sminshall GetNames() 73731055Sminshall { 73831055Sminshall GetWS(); 73931055Sminshall if (!GetName()) { 74031055Sminshall return(0); 74131055Sminshall } else { 74231055Sminshall GetWS(); 74331055Sminshall while (GetCharacter('|')) { 74431055Sminshall GetWS(); 74531055Sminshall if (!GetName()) { 74631055Sminshall return(0); 74731055Sminshall } 74831055Sminshall } 74931055Sminshall } 75031055Sminshall return(1); 75131055Sminshall } 75231055Sminshall 75331055Sminshall static 75431055Sminshall GetEntry0() 75531055Sminshall { 75631055Sminshall if (!GetBegin()) { 75731055Sminshall fprintf(stderr, "no '{'\n"); 75831055Sminshall return(0); 75931055Sminshall } else if (!GetDefinitions()) { 76031055Sminshall fprintf(stderr, "unable to parse the definitions\n"); 76131055Sminshall return(0); 76231055Sminshall } else if (!GetEnd()) { 76331055Sminshall fprintf(stderr, "No '}' or scanning stopped early due to error.\n"); 76431055Sminshall return(0); 76531055Sminshall } else { 76631055Sminshall /* done */ 76731055Sminshall return(1); 76831055Sminshall } 76931055Sminshall } 77031055Sminshall 77131055Sminshall 77231055Sminshall static 77331055Sminshall GetEntry() 77431055Sminshall { 77531055Sminshall if (!GetNames()) { 77631055Sminshall fprintf(stderr, "Invalid name field in entry.\n"); 77731055Sminshall return(0); 77831055Sminshall } else { 77931055Sminshall return(GetEntry0()); 78031055Sminshall } 78131055Sminshall } 78231055Sminshall 78331055Sminshall /* position ourselves within a given filename to the entry for the current 78431055Sminshall * KEYBD (or TERM) variable 78531055Sminshall */ 78631055Sminshall 78731055Sminshall Position(filename, keybdPointer) 78831055Sminshall char *filename; 78931055Sminshall char *keybdPointer; 79031055Sminshall { 79131055Sminshall lexicon lex; 79231055Sminshall stringWithLength *name = 0; 79331055Sminshall stringWithLength *oldName; 79431055Sminshall # define Return(x) {doPaste = 1; return(x);} 79531055Sminshall 79631055Sminshall doPaste = 0; 79731055Sminshall 79831055Sminshall if ((ourFile = fopen(filename, "r")) == NULL) { 79931100Sminshall # if !defined(MSDOS) 80031055Sminshall fprintf(stderr, "Unable to open file %s\n", filename); 80131100Sminshall # endif /* !defined(MSDOS) */ 80231055Sminshall Return(0); 80331055Sminshall } 80431055Sminshall lex = Get(); 80531055Sminshall while (lex.type != LEX_END_OF_FILE) { 80631055Sminshall UnGet(lex); 80731055Sminshall /* now, find an entry that is our type. */ 80831055Sminshall GetWS(); 80931055Sminshall oldName = name; 81031055Sminshall if ((name = GetAlphaMericString()) != 0) { 81131055Sminshall if (!ustrcmp(name->array, keybdPointer)) { 81231055Sminshall /* need to make sure there is a name here... */ 81331055Sminshall lex.type = LEX_CHAR; 81431055Sminshall lex.value = 'a'; 81531055Sminshall UnGet(lex); 81631055Sminshall Return(1); 81731055Sminshall } 81831055Sminshall } else if (GetCharacter('|')) { 81931055Sminshall ; /* more names coming */ 82031055Sminshall } else { 82131055Sminshall lex = Get(); 82231055Sminshall UnGet(lex); 82331055Sminshall if (lex.type != LEX_END_OF_FILE) { 82431055Sminshall if (!GetEntry0()) { /* start of an entry */ 82531055Sminshall fprintf(stderr, 82631055Sminshall "error was in entry for %s in file %s\n", 82731055Sminshall (oldName)? oldName->array:"(unknown)", filename); 82831055Sminshall Return(0); 82931055Sminshall } 83031055Sminshall } 83131055Sminshall } 83231055Sminshall lex = Get(); 83331055Sminshall } 83431100Sminshall #if !defined(MSDOS) 83531055Sminshall fprintf(stderr, "Unable to find entry for %s in file %s\n", keybdPointer, 83631055Sminshall filename); 83731100Sminshall #endif /* !defined(MSDOS) */ 83831055Sminshall Return(0); 83931055Sminshall } 84031055Sminshall 84131055Sminshall char * 84231055Sminshall strsave(string) 84331055Sminshall char *string; 84431055Sminshall { 84531055Sminshall char *p; 84631055Sminshall extern char *malloc(); 84731055Sminshall 84831055Sminshall p = malloc(strlen(string)+1); 84931055Sminshall if (p != 0) { 85031055Sminshall strcpy(p, string); 85131055Sminshall } 85231055Sminshall return(p); 85331055Sminshall } 85431055Sminshall 85531055Sminshall 85631055Sminshall /* 85731055Sminshall * InitControl - our interface to the outside. What we should 85831055Sminshall * do is figure out keyboard (or terminal) type, set up file pointer 85931055Sminshall * (or string pointer), etc. 86031055Sminshall */ 86131055Sminshall 86231055Sminshall state * 86331055Sminshall InitControl(keybdPointer, pickyarg) 86431055Sminshall char *keybdPointer; 86531055Sminshall int pickyarg; /* Should we be picky? */ 86631055Sminshall { 86731055Sminshall extern char *getenv(); 86831055Sminshall int GotIt; 86931055Sminshall 87031055Sminshall picky = pickyarg; 87131055Sminshall 87231055Sminshall if (keybdPointer == 0) { 87331055Sminshall keybdPointer = getenv("KEYBD"); 87431055Sminshall } 87531055Sminshall if (keybdPointer == 0) { 87631055Sminshall keybdPointer = getenv("TERM"); 87731055Sminshall } 87831055Sminshall 87931055Sminshall /* 88031055Sminshall * Some environments have getenv() return 88131055Sminshall * out of a static area. So, save the keyboard name. 88231055Sminshall */ 88331055Sminshall if (keybdPointer) { 88431055Sminshall keybdPointer = strsave(keybdPointer); 88531055Sminshall } 88631055Sminshall environPointer = getenv("MAP3270"); 88731055Sminshall if (environPointer 88831055Sminshall && (environPointer[0] != '/') 88931100Sminshall #if defined(MSDOS) 89031055Sminshall && (environPointer[0] != '\\') 89131100Sminshall #endif /* defined(MSDOS) */ 89231055Sminshall && (strncmp(keybdPointer, environPointer, 89331055Sminshall strlen(keybdPointer) != 0) 89431055Sminshall || (environPointer[strlen(keybdPointer)] != '{'))) /* } */ 89531055Sminshall { 89631055Sminshall environPointer = 0; 89731055Sminshall } 89831055Sminshall 89931055Sminshall if ((!environPointer) 90031100Sminshall #if defined(MSDOS) 90131055Sminshall || (*environPointer == '\\') 90231100Sminshall #endif /* defined(MSDOS) */ 90331055Sminshall || (*environPointer == '/')) { 90431055Sminshall usePointer = 0; 90531055Sminshall GotIt = 0; 90631055Sminshall if (!keybdPointer) { 90731100Sminshall #if !defined(MSDOS) 90831055Sminshall fprintf(stderr, "%s%s%s%s", 90931055Sminshall "Neither the KEYBD environment variable nor the TERM ", 91031055Sminshall "environment variable\n(one of which is needed to determine ", 91131055Sminshall "the type of keyboard you are using)\n", 91231055Sminshall "is set. To set it, say 'setenv KEYBD <type>'\n"); 91331100Sminshall #endif /* !defined(MSDOS) */ 91431055Sminshall } else { 91531055Sminshall if (environPointer) { 91631055Sminshall GotIt = Position(environPointer, keybdPointer); 91731055Sminshall } 91831055Sminshall if (!GotIt) { 91931055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 92031055Sminshall } 92131055Sminshall } 92231055Sminshall if (!GotIt) { 92331055Sminshall if (environPointer) { 92431055Sminshall GotIt = Position(environPointer, "unknown"); 92531055Sminshall } 92631055Sminshall if (!GotIt) { 92731055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 92831055Sminshall } 92931055Sminshall } 93031055Sminshall if (!GotIt) { 93131100Sminshall #if !defined(MSDOS) 93231055Sminshall fprintf(stderr, "Using default key mappings.\n"); 93331100Sminshall #endif /* !defined(MSDOS) */ 93431055Sminshall usePointer = 1; /* flag use of non-file */ 93531135Sminshall whichkey = keysgeneric; 93631135Sminshall environPointer = *whichkey; /* use default table */ 93731055Sminshall } 93831055Sminshall } else { 93931055Sminshall usePointer = 1; 94031055Sminshall } 94131055Sminshall (void) GetEntry(); 94231055Sminshall return(firstentry.address); 94331055Sminshall } 944