1*48755Sbostic /*- 2*48755Sbostic * Copyright (c) 1988 The Regents of the University of California. 333817Sbostic * All rights reserved. 431055Sminshall * 5*48755Sbostic * %sccs.include.redist.c% 631055Sminshall */ 731055Sminshall 833817Sbostic #ifndef lint 9*48755Sbostic static char sccsid[] = "@(#)map3270.c 4.2 (Berkeley) 04/26/91"; 1033817Sbostic #endif /* not lint */ 1131055Sminshall 1231055Sminshall /* This program reads a description file, somewhat like /etc/termcap, 1331055Sminshall that describes the mapping between the current terminal's keyboard and 1431055Sminshall a 3270 keyboard. 1531055Sminshall */ 1631055Sminshall #ifdef DOCUMENTATION_ONLY 1731055Sminshall /* here is a sample (very small) entry... 1831055Sminshall 1931055Sminshall # this table is sensitive to position on a line. In particular, 2031055Sminshall # a terminal definition for a terminal is terminated whenever a 2131055Sminshall # (non-comment) line beginning in column one is found. 2231055Sminshall # 2331055Sminshall # this is an entry to map tvi924 to 3270 keys... 2431055Sminshall v8|tvi924|924|televideo model 924 { 2531055Sminshall pfk1 = '\E1'; 2631055Sminshall pfk2 = '\E2'; 2731055Sminshall clear = '^z'; # clear the screen 2831055Sminshall } 2931055Sminshall */ 3031055Sminshall #endif /* DOCUMENTATION_ONLY */ 3131055Sminshall 3231055Sminshall #include <stdio.h> 3331055Sminshall #include <ctype.h> 3431100Sminshall #if defined(unix) 3531055Sminshall #include <strings.h> 3631100Sminshall #else /* defined(unix) */ 3731100Sminshall #include <string.h> 3831100Sminshall #endif /* defined(unix) */ 3931055Sminshall 4031055Sminshall #define IsPrint(c) ((isprint(c) && !isspace(c)) || ((c) == ' ')) 4131055Sminshall 4231055Sminshall #include "state.h" 4335419Sminshall #include "map3270.h" 4431055Sminshall 4531176Sminshall #include "../general/globals.h" 4631055Sminshall 4731055Sminshall /* this is the list of types returned by the lex processor */ 4831245Sminshall #define LEX_CHAR 400 /* plain unadorned character */ 4931055Sminshall #define LEX_ESCAPED LEX_CHAR+1 /* escaped with \ */ 5031055Sminshall #define LEX_CARETED LEX_ESCAPED+1 /* escaped with ^ */ 5131055Sminshall #define LEX_END_OF_FILE LEX_CARETED+1 /* end of file encountered */ 5231055Sminshall #define LEX_ILLEGAL LEX_END_OF_FILE+1 /* trailing escape character */ 5331055Sminshall 5431055Sminshall /* the following is part of our character set dependancy... */ 5531055Sminshall #define ESCAPE 0x1b 5631055Sminshall #define TAB 0x09 5731055Sminshall #define NEWLINE 0x0a 5831055Sminshall #define CARRIAGE_RETURN 0x0d 5931055Sminshall 6031055Sminshall typedef struct { 6131055Sminshall int type; /* LEX_* - type of character */ 6231055Sminshall int value; /* character this was */ 6331055Sminshall } lexicon; 6431055Sminshall 6531055Sminshall typedef struct { 6631055Sminshall int length; /* length of character string */ 6731055Sminshall char array[500]; /* character string */ 6831055Sminshall } stringWithLength; 6931055Sminshall 7031055Sminshall #define panic(s) { fprintf(stderr, s); exit(1); } 7131055Sminshall 7231245Sminshall static state firstentry = { 0, STATE_NULL, 0, 0 }; 7331055Sminshall static state *headOfQueue = &firstentry; 7431055Sminshall 7531055Sminshall /* the following is a primitive adm3a table, to be used when nothing 7631055Sminshall * else seems to be avaliable. 7731055Sminshall */ 7831055Sminshall 7931055Sminshall #ifdef DEBUG 8031055Sminshall static int debug = 0; /* debug flag (for debuggin tables) */ 8131055Sminshall #endif /* DEBUG */ 8231055Sminshall 8331245Sminshall static int (*GetTc)(); 8431245Sminshall static int doPaste = 1; /* should we have side effects */ 8531245Sminshall static int picky = 0; /* do we complain of unknown functions? */ 8631245Sminshall static char usePointer = 0; /* use pointer, or file */ 8731055Sminshall static FILE *ourFile= 0; 8831245Sminshall static char *environPointer = 0;/* if non-zero, point to input 8931245Sminshall * string in core. 9031245Sminshall */ 9131135Sminshall static char **whichkey = 0; 9231135Sminshall static char *keysgeneric[] = { 9331055Sminshall #include "default.map" /* Define the default default */ 9431135Sminshall 9531135Sminshall 0, /* Terminate list of entries */ 9631135Sminshall }; 9731055Sminshall ; 9831055Sminshall 9931055Sminshall static int Empty = 1, /* is the unget lifo empty? */ 10031055Sminshall Full = 0; /* is the unget lifo full? */ 10131100Sminshall static lexicon lifo[200] = { 0 }; /* character stack for parser */ 10231055Sminshall static int rp = 0, /* read pointer into lifo */ 10331055Sminshall wp = 0; /* write pointer into lifo */ 10431055Sminshall 10531055Sminshall static int 10631055Sminshall GetC() 10731055Sminshall { 10831055Sminshall int character; 10931055Sminshall 11031055Sminshall if (usePointer) { 11131135Sminshall if ((*environPointer) == 0) { 11231135Sminshall /* 11331135Sminshall * If we have reached the end of this string, go on to 11431135Sminshall * the next (if there is a next). 11531135Sminshall */ 11631135Sminshall if (whichkey == 0) { 11731135Sminshall static char suffix = 'A'; /* From environment */ 11831135Sminshall char envname[9]; 11931135Sminshall extern char *getenv(); 12031055Sminshall 12131135Sminshall (void) sprintf(envname, "MAP3270%c", suffix++); 12231135Sminshall environPointer = getenv(envname); 12331055Sminshall } else { 12431135Sminshall whichkey++; /* default map */ 12531135Sminshall environPointer = *whichkey; 12631055Sminshall } 12731055Sminshall } 12831135Sminshall if (*environPointer) { 12931135Sminshall character = 0xff&*environPointer++; 13031135Sminshall } else { 13131135Sminshall character = EOF; 13231135Sminshall } 13331055Sminshall } else { 13431055Sminshall character = getc(ourFile); 13531055Sminshall } 13631055Sminshall return(character); 13731055Sminshall } 13831055Sminshall 13931055Sminshall static lexicon 14031055Sminshall Get() 14131055Sminshall { 14231055Sminshall lexicon c; 14331055Sminshall register lexicon *pC = &c; 14431055Sminshall register int character; 14531055Sminshall 14631055Sminshall if (!Empty) { 14731055Sminshall *pC = lifo[rp]; 14831055Sminshall rp++; 14931055Sminshall if (rp == sizeof lifo/sizeof (lexicon)) { 15031055Sminshall rp = 0; 15131055Sminshall } 15231055Sminshall if (rp == wp) { 15331055Sminshall Empty = 1; 15431055Sminshall } 15531055Sminshall Full = 0; 15631055Sminshall } else { 15731055Sminshall character = GetC(); 15831055Sminshall switch (character) { 15931055Sminshall case EOF: 16031055Sminshall pC->type = LEX_END_OF_FILE; 16131055Sminshall break; 16231055Sminshall case '^': 16331055Sminshall character = GetC(); 16431055Sminshall if (!IsPrint(character)) { 16531055Sminshall pC->type = LEX_ILLEGAL; 16631055Sminshall } else { 16731055Sminshall pC->type = LEX_CARETED; 16831055Sminshall if (character == '?') { 16931055Sminshall character |= 0x40; /* rubout */ 17031055Sminshall } else { 17131055Sminshall character &= 0x1f; 17231055Sminshall } 17331055Sminshall } 17431055Sminshall break; 17531055Sminshall case '\\': 17631055Sminshall character = GetC(); 17731055Sminshall if (!IsPrint(character)) { 17831055Sminshall pC->type = LEX_ILLEGAL; 17931055Sminshall } else { 18031055Sminshall pC->type = LEX_ESCAPED; 18131055Sminshall switch (character) { 18231055Sminshall case 'E': case 'e': 18331055Sminshall character = ESCAPE; 18431055Sminshall break; 18531055Sminshall case 't': 18631055Sminshall character = TAB; 18731055Sminshall break; 18831055Sminshall case 'n': 18931055Sminshall character = NEWLINE; 19031055Sminshall break; 19131055Sminshall case 'r': 19231055Sminshall character = CARRIAGE_RETURN; 19331055Sminshall break; 19431055Sminshall default: 19531055Sminshall pC->type = LEX_ILLEGAL; 19631055Sminshall break; 19731055Sminshall } 19831055Sminshall } 19931055Sminshall break; 20031055Sminshall default: 20131055Sminshall if ((IsPrint(character)) || isspace(character)) { 20231055Sminshall pC->type = LEX_CHAR; 20331055Sminshall } else { 20431055Sminshall pC->type = LEX_ILLEGAL; 20531055Sminshall } 20631055Sminshall break; 20731055Sminshall } 20831055Sminshall pC->value = character; 20931055Sminshall } 21031055Sminshall return(*pC); 21131055Sminshall } 21231055Sminshall 21331055Sminshall static void 21431055Sminshall UnGet(c) 21531055Sminshall lexicon c; /* character to unget */ 21631055Sminshall { 21731055Sminshall if (Full) { 21831055Sminshall fprintf(stderr, "attempt to put too many characters in lifo\n"); 21931055Sminshall panic("map3270"); 22031055Sminshall /* NOTREACHED */ 22131055Sminshall } else { 22231055Sminshall lifo[wp] = c; 22331055Sminshall wp++; 22431055Sminshall if (wp == sizeof lifo/sizeof (lexicon)) { 22531055Sminshall wp = 0; 22631055Sminshall } 22731055Sminshall if (wp == rp) { 22831055Sminshall Full = 1; 22931055Sminshall } 23031055Sminshall Empty = 0; 23131055Sminshall } 23231055Sminshall } 23331055Sminshall 23431100Sminshall /* 23531100Sminshall * Construct a control character sequence 23631100Sminshall * for a special character. 23731100Sminshall */ 23831100Sminshall char * 23931100Sminshall uncontrol(c) 24031100Sminshall register int c; 24131100Sminshall { 24231100Sminshall static char buf[3]; 24331100Sminshall 24431100Sminshall if (c == 0x7f) 24531100Sminshall return ("^?"); 24631100Sminshall if (c == '\377') { 24731100Sminshall return "-1"; 24831100Sminshall } 24931100Sminshall if (c >= 0x20) { 25031100Sminshall buf[0] = c; 25131100Sminshall buf[1] = 0; 25231100Sminshall } else { 25331100Sminshall buf[0] = '^'; 25431100Sminshall buf[1] = '@'+c; 25531100Sminshall buf[2] = 0; 25631100Sminshall } 25731100Sminshall return (buf); 25831100Sminshall } 25931100Sminshall 26031055Sminshall /* compare two strings, ignoring case */ 26131055Sminshall 26231055Sminshall ustrcmp(string1, string2) 26331055Sminshall register char *string1; 26431055Sminshall register char *string2; 26531055Sminshall { 26631055Sminshall register int c1, c2; 26731055Sminshall 26831055Sminshall while ((c1 = (unsigned char) *string1++) != 0) { 26931055Sminshall if (isupper(c1)) { 27031055Sminshall c1 = tolower(c1); 27131055Sminshall } 27231055Sminshall if (isupper(c2 = (unsigned char) *string2++)) { 27331055Sminshall c2 = tolower(c2); 27431055Sminshall } 27531055Sminshall if (c1 < c2) { 27631055Sminshall return(-1); 27731055Sminshall } else if (c1 > c2) { 27831055Sminshall return(1); 27931055Sminshall } 28031055Sminshall } 28131055Sminshall if (*string2) { 28231055Sminshall return(-1); 28331055Sminshall } else { 28431055Sminshall return(0); 28531055Sminshall } 28631055Sminshall } 28731055Sminshall 28831055Sminshall 28931055Sminshall static stringWithLength * 29031055Sminshall GetQuotedString() 29131055Sminshall { 29231055Sminshall lexicon lex; 29331055Sminshall static stringWithLength output = { 0 }; /* where return value is held */ 29431055Sminshall char *pointer = output.array; 29531055Sminshall 29631055Sminshall lex = Get(); 29731055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != '\'')) { 29831055Sminshall UnGet(lex); 29931055Sminshall return(0); 30031055Sminshall } 30131055Sminshall while (1) { 30231055Sminshall lex = Get(); 30331055Sminshall if ((lex.type == LEX_CHAR) && (lex.value == '\'')) { 30431055Sminshall break; 30531055Sminshall } 30631055Sminshall if ((lex.type == LEX_CHAR) && !IsPrint(lex.value)) { 30731055Sminshall UnGet(lex); 30831055Sminshall return(0); /* illegal character in quoted string */ 30931055Sminshall } 31031055Sminshall if (pointer >= output.array+sizeof output.array) { 31131055Sminshall return(0); /* too long */ 31231055Sminshall } 31331055Sminshall *pointer++ = lex.value; 31431055Sminshall } 31531055Sminshall output.length = pointer-output.array; 31631055Sminshall return(&output); 31731055Sminshall } 31831055Sminshall 31931055Sminshall #ifdef NOTUSED 32031055Sminshall static stringWithLength * 32131055Sminshall GetCharString() 32231055Sminshall { 32331055Sminshall lexicon lex; 32431055Sminshall static stringWithLength output; 32531055Sminshall char *pointer = output.array; 32631055Sminshall 32731055Sminshall lex = Get(); 32831055Sminshall 32931055Sminshall while ((lex.type == LEX_CHAR) && 33031055Sminshall !isspace(lex.value) && (lex.value != '=')) { 33131055Sminshall *pointer++ = lex.value; 33231055Sminshall lex = Get(); 33331055Sminshall if (pointer >= output.array + sizeof output.array) { 33431055Sminshall return(0); /* too long */ 33531055Sminshall } 33631055Sminshall } 33731055Sminshall UnGet(lex); 33831055Sminshall output.length = pointer-output.array; 33931055Sminshall return(&output); 34031055Sminshall } 34131055Sminshall #endif /* NOTUSED */ 34231055Sminshall 34331055Sminshall static 34431055Sminshall GetCharacter(character) 34531055Sminshall int character; /* desired character */ 34631055Sminshall { 34731055Sminshall lexicon lex; 34831055Sminshall 34931055Sminshall lex = Get(); 35031055Sminshall 35131055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != character)) { 35231055Sminshall UnGet(lex); 35331055Sminshall return(0); 35431055Sminshall } 35531055Sminshall return(1); 35631055Sminshall } 35731055Sminshall 35831055Sminshall #ifdef NOTUSED 35931055Sminshall static 36031055Sminshall GetString(string) 36131055Sminshall char *string; /* string to get */ 36231055Sminshall { 36331055Sminshall lexicon lex; 36431055Sminshall 36531055Sminshall while (*string) { 36631055Sminshall lex = Get(); 36731055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != *string&0xff)) { 36831055Sminshall UnGet(lex); 36931055Sminshall return(0); /* XXX restore to state on entry */ 37031055Sminshall } 37131055Sminshall string++; 37231055Sminshall } 37331055Sminshall return(1); 37431055Sminshall } 37531055Sminshall #endif /* NOTUSED */ 37631055Sminshall 37731055Sminshall 37831055Sminshall static stringWithLength * 37931055Sminshall GetAlphaMericString() 38031055Sminshall { 38131055Sminshall lexicon lex; 38231055Sminshall static stringWithLength output = { 0 }; 38331055Sminshall char *pointer = output.array; 38431055Sminshall # define IsAlnum(c) (isalnum(c) || (c == '_') \ 38531055Sminshall || (c == '-') || (c == '.')) 38631055Sminshall 38731055Sminshall lex = Get(); 38831055Sminshall 38931055Sminshall if ((lex.type != LEX_CHAR) || !IsAlnum(lex.value)) { 39031055Sminshall UnGet(lex); 39131055Sminshall return(0); 39231055Sminshall } 39331055Sminshall 39431055Sminshall while ((lex.type == LEX_CHAR) && IsAlnum(lex.value)) { 39531055Sminshall *pointer++ = lex.value; 39631055Sminshall lex = Get(); 39731055Sminshall } 39831055Sminshall UnGet(lex); 39931055Sminshall *pointer = 0; 40031055Sminshall output.length = pointer-output.array; 40131055Sminshall return(&output); 40231055Sminshall } 40331055Sminshall 40431055Sminshall 40531055Sminshall /* eat up characters until a new line, or end of file. returns terminating 40631055Sminshall character. 40731055Sminshall */ 40831055Sminshall 40931055Sminshall static lexicon 41031055Sminshall EatToNL() 41131055Sminshall { 41231055Sminshall lexicon lex; 41331055Sminshall 41431055Sminshall lex = Get(); 41531055Sminshall 41631055Sminshall while (!((lex.type != LEX_ESCAPED) && (lex.type != LEX_CARETED) && 41731055Sminshall (lex.value == '\n')) && (!(lex.type == LEX_END_OF_FILE))) { 41831055Sminshall lex = Get(); 41931055Sminshall } 42031055Sminshall if (lex.type != LEX_END_OF_FILE) { 42131055Sminshall return(Get()); 42231055Sminshall } else { 42331055Sminshall return(lex); 42431055Sminshall } 42531055Sminshall } 42631055Sminshall 42731055Sminshall 42831055Sminshall static void 42931055Sminshall GetWS() 43031055Sminshall { 43131055Sminshall lexicon lex; 43231055Sminshall 43331055Sminshall lex = Get(); 43431055Sminshall 43531055Sminshall while ((lex.type == LEX_CHAR) && 43631055Sminshall (isspace(lex.value) || (lex.value == '#'))) { 43731055Sminshall if (lex.value == '#') { 43831055Sminshall lex = EatToNL(); 43931055Sminshall } else { 44031055Sminshall lex = Get(); 44131055Sminshall } 44231055Sminshall } 44331055Sminshall UnGet(lex); 44431055Sminshall } 44531055Sminshall 44631055Sminshall static void 44731055Sminshall FreeState(pState) 44831055Sminshall state *pState; 44931055Sminshall { 45035419Sminshall extern int free(); 45131055Sminshall 45231055Sminshall free((char *)pState); 45331055Sminshall } 45431055Sminshall 45531055Sminshall 45631055Sminshall static state * 45731055Sminshall GetState() 45831055Sminshall { 45931055Sminshall state *pState; 46031055Sminshall extern char *malloc(); 46131055Sminshall 46231055Sminshall pState = (state *) malloc(sizeof (state)); 46331055Sminshall 46431245Sminshall pState->result = STATE_NULL; 46531055Sminshall pState->next = 0; 46631055Sminshall 46731055Sminshall return(pState); 46831055Sminshall } 46931055Sminshall 47031055Sminshall 47131055Sminshall static state * 47231055Sminshall FindMatchAtThisLevel(pState, character) 47331055Sminshall state *pState; 47431055Sminshall int character; 47531055Sminshall { 47631055Sminshall while (pState) { 47731055Sminshall if (pState->match == character) { 47831055Sminshall return(pState); 47931055Sminshall } 48031055Sminshall pState = pState->next; 48131055Sminshall } 48231055Sminshall return(0); 48331055Sminshall } 48431055Sminshall 48531055Sminshall 48631055Sminshall static state * 48731055Sminshall PasteEntry(head, string, count, identifier) 48831055Sminshall state *head; /* points to who should point here... */ 48931055Sminshall char *string; /* which characters to paste */ 49031055Sminshall int count; /* number of character to do */ 49131055Sminshall char *identifier; /* for error messages */ 49231055Sminshall { 49331055Sminshall state *pState, *other; 49431055Sminshall 49531055Sminshall if (!doPaste) { /* flag to not have any side effects */ 49631055Sminshall return((state *)1); 49731055Sminshall } 49831055Sminshall if (!count) { 49931055Sminshall return(head); /* return pointer to the parent */ 50031055Sminshall } 50131245Sminshall if ((head->result != STATE_NULL) && (head->result != STATE_GOTO)) { 50231055Sminshall /* this means that a previously defined sequence is an initial 50331055Sminshall * part of this one. 50431055Sminshall */ 50531055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 50631055Sminshall identifier); 50731055Sminshall return(0); 50831055Sminshall } 50931055Sminshall # ifdef DEBUG 51031055Sminshall if (debug) { 51131100Sminshall fprintf(stderr, "%s", uncontrol(*string)); 51231055Sminshall } 51331055Sminshall # endif /* DEBUG */ 51431055Sminshall pState = GetState(); 51531055Sminshall pState->match = *string; 51631245Sminshall if (head->result == STATE_NULL) { 51731245Sminshall head->result = STATE_GOTO; 51831055Sminshall head->address = pState; 51931055Sminshall other = pState; 52031055Sminshall } else { /* search for same character */ 52131055Sminshall if ((other = FindMatchAtThisLevel(head->address, *string)) != 0) { 52231055Sminshall FreeState(pState); 52331055Sminshall } else { 52431055Sminshall pState->next = head->address; 52531055Sminshall head->address = pState; 52631055Sminshall other = pState; 52731055Sminshall } 52831055Sminshall } 52931055Sminshall return(PasteEntry(other, string+1, count-1, identifier)); 53031055Sminshall } 53131055Sminshall 53231055Sminshall static 53331055Sminshall GetInput(tc, identifier) 53431055Sminshall int tc; 53531055Sminshall char *identifier; /* entry being parsed (for error messages) */ 53631055Sminshall { 53731055Sminshall stringWithLength *outputString; 53831055Sminshall state *head; 53931055Sminshall state fakeQueue; 54031055Sminshall 54131055Sminshall if (doPaste) { 54231055Sminshall head = headOfQueue; /* always points to level above this one */ 54331055Sminshall } else { 54431055Sminshall head = &fakeQueue; /* don't have any side effects... */ 54531055Sminshall } 54631055Sminshall 54731055Sminshall if ((outputString = GetQuotedString()) == 0) { 54831055Sminshall return(0); 54931055Sminshall } else if (IsPrint(outputString->array[0])) { 55031055Sminshall fprintf(stderr, 55131055Sminshall "first character of sequence for %s is not a control type character\n", 55231055Sminshall identifier); 55331055Sminshall return(0); 55431055Sminshall } else { 55531055Sminshall if ((head = PasteEntry(head, outputString->array, 55631055Sminshall outputString->length, identifier)) == 0) { 55731055Sminshall return(0); 55831055Sminshall } 55931055Sminshall GetWS(); 56031055Sminshall while ((outputString = GetQuotedString()) != 0) { 56131055Sminshall if ((head = PasteEntry(head, outputString->array, 56231055Sminshall outputString->length, identifier)) == 0) { 56331055Sminshall return(0); 56431055Sminshall } 56531055Sminshall GetWS(); 56631055Sminshall } 56731055Sminshall } 56831055Sminshall if (!doPaste) { 56931055Sminshall return(1); 57031055Sminshall } 57131245Sminshall if ((head->result != STATE_NULL) && (head->result != tc)) { 57231055Sminshall /* this means that this sequence is an initial part 57331055Sminshall * of a previously defined one. 57431055Sminshall */ 57531055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 57631055Sminshall identifier); 57731055Sminshall return(0); 57831055Sminshall } else { 57931055Sminshall head->result = tc; 58031055Sminshall return(1); /* done */ 58131055Sminshall } 58231055Sminshall } 58331055Sminshall 58431055Sminshall static 58531055Sminshall GetDefinition() 58631055Sminshall { 58731055Sminshall stringWithLength *string; 58831055Sminshall int Tc; 58931055Sminshall 59031055Sminshall GetWS(); 59131055Sminshall if ((string = GetAlphaMericString()) == 0) { 59231055Sminshall return(0); 59331055Sminshall } 59431055Sminshall string->array[string->length] = 0; 59531055Sminshall if (doPaste) { 59631609Sminshall if ((Tc = (*GetTc)(string->array)) == -1) { 59731055Sminshall if (picky) { 59831055Sminshall fprintf(stderr, "%s: unknown 3270 key identifier\n", 59931055Sminshall string->array); 60031055Sminshall } 60131245Sminshall Tc = STATE_NULL; 60231055Sminshall } 60331055Sminshall } else { 60431245Sminshall Tc = STATE_NULL; /* XXX ? */ 60531055Sminshall } 60631055Sminshall GetWS(); 60731055Sminshall if (!GetCharacter('=')) { 60831055Sminshall fprintf(stderr, 60931055Sminshall "Required equal sign after 3270 key identifier %s missing\n", 61031055Sminshall string->array); 61131055Sminshall return(0); 61231055Sminshall } 61331055Sminshall GetWS(); 61431055Sminshall if (!GetInput(Tc, string->array)) { 61531055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 61631055Sminshall string->array); 61731055Sminshall return(0); 61831055Sminshall } else { 61931055Sminshall GetWS(); 62031055Sminshall while (GetCharacter('|')) { 62131055Sminshall # ifdef DEBUG 62231055Sminshall if (debug) { 62331055Sminshall fprintf(stderr, " or "); 62431055Sminshall } 62531055Sminshall # endif /* DEBUG */ 62631055Sminshall GetWS(); 62731055Sminshall if (!GetInput(Tc, string->array)) { 62831055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 62931055Sminshall string->array); 63031055Sminshall return(0); 63131055Sminshall } 63231055Sminshall GetWS(); 63331055Sminshall } 63431055Sminshall } 63531055Sminshall GetWS(); 63631055Sminshall if (!GetCharacter(';')) { 63731055Sminshall fprintf(stderr, "Missing semi-colon for 3270 key %s\n", string->array); 63831055Sminshall return(0); 63931055Sminshall } 64031055Sminshall # ifdef DEBUG 64131055Sminshall if (debug) { 64231055Sminshall fprintf(stderr, ";\n"); 64331055Sminshall } 64431055Sminshall # endif /* DEBUG */ 64531055Sminshall return(1); 64631055Sminshall } 64731055Sminshall 64831055Sminshall 64931055Sminshall static 65031055Sminshall GetDefinitions() 65131055Sminshall { 65231055Sminshall if (!GetDefinition()) { 65331055Sminshall return(0); 65431055Sminshall } else { 65531055Sminshall while (GetDefinition()) { 65631055Sminshall ; 65731055Sminshall } 65831055Sminshall } 65931055Sminshall return(1); 66031055Sminshall } 66131055Sminshall 66231055Sminshall static 66331055Sminshall GetBegin() 66431055Sminshall { 66531055Sminshall GetWS(); 66631055Sminshall if (!GetCharacter('{')) { 66731055Sminshall return(0); 66831055Sminshall } 66931055Sminshall return(1); 67031055Sminshall } 67131055Sminshall 67231055Sminshall static 67331055Sminshall GetEnd() 67431055Sminshall { 67531055Sminshall GetWS(); 67631055Sminshall if (!GetCharacter('}')) { 67731055Sminshall return(0); 67831055Sminshall } 67931055Sminshall return(1); 68031055Sminshall } 68131055Sminshall 68231055Sminshall static 68331055Sminshall GetName() 68431055Sminshall { 68531055Sminshall if (!GetAlphaMericString()) { 68631055Sminshall return(0); 68731055Sminshall } 68831055Sminshall GetWS(); 68931055Sminshall while (GetAlphaMericString()) { 69031055Sminshall GetWS(); 69131055Sminshall } 69231055Sminshall return(1); 69331055Sminshall } 69431055Sminshall 69531055Sminshall static 69631055Sminshall GetNames() 69731055Sminshall { 69831055Sminshall GetWS(); 69931055Sminshall if (!GetName()) { 70031055Sminshall return(0); 70131055Sminshall } else { 70231055Sminshall GetWS(); 70331055Sminshall while (GetCharacter('|')) { 70431055Sminshall GetWS(); 70531055Sminshall if (!GetName()) { 70631055Sminshall return(0); 70731055Sminshall } 70831055Sminshall } 70931055Sminshall } 71031055Sminshall return(1); 71131055Sminshall } 71231055Sminshall 71331055Sminshall static 71431055Sminshall GetEntry0() 71531055Sminshall { 71631055Sminshall if (!GetBegin()) { 71731055Sminshall fprintf(stderr, "no '{'\n"); 71831055Sminshall return(0); 71931055Sminshall } else if (!GetDefinitions()) { 72031055Sminshall fprintf(stderr, "unable to parse the definitions\n"); 72131055Sminshall return(0); 72231055Sminshall } else if (!GetEnd()) { 72331055Sminshall fprintf(stderr, "No '}' or scanning stopped early due to error.\n"); 72431055Sminshall return(0); 72531055Sminshall } else { 72631055Sminshall /* done */ 72731055Sminshall return(1); 72831055Sminshall } 72931055Sminshall } 73031055Sminshall 73131055Sminshall 73231055Sminshall static 73331055Sminshall GetEntry() 73431055Sminshall { 73531055Sminshall if (!GetNames()) { 73631055Sminshall fprintf(stderr, "Invalid name field in entry.\n"); 73731055Sminshall return(0); 73831055Sminshall } else { 73931055Sminshall return(GetEntry0()); 74031055Sminshall } 74131055Sminshall } 74231055Sminshall 74331055Sminshall /* position ourselves within a given filename to the entry for the current 74431055Sminshall * KEYBD (or TERM) variable 74531055Sminshall */ 74631055Sminshall 74731055Sminshall Position(filename, keybdPointer) 74831055Sminshall char *filename; 74931055Sminshall char *keybdPointer; 75031055Sminshall { 75131055Sminshall lexicon lex; 75231055Sminshall stringWithLength *name = 0; 75331055Sminshall stringWithLength *oldName; 75431055Sminshall # define Return(x) {doPaste = 1; return(x);} 75531055Sminshall 75631055Sminshall doPaste = 0; 75731055Sminshall 75831055Sminshall if ((ourFile = fopen(filename, "r")) == NULL) { 75931100Sminshall # if !defined(MSDOS) 76031055Sminshall fprintf(stderr, "Unable to open file %s\n", filename); 76131100Sminshall # endif /* !defined(MSDOS) */ 76231055Sminshall Return(0); 76331055Sminshall } 76431055Sminshall lex = Get(); 76531055Sminshall while (lex.type != LEX_END_OF_FILE) { 76631055Sminshall UnGet(lex); 76731055Sminshall /* now, find an entry that is our type. */ 76831055Sminshall GetWS(); 76931055Sminshall oldName = name; 77031055Sminshall if ((name = GetAlphaMericString()) != 0) { 77131055Sminshall if (!ustrcmp(name->array, keybdPointer)) { 77231055Sminshall /* need to make sure there is a name here... */ 77331055Sminshall lex.type = LEX_CHAR; 77431055Sminshall lex.value = 'a'; 77531055Sminshall UnGet(lex); 77631055Sminshall Return(1); 77731055Sminshall } 77831055Sminshall } else if (GetCharacter('|')) { 77931055Sminshall ; /* more names coming */ 78031055Sminshall } else { 78131055Sminshall lex = Get(); 78231055Sminshall UnGet(lex); 78331055Sminshall if (lex.type != LEX_END_OF_FILE) { 78431055Sminshall if (!GetEntry0()) { /* start of an entry */ 78531055Sminshall fprintf(stderr, 78631055Sminshall "error was in entry for %s in file %s\n", 78731055Sminshall (oldName)? oldName->array:"(unknown)", filename); 78831055Sminshall Return(0); 78931055Sminshall } 79031055Sminshall } 79131055Sminshall } 79231055Sminshall lex = Get(); 79331055Sminshall } 79431100Sminshall #if !defined(MSDOS) 79531055Sminshall fprintf(stderr, "Unable to find entry for %s in file %s\n", keybdPointer, 79631055Sminshall filename); 79731100Sminshall #endif /* !defined(MSDOS) */ 79831055Sminshall Return(0); 79931055Sminshall } 80031055Sminshall 80131055Sminshall char * 80231055Sminshall strsave(string) 80331055Sminshall char *string; 80431055Sminshall { 80531055Sminshall char *p; 80631055Sminshall extern char *malloc(); 80731055Sminshall 80835419Sminshall p = malloc((unsigned int)strlen(string)+1); 80931055Sminshall if (p != 0) { 81031055Sminshall strcpy(p, string); 81131055Sminshall } 81231055Sminshall return(p); 81331055Sminshall } 81431055Sminshall 81531055Sminshall 81631055Sminshall /* 81731055Sminshall * InitControl - our interface to the outside. What we should 81831055Sminshall * do is figure out keyboard (or terminal) type, set up file pointer 81931055Sminshall * (or string pointer), etc. 82031055Sminshall */ 82131055Sminshall 82231055Sminshall state * 82331245Sminshall InitControl(keybdPointer, pickyarg, translator) 82431055Sminshall char *keybdPointer; 82531055Sminshall int pickyarg; /* Should we be picky? */ 82631245Sminshall int (*translator)(); /* Translates ascii string to integer */ 82731055Sminshall { 82831055Sminshall extern char *getenv(); 82931055Sminshall int GotIt; 83031055Sminshall 83131055Sminshall picky = pickyarg; 83231245Sminshall GetTc = translator; 83331055Sminshall 83431055Sminshall if (keybdPointer == 0) { 83531055Sminshall keybdPointer = getenv("KEYBD"); 83631055Sminshall } 83731055Sminshall if (keybdPointer == 0) { 83831055Sminshall keybdPointer = getenv("TERM"); 83931055Sminshall } 84031055Sminshall 84131055Sminshall /* 84231055Sminshall * Some environments have getenv() return 84331055Sminshall * out of a static area. So, save the keyboard name. 84431055Sminshall */ 84531055Sminshall if (keybdPointer) { 84631055Sminshall keybdPointer = strsave(keybdPointer); 84731055Sminshall } 84831055Sminshall environPointer = getenv("MAP3270"); 84931055Sminshall if (environPointer 85031055Sminshall && (environPointer[0] != '/') 85131100Sminshall #if defined(MSDOS) 85231055Sminshall && (environPointer[0] != '\\') 85331100Sminshall #endif /* defined(MSDOS) */ 85431055Sminshall && (strncmp(keybdPointer, environPointer, 85531055Sminshall strlen(keybdPointer) != 0) 85631055Sminshall || (environPointer[strlen(keybdPointer)] != '{'))) /* } */ 85731055Sminshall { 85831055Sminshall environPointer = 0; 85931055Sminshall } 86031055Sminshall 86131055Sminshall if ((!environPointer) 86231100Sminshall #if defined(MSDOS) 86331055Sminshall || (*environPointer == '\\') 86431100Sminshall #endif /* defined(MSDOS) */ 86531055Sminshall || (*environPointer == '/')) { 86631055Sminshall usePointer = 0; 86731055Sminshall GotIt = 0; 86831055Sminshall if (!keybdPointer) { 86931100Sminshall #if !defined(MSDOS) 87031055Sminshall fprintf(stderr, "%s%s%s%s", 87131055Sminshall "Neither the KEYBD environment variable nor the TERM ", 87231055Sminshall "environment variable\n(one of which is needed to determine ", 87331055Sminshall "the type of keyboard you are using)\n", 87431055Sminshall "is set. To set it, say 'setenv KEYBD <type>'\n"); 87531100Sminshall #endif /* !defined(MSDOS) */ 87631055Sminshall } else { 87731055Sminshall if (environPointer) { 87831055Sminshall GotIt = Position(environPointer, keybdPointer); 87931055Sminshall } 88031055Sminshall if (!GotIt) { 88131055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 88231055Sminshall } 88331055Sminshall } 88431055Sminshall if (!GotIt) { 88531055Sminshall if (environPointer) { 88631055Sminshall GotIt = Position(environPointer, "unknown"); 88731055Sminshall } 88831055Sminshall if (!GotIt) { 88931055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 89031055Sminshall } 89131055Sminshall } 89231055Sminshall if (!GotIt) { 89331100Sminshall #if !defined(MSDOS) 89431055Sminshall fprintf(stderr, "Using default key mappings.\n"); 89531100Sminshall #endif /* !defined(MSDOS) */ 89631055Sminshall usePointer = 1; /* flag use of non-file */ 89731135Sminshall whichkey = keysgeneric; 89831135Sminshall environPointer = *whichkey; /* use default table */ 89931055Sminshall } 90031055Sminshall } else { 90131055Sminshall usePointer = 1; 90231055Sminshall } 90331055Sminshall (void) GetEntry(); 90431055Sminshall return(firstentry.address); 90531055Sminshall } 906