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 #include "state.h" 5831055Sminshall 5931176Sminshall #include "../general/globals.h" 6031055Sminshall #include "map3270.ext" 6131055Sminshall 6231055Sminshall /* this is the list of types returned by the lex processor */ 6331245Sminshall #define LEX_CHAR 400 /* plain unadorned character */ 6431055Sminshall #define LEX_ESCAPED LEX_CHAR+1 /* escaped with \ */ 6531055Sminshall #define LEX_CARETED LEX_ESCAPED+1 /* escaped with ^ */ 6631055Sminshall #define LEX_END_OF_FILE LEX_CARETED+1 /* end of file encountered */ 6731055Sminshall #define LEX_ILLEGAL LEX_END_OF_FILE+1 /* trailing escape character */ 6831055Sminshall 6931055Sminshall /* the following is part of our character set dependancy... */ 7031055Sminshall #define ESCAPE 0x1b 7131055Sminshall #define TAB 0x09 7231055Sminshall #define NEWLINE 0x0a 7331055Sminshall #define CARRIAGE_RETURN 0x0d 7431055Sminshall 7531055Sminshall typedef struct { 7631055Sminshall int type; /* LEX_* - type of character */ 7731055Sminshall int value; /* character this was */ 7831055Sminshall } lexicon; 7931055Sminshall 8031055Sminshall typedef struct { 8131055Sminshall int length; /* length of character string */ 8231055Sminshall char array[500]; /* character string */ 8331055Sminshall } stringWithLength; 8431055Sminshall 8531055Sminshall #define panic(s) { fprintf(stderr, s); exit(1); } 8631055Sminshall 8731245Sminshall static state firstentry = { 0, STATE_NULL, 0, 0 }; 8831055Sminshall static state *headOfQueue = &firstentry; 8931055Sminshall 9031055Sminshall /* the following is a primitive adm3a table, to be used when nothing 9131055Sminshall * else seems to be avaliable. 9231055Sminshall */ 9331055Sminshall 9431055Sminshall #ifdef DEBUG 9531055Sminshall static int debug = 0; /* debug flag (for debuggin tables) */ 9631055Sminshall #endif /* DEBUG */ 9731055Sminshall 9831245Sminshall static int (*GetTc)(); 9931245Sminshall static int doPaste = 1; /* should we have side effects */ 10031245Sminshall static int picky = 0; /* do we complain of unknown functions? */ 10131245Sminshall static char usePointer = 0; /* use pointer, or file */ 10231055Sminshall static FILE *ourFile= 0; 10331245Sminshall static char *environPointer = 0;/* if non-zero, point to input 10431245Sminshall * string in core. 10531245Sminshall */ 10631135Sminshall static char **whichkey = 0; 10731135Sminshall static char *keysgeneric[] = { 10831055Sminshall #include "default.map" /* Define the default default */ 10931135Sminshall 11031135Sminshall 0, /* Terminate list of entries */ 11131135Sminshall }; 11231055Sminshall ; 11331055Sminshall 11431055Sminshall static int Empty = 1, /* is the unget lifo empty? */ 11531055Sminshall Full = 0; /* is the unget lifo full? */ 11631100Sminshall static lexicon lifo[200] = { 0 }; /* character stack for parser */ 11731055Sminshall static int rp = 0, /* read pointer into lifo */ 11831055Sminshall wp = 0; /* write pointer into lifo */ 11931055Sminshall 12031055Sminshall static int 12131055Sminshall GetC() 12231055Sminshall { 12331055Sminshall int character; 12431055Sminshall 12531055Sminshall if (usePointer) { 12631135Sminshall if ((*environPointer) == 0) { 12731135Sminshall /* 12831135Sminshall * If we have reached the end of this string, go on to 12931135Sminshall * the next (if there is a next). 13031135Sminshall */ 13131135Sminshall if (whichkey == 0) { 13231135Sminshall static char suffix = 'A'; /* From environment */ 13331135Sminshall char envname[9]; 13431135Sminshall extern char *getenv(); 13531055Sminshall 13631135Sminshall (void) sprintf(envname, "MAP3270%c", suffix++); 13731135Sminshall environPointer = getenv(envname); 13831055Sminshall } else { 13931135Sminshall whichkey++; /* default map */ 14031135Sminshall environPointer = *whichkey; 14131055Sminshall } 14231055Sminshall } 14331135Sminshall if (*environPointer) { 14431135Sminshall character = 0xff&*environPointer++; 14531135Sminshall } else { 14631135Sminshall character = EOF; 14731135Sminshall } 14831055Sminshall } else { 14931055Sminshall character = getc(ourFile); 15031055Sminshall } 15131055Sminshall return(character); 15231055Sminshall } 15331055Sminshall 15431055Sminshall static lexicon 15531055Sminshall Get() 15631055Sminshall { 15731055Sminshall lexicon c; 15831055Sminshall register lexicon *pC = &c; 15931055Sminshall register int character; 16031055Sminshall 16131055Sminshall if (!Empty) { 16231055Sminshall *pC = lifo[rp]; 16331055Sminshall rp++; 16431055Sminshall if (rp == sizeof lifo/sizeof (lexicon)) { 16531055Sminshall rp = 0; 16631055Sminshall } 16731055Sminshall if (rp == wp) { 16831055Sminshall Empty = 1; 16931055Sminshall } 17031055Sminshall Full = 0; 17131055Sminshall } else { 17231055Sminshall character = GetC(); 17331055Sminshall switch (character) { 17431055Sminshall case EOF: 17531055Sminshall pC->type = LEX_END_OF_FILE; 17631055Sminshall break; 17731055Sminshall case '^': 17831055Sminshall character = GetC(); 17931055Sminshall if (!IsPrint(character)) { 18031055Sminshall pC->type = LEX_ILLEGAL; 18131055Sminshall } else { 18231055Sminshall pC->type = LEX_CARETED; 18331055Sminshall if (character == '?') { 18431055Sminshall character |= 0x40; /* rubout */ 18531055Sminshall } else { 18631055Sminshall character &= 0x1f; 18731055Sminshall } 18831055Sminshall } 18931055Sminshall break; 19031055Sminshall case '\\': 19131055Sminshall character = GetC(); 19231055Sminshall if (!IsPrint(character)) { 19331055Sminshall pC->type = LEX_ILLEGAL; 19431055Sminshall } else { 19531055Sminshall pC->type = LEX_ESCAPED; 19631055Sminshall switch (character) { 19731055Sminshall case 'E': case 'e': 19831055Sminshall character = ESCAPE; 19931055Sminshall break; 20031055Sminshall case 't': 20131055Sminshall character = TAB; 20231055Sminshall break; 20331055Sminshall case 'n': 20431055Sminshall character = NEWLINE; 20531055Sminshall break; 20631055Sminshall case 'r': 20731055Sminshall character = CARRIAGE_RETURN; 20831055Sminshall break; 20931055Sminshall default: 21031055Sminshall pC->type = LEX_ILLEGAL; 21131055Sminshall break; 21231055Sminshall } 21331055Sminshall } 21431055Sminshall break; 21531055Sminshall default: 21631055Sminshall if ((IsPrint(character)) || isspace(character)) { 21731055Sminshall pC->type = LEX_CHAR; 21831055Sminshall } else { 21931055Sminshall pC->type = LEX_ILLEGAL; 22031055Sminshall } 22131055Sminshall break; 22231055Sminshall } 22331055Sminshall pC->value = character; 22431055Sminshall } 22531055Sminshall return(*pC); 22631055Sminshall } 22731055Sminshall 22831055Sminshall static void 22931055Sminshall UnGet(c) 23031055Sminshall lexicon c; /* character to unget */ 23131055Sminshall { 23231055Sminshall if (Full) { 23331055Sminshall fprintf(stderr, "attempt to put too many characters in lifo\n"); 23431055Sminshall panic("map3270"); 23531055Sminshall /* NOTREACHED */ 23631055Sminshall } else { 23731055Sminshall lifo[wp] = c; 23831055Sminshall wp++; 23931055Sminshall if (wp == sizeof lifo/sizeof (lexicon)) { 24031055Sminshall wp = 0; 24131055Sminshall } 24231055Sminshall if (wp == rp) { 24331055Sminshall Full = 1; 24431055Sminshall } 24531055Sminshall Empty = 0; 24631055Sminshall } 24731055Sminshall } 24831055Sminshall 24931100Sminshall /* 25031100Sminshall * Construct a control character sequence 25131100Sminshall * for a special character. 25231100Sminshall */ 25331100Sminshall char * 25431100Sminshall uncontrol(c) 25531100Sminshall register int c; 25631100Sminshall { 25731100Sminshall static char buf[3]; 25831100Sminshall 25931100Sminshall if (c == 0x7f) 26031100Sminshall return ("^?"); 26131100Sminshall if (c == '\377') { 26231100Sminshall return "-1"; 26331100Sminshall } 26431100Sminshall if (c >= 0x20) { 26531100Sminshall buf[0] = c; 26631100Sminshall buf[1] = 0; 26731100Sminshall } else { 26831100Sminshall buf[0] = '^'; 26931100Sminshall buf[1] = '@'+c; 27031100Sminshall buf[2] = 0; 27131100Sminshall } 27231100Sminshall return (buf); 27331100Sminshall } 27431100Sminshall 27531055Sminshall /* compare two strings, ignoring case */ 27631055Sminshall 27731055Sminshall ustrcmp(string1, string2) 27831055Sminshall register char *string1; 27931055Sminshall register char *string2; 28031055Sminshall { 28131055Sminshall register int c1, c2; 28231055Sminshall 28331055Sminshall while ((c1 = (unsigned char) *string1++) != 0) { 28431055Sminshall if (isupper(c1)) { 28531055Sminshall c1 = tolower(c1); 28631055Sminshall } 28731055Sminshall if (isupper(c2 = (unsigned char) *string2++)) { 28831055Sminshall c2 = tolower(c2); 28931055Sminshall } 29031055Sminshall if (c1 < c2) { 29131055Sminshall return(-1); 29231055Sminshall } else if (c1 > c2) { 29331055Sminshall return(1); 29431055Sminshall } 29531055Sminshall } 29631055Sminshall if (*string2) { 29731055Sminshall return(-1); 29831055Sminshall } else { 29931055Sminshall return(0); 30031055Sminshall } 30131055Sminshall } 30231055Sminshall 30331055Sminshall 30431055Sminshall static stringWithLength * 30531055Sminshall GetQuotedString() 30631055Sminshall { 30731055Sminshall lexicon lex; 30831055Sminshall static stringWithLength output = { 0 }; /* where return value is held */ 30931055Sminshall char *pointer = output.array; 31031055Sminshall 31131055Sminshall lex = Get(); 31231055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != '\'')) { 31331055Sminshall UnGet(lex); 31431055Sminshall return(0); 31531055Sminshall } 31631055Sminshall while (1) { 31731055Sminshall lex = Get(); 31831055Sminshall if ((lex.type == LEX_CHAR) && (lex.value == '\'')) { 31931055Sminshall break; 32031055Sminshall } 32131055Sminshall if ((lex.type == LEX_CHAR) && !IsPrint(lex.value)) { 32231055Sminshall UnGet(lex); 32331055Sminshall return(0); /* illegal character in quoted string */ 32431055Sminshall } 32531055Sminshall if (pointer >= output.array+sizeof output.array) { 32631055Sminshall return(0); /* too long */ 32731055Sminshall } 32831055Sminshall *pointer++ = lex.value; 32931055Sminshall } 33031055Sminshall output.length = pointer-output.array; 33131055Sminshall return(&output); 33231055Sminshall } 33331055Sminshall 33431055Sminshall #ifdef NOTUSED 33531055Sminshall static stringWithLength * 33631055Sminshall GetCharString() 33731055Sminshall { 33831055Sminshall lexicon lex; 33931055Sminshall static stringWithLength output; 34031055Sminshall char *pointer = output.array; 34131055Sminshall 34231055Sminshall lex = Get(); 34331055Sminshall 34431055Sminshall while ((lex.type == LEX_CHAR) && 34531055Sminshall !isspace(lex.value) && (lex.value != '=')) { 34631055Sminshall *pointer++ = lex.value; 34731055Sminshall lex = Get(); 34831055Sminshall if (pointer >= output.array + sizeof output.array) { 34931055Sminshall return(0); /* too long */ 35031055Sminshall } 35131055Sminshall } 35231055Sminshall UnGet(lex); 35331055Sminshall output.length = pointer-output.array; 35431055Sminshall return(&output); 35531055Sminshall } 35631055Sminshall #endif /* NOTUSED */ 35731055Sminshall 35831055Sminshall static 35931055Sminshall GetCharacter(character) 36031055Sminshall int character; /* desired character */ 36131055Sminshall { 36231055Sminshall lexicon lex; 36331055Sminshall 36431055Sminshall lex = Get(); 36531055Sminshall 36631055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != character)) { 36731055Sminshall UnGet(lex); 36831055Sminshall return(0); 36931055Sminshall } 37031055Sminshall return(1); 37131055Sminshall } 37231055Sminshall 37331055Sminshall #ifdef NOTUSED 37431055Sminshall static 37531055Sminshall GetString(string) 37631055Sminshall char *string; /* string to get */ 37731055Sminshall { 37831055Sminshall lexicon lex; 37931055Sminshall 38031055Sminshall while (*string) { 38131055Sminshall lex = Get(); 38231055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != *string&0xff)) { 38331055Sminshall UnGet(lex); 38431055Sminshall return(0); /* XXX restore to state on entry */ 38531055Sminshall } 38631055Sminshall string++; 38731055Sminshall } 38831055Sminshall return(1); 38931055Sminshall } 39031055Sminshall #endif /* NOTUSED */ 39131055Sminshall 39231055Sminshall 39331055Sminshall static stringWithLength * 39431055Sminshall GetAlphaMericString() 39531055Sminshall { 39631055Sminshall lexicon lex; 39731055Sminshall static stringWithLength output = { 0 }; 39831055Sminshall char *pointer = output.array; 39931055Sminshall # define IsAlnum(c) (isalnum(c) || (c == '_') \ 40031055Sminshall || (c == '-') || (c == '.')) 40131055Sminshall 40231055Sminshall lex = Get(); 40331055Sminshall 40431055Sminshall if ((lex.type != LEX_CHAR) || !IsAlnum(lex.value)) { 40531055Sminshall UnGet(lex); 40631055Sminshall return(0); 40731055Sminshall } 40831055Sminshall 40931055Sminshall while ((lex.type == LEX_CHAR) && IsAlnum(lex.value)) { 41031055Sminshall *pointer++ = lex.value; 41131055Sminshall lex = Get(); 41231055Sminshall } 41331055Sminshall UnGet(lex); 41431055Sminshall *pointer = 0; 41531055Sminshall output.length = pointer-output.array; 41631055Sminshall return(&output); 41731055Sminshall } 41831055Sminshall 41931055Sminshall 42031055Sminshall /* eat up characters until a new line, or end of file. returns terminating 42131055Sminshall character. 42231055Sminshall */ 42331055Sminshall 42431055Sminshall static lexicon 42531055Sminshall EatToNL() 42631055Sminshall { 42731055Sminshall lexicon lex; 42831055Sminshall 42931055Sminshall lex = Get(); 43031055Sminshall 43131055Sminshall while (!((lex.type != LEX_ESCAPED) && (lex.type != LEX_CARETED) && 43231055Sminshall (lex.value == '\n')) && (!(lex.type == LEX_END_OF_FILE))) { 43331055Sminshall lex = Get(); 43431055Sminshall } 43531055Sminshall if (lex.type != LEX_END_OF_FILE) { 43631055Sminshall return(Get()); 43731055Sminshall } else { 43831055Sminshall return(lex); 43931055Sminshall } 44031055Sminshall } 44131055Sminshall 44231055Sminshall 44331055Sminshall static void 44431055Sminshall GetWS() 44531055Sminshall { 44631055Sminshall lexicon lex; 44731055Sminshall 44831055Sminshall lex = Get(); 44931055Sminshall 45031055Sminshall while ((lex.type == LEX_CHAR) && 45131055Sminshall (isspace(lex.value) || (lex.value == '#'))) { 45231055Sminshall if (lex.value == '#') { 45331055Sminshall lex = EatToNL(); 45431055Sminshall } else { 45531055Sminshall lex = Get(); 45631055Sminshall } 45731055Sminshall } 45831055Sminshall UnGet(lex); 45931055Sminshall } 46031055Sminshall 46131055Sminshall static void 46231055Sminshall FreeState(pState) 46331055Sminshall state *pState; 46431055Sminshall { 46531055Sminshall extern void free(); 46631055Sminshall 46731055Sminshall free((char *)pState); 46831055Sminshall } 46931055Sminshall 47031055Sminshall 47131055Sminshall static state * 47231055Sminshall GetState() 47331055Sminshall { 47431055Sminshall state *pState; 47531055Sminshall extern char *malloc(); 47631055Sminshall 47731055Sminshall pState = (state *) malloc(sizeof (state)); 47831055Sminshall 47931245Sminshall pState->result = STATE_NULL; 48031055Sminshall pState->next = 0; 48131055Sminshall 48231055Sminshall return(pState); 48331055Sminshall } 48431055Sminshall 48531055Sminshall 48631055Sminshall static state * 48731055Sminshall FindMatchAtThisLevel(pState, character) 48831055Sminshall state *pState; 48931055Sminshall int character; 49031055Sminshall { 49131055Sminshall while (pState) { 49231055Sminshall if (pState->match == character) { 49331055Sminshall return(pState); 49431055Sminshall } 49531055Sminshall pState = pState->next; 49631055Sminshall } 49731055Sminshall return(0); 49831055Sminshall } 49931055Sminshall 50031055Sminshall 50131055Sminshall static state * 50231055Sminshall PasteEntry(head, string, count, identifier) 50331055Sminshall state *head; /* points to who should point here... */ 50431055Sminshall char *string; /* which characters to paste */ 50531055Sminshall int count; /* number of character to do */ 50631055Sminshall char *identifier; /* for error messages */ 50731055Sminshall { 50831055Sminshall state *pState, *other; 50931055Sminshall 51031055Sminshall if (!doPaste) { /* flag to not have any side effects */ 51131055Sminshall return((state *)1); 51231055Sminshall } 51331055Sminshall if (!count) { 51431055Sminshall return(head); /* return pointer to the parent */ 51531055Sminshall } 51631245Sminshall if ((head->result != STATE_NULL) && (head->result != STATE_GOTO)) { 51731055Sminshall /* this means that a previously defined sequence is an initial 51831055Sminshall * part of this one. 51931055Sminshall */ 52031055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 52131055Sminshall identifier); 52231055Sminshall return(0); 52331055Sminshall } 52431055Sminshall # ifdef DEBUG 52531055Sminshall if (debug) { 52631100Sminshall fprintf(stderr, "%s", uncontrol(*string)); 52731055Sminshall } 52831055Sminshall # endif /* DEBUG */ 52931055Sminshall pState = GetState(); 53031055Sminshall pState->match = *string; 53131245Sminshall if (head->result == STATE_NULL) { 53231245Sminshall head->result = STATE_GOTO; 53331055Sminshall head->address = pState; 53431055Sminshall other = pState; 53531055Sminshall } else { /* search for same character */ 53631055Sminshall if ((other = FindMatchAtThisLevel(head->address, *string)) != 0) { 53731055Sminshall FreeState(pState); 53831055Sminshall } else { 53931055Sminshall pState->next = head->address; 54031055Sminshall head->address = pState; 54131055Sminshall other = pState; 54231055Sminshall } 54331055Sminshall } 54431055Sminshall return(PasteEntry(other, string+1, count-1, identifier)); 54531055Sminshall } 54631055Sminshall 54731055Sminshall static 54831055Sminshall GetInput(tc, identifier) 54931055Sminshall int tc; 55031055Sminshall char *identifier; /* entry being parsed (for error messages) */ 55131055Sminshall { 55231055Sminshall stringWithLength *outputString; 55331055Sminshall state *head; 55431055Sminshall state fakeQueue; 55531055Sminshall 55631055Sminshall if (doPaste) { 55731055Sminshall head = headOfQueue; /* always points to level above this one */ 55831055Sminshall } else { 55931055Sminshall head = &fakeQueue; /* don't have any side effects... */ 56031055Sminshall } 56131055Sminshall 56231055Sminshall if ((outputString = GetQuotedString()) == 0) { 56331055Sminshall return(0); 56431055Sminshall } else if (IsPrint(outputString->array[0])) { 56531055Sminshall fprintf(stderr, 56631055Sminshall "first character of sequence for %s is not a control type character\n", 56731055Sminshall identifier); 56831055Sminshall return(0); 56931055Sminshall } else { 57031055Sminshall if ((head = PasteEntry(head, outputString->array, 57131055Sminshall outputString->length, identifier)) == 0) { 57231055Sminshall return(0); 57331055Sminshall } 57431055Sminshall GetWS(); 57531055Sminshall while ((outputString = GetQuotedString()) != 0) { 57631055Sminshall if ((head = PasteEntry(head, outputString->array, 57731055Sminshall outputString->length, identifier)) == 0) { 57831055Sminshall return(0); 57931055Sminshall } 58031055Sminshall GetWS(); 58131055Sminshall } 58231055Sminshall } 58331055Sminshall if (!doPaste) { 58431055Sminshall return(1); 58531055Sminshall } 58631245Sminshall if ((head->result != STATE_NULL) && (head->result != tc)) { 58731055Sminshall /* this means that this sequence is an initial part 58831055Sminshall * of a previously defined one. 58931055Sminshall */ 59031055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 59131055Sminshall identifier); 59231055Sminshall return(0); 59331055Sminshall } else { 59431055Sminshall head->result = tc; 59531055Sminshall return(1); /* done */ 59631055Sminshall } 59731055Sminshall } 59831055Sminshall 59931055Sminshall static 60031055Sminshall GetDefinition() 60131055Sminshall { 60231055Sminshall stringWithLength *string; 60331055Sminshall int Tc; 60431055Sminshall 60531055Sminshall GetWS(); 60631055Sminshall if ((string = GetAlphaMericString()) == 0) { 60731055Sminshall return(0); 60831055Sminshall } 60931055Sminshall string->array[string->length] = 0; 61031055Sminshall if (doPaste) { 611*31609Sminshall if ((Tc = (*GetTc)(string->array)) == -1) { 61231055Sminshall if (picky) { 61331055Sminshall fprintf(stderr, "%s: unknown 3270 key identifier\n", 61431055Sminshall string->array); 61531055Sminshall } 61631245Sminshall Tc = STATE_NULL; 61731055Sminshall } 61831055Sminshall } else { 61931245Sminshall Tc = STATE_NULL; /* XXX ? */ 62031055Sminshall } 62131055Sminshall GetWS(); 62231055Sminshall if (!GetCharacter('=')) { 62331055Sminshall fprintf(stderr, 62431055Sminshall "Required equal sign after 3270 key identifier %s missing\n", 62531055Sminshall string->array); 62631055Sminshall return(0); 62731055Sminshall } 62831055Sminshall GetWS(); 62931055Sminshall if (!GetInput(Tc, string->array)) { 63031055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 63131055Sminshall string->array); 63231055Sminshall return(0); 63331055Sminshall } else { 63431055Sminshall GetWS(); 63531055Sminshall while (GetCharacter('|')) { 63631055Sminshall # ifdef DEBUG 63731055Sminshall if (debug) { 63831055Sminshall fprintf(stderr, " or "); 63931055Sminshall } 64031055Sminshall # endif /* DEBUG */ 64131055Sminshall GetWS(); 64231055Sminshall if (!GetInput(Tc, string->array)) { 64331055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 64431055Sminshall string->array); 64531055Sminshall return(0); 64631055Sminshall } 64731055Sminshall GetWS(); 64831055Sminshall } 64931055Sminshall } 65031055Sminshall GetWS(); 65131055Sminshall if (!GetCharacter(';')) { 65231055Sminshall fprintf(stderr, "Missing semi-colon for 3270 key %s\n", string->array); 65331055Sminshall return(0); 65431055Sminshall } 65531055Sminshall # ifdef DEBUG 65631055Sminshall if (debug) { 65731055Sminshall fprintf(stderr, ";\n"); 65831055Sminshall } 65931055Sminshall # endif /* DEBUG */ 66031055Sminshall return(1); 66131055Sminshall } 66231055Sminshall 66331055Sminshall 66431055Sminshall static 66531055Sminshall GetDefinitions() 66631055Sminshall { 66731055Sminshall if (!GetDefinition()) { 66831055Sminshall return(0); 66931055Sminshall } else { 67031055Sminshall while (GetDefinition()) { 67131055Sminshall ; 67231055Sminshall } 67331055Sminshall } 67431055Sminshall return(1); 67531055Sminshall } 67631055Sminshall 67731055Sminshall static 67831055Sminshall GetBegin() 67931055Sminshall { 68031055Sminshall GetWS(); 68131055Sminshall if (!GetCharacter('{')) { 68231055Sminshall return(0); 68331055Sminshall } 68431055Sminshall return(1); 68531055Sminshall } 68631055Sminshall 68731055Sminshall static 68831055Sminshall GetEnd() 68931055Sminshall { 69031055Sminshall GetWS(); 69131055Sminshall if (!GetCharacter('}')) { 69231055Sminshall return(0); 69331055Sminshall } 69431055Sminshall return(1); 69531055Sminshall } 69631055Sminshall 69731055Sminshall static 69831055Sminshall GetName() 69931055Sminshall { 70031055Sminshall if (!GetAlphaMericString()) { 70131055Sminshall return(0); 70231055Sminshall } 70331055Sminshall GetWS(); 70431055Sminshall while (GetAlphaMericString()) { 70531055Sminshall GetWS(); 70631055Sminshall } 70731055Sminshall return(1); 70831055Sminshall } 70931055Sminshall 71031055Sminshall static 71131055Sminshall GetNames() 71231055Sminshall { 71331055Sminshall GetWS(); 71431055Sminshall if (!GetName()) { 71531055Sminshall return(0); 71631055Sminshall } else { 71731055Sminshall GetWS(); 71831055Sminshall while (GetCharacter('|')) { 71931055Sminshall GetWS(); 72031055Sminshall if (!GetName()) { 72131055Sminshall return(0); 72231055Sminshall } 72331055Sminshall } 72431055Sminshall } 72531055Sminshall return(1); 72631055Sminshall } 72731055Sminshall 72831055Sminshall static 72931055Sminshall GetEntry0() 73031055Sminshall { 73131055Sminshall if (!GetBegin()) { 73231055Sminshall fprintf(stderr, "no '{'\n"); 73331055Sminshall return(0); 73431055Sminshall } else if (!GetDefinitions()) { 73531055Sminshall fprintf(stderr, "unable to parse the definitions\n"); 73631055Sminshall return(0); 73731055Sminshall } else if (!GetEnd()) { 73831055Sminshall fprintf(stderr, "No '}' or scanning stopped early due to error.\n"); 73931055Sminshall return(0); 74031055Sminshall } else { 74131055Sminshall /* done */ 74231055Sminshall return(1); 74331055Sminshall } 74431055Sminshall } 74531055Sminshall 74631055Sminshall 74731055Sminshall static 74831055Sminshall GetEntry() 74931055Sminshall { 75031055Sminshall if (!GetNames()) { 75131055Sminshall fprintf(stderr, "Invalid name field in entry.\n"); 75231055Sminshall return(0); 75331055Sminshall } else { 75431055Sminshall return(GetEntry0()); 75531055Sminshall } 75631055Sminshall } 75731055Sminshall 75831055Sminshall /* position ourselves within a given filename to the entry for the current 75931055Sminshall * KEYBD (or TERM) variable 76031055Sminshall */ 76131055Sminshall 76231055Sminshall Position(filename, keybdPointer) 76331055Sminshall char *filename; 76431055Sminshall char *keybdPointer; 76531055Sminshall { 76631055Sminshall lexicon lex; 76731055Sminshall stringWithLength *name = 0; 76831055Sminshall stringWithLength *oldName; 76931055Sminshall # define Return(x) {doPaste = 1; return(x);} 77031055Sminshall 77131055Sminshall doPaste = 0; 77231055Sminshall 77331055Sminshall if ((ourFile = fopen(filename, "r")) == NULL) { 77431100Sminshall # if !defined(MSDOS) 77531055Sminshall fprintf(stderr, "Unable to open file %s\n", filename); 77631100Sminshall # endif /* !defined(MSDOS) */ 77731055Sminshall Return(0); 77831055Sminshall } 77931055Sminshall lex = Get(); 78031055Sminshall while (lex.type != LEX_END_OF_FILE) { 78131055Sminshall UnGet(lex); 78231055Sminshall /* now, find an entry that is our type. */ 78331055Sminshall GetWS(); 78431055Sminshall oldName = name; 78531055Sminshall if ((name = GetAlphaMericString()) != 0) { 78631055Sminshall if (!ustrcmp(name->array, keybdPointer)) { 78731055Sminshall /* need to make sure there is a name here... */ 78831055Sminshall lex.type = LEX_CHAR; 78931055Sminshall lex.value = 'a'; 79031055Sminshall UnGet(lex); 79131055Sminshall Return(1); 79231055Sminshall } 79331055Sminshall } else if (GetCharacter('|')) { 79431055Sminshall ; /* more names coming */ 79531055Sminshall } else { 79631055Sminshall lex = Get(); 79731055Sminshall UnGet(lex); 79831055Sminshall if (lex.type != LEX_END_OF_FILE) { 79931055Sminshall if (!GetEntry0()) { /* start of an entry */ 80031055Sminshall fprintf(stderr, 80131055Sminshall "error was in entry for %s in file %s\n", 80231055Sminshall (oldName)? oldName->array:"(unknown)", filename); 80331055Sminshall Return(0); 80431055Sminshall } 80531055Sminshall } 80631055Sminshall } 80731055Sminshall lex = Get(); 80831055Sminshall } 80931100Sminshall #if !defined(MSDOS) 81031055Sminshall fprintf(stderr, "Unable to find entry for %s in file %s\n", keybdPointer, 81131055Sminshall filename); 81231100Sminshall #endif /* !defined(MSDOS) */ 81331055Sminshall Return(0); 81431055Sminshall } 81531055Sminshall 81631055Sminshall char * 81731055Sminshall strsave(string) 81831055Sminshall char *string; 81931055Sminshall { 82031055Sminshall char *p; 82131055Sminshall extern char *malloc(); 82231055Sminshall 82331055Sminshall p = malloc(strlen(string)+1); 82431055Sminshall if (p != 0) { 82531055Sminshall strcpy(p, string); 82631055Sminshall } 82731055Sminshall return(p); 82831055Sminshall } 82931055Sminshall 83031055Sminshall 83131055Sminshall /* 83231055Sminshall * InitControl - our interface to the outside. What we should 83331055Sminshall * do is figure out keyboard (or terminal) type, set up file pointer 83431055Sminshall * (or string pointer), etc. 83531055Sminshall */ 83631055Sminshall 83731055Sminshall state * 83831245Sminshall InitControl(keybdPointer, pickyarg, translator) 83931055Sminshall char *keybdPointer; 84031055Sminshall int pickyarg; /* Should we be picky? */ 84131245Sminshall int (*translator)(); /* Translates ascii string to integer */ 84231055Sminshall { 84331055Sminshall extern char *getenv(); 84431055Sminshall int GotIt; 84531055Sminshall 84631055Sminshall picky = pickyarg; 84731245Sminshall GetTc = translator; 84831055Sminshall 84931055Sminshall if (keybdPointer == 0) { 85031055Sminshall keybdPointer = getenv("KEYBD"); 85131055Sminshall } 85231055Sminshall if (keybdPointer == 0) { 85331055Sminshall keybdPointer = getenv("TERM"); 85431055Sminshall } 85531055Sminshall 85631055Sminshall /* 85731055Sminshall * Some environments have getenv() return 85831055Sminshall * out of a static area. So, save the keyboard name. 85931055Sminshall */ 86031055Sminshall if (keybdPointer) { 86131055Sminshall keybdPointer = strsave(keybdPointer); 86231055Sminshall } 86331055Sminshall environPointer = getenv("MAP3270"); 86431055Sminshall if (environPointer 86531055Sminshall && (environPointer[0] != '/') 86631100Sminshall #if defined(MSDOS) 86731055Sminshall && (environPointer[0] != '\\') 86831100Sminshall #endif /* defined(MSDOS) */ 86931055Sminshall && (strncmp(keybdPointer, environPointer, 87031055Sminshall strlen(keybdPointer) != 0) 87131055Sminshall || (environPointer[strlen(keybdPointer)] != '{'))) /* } */ 87231055Sminshall { 87331055Sminshall environPointer = 0; 87431055Sminshall } 87531055Sminshall 87631055Sminshall if ((!environPointer) 87731100Sminshall #if defined(MSDOS) 87831055Sminshall || (*environPointer == '\\') 87931100Sminshall #endif /* defined(MSDOS) */ 88031055Sminshall || (*environPointer == '/')) { 88131055Sminshall usePointer = 0; 88231055Sminshall GotIt = 0; 88331055Sminshall if (!keybdPointer) { 88431100Sminshall #if !defined(MSDOS) 88531055Sminshall fprintf(stderr, "%s%s%s%s", 88631055Sminshall "Neither the KEYBD environment variable nor the TERM ", 88731055Sminshall "environment variable\n(one of which is needed to determine ", 88831055Sminshall "the type of keyboard you are using)\n", 88931055Sminshall "is set. To set it, say 'setenv KEYBD <type>'\n"); 89031100Sminshall #endif /* !defined(MSDOS) */ 89131055Sminshall } else { 89231055Sminshall if (environPointer) { 89331055Sminshall GotIt = Position(environPointer, keybdPointer); 89431055Sminshall } 89531055Sminshall if (!GotIt) { 89631055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 89731055Sminshall } 89831055Sminshall } 89931055Sminshall if (!GotIt) { 90031055Sminshall if (environPointer) { 90131055Sminshall GotIt = Position(environPointer, "unknown"); 90231055Sminshall } 90331055Sminshall if (!GotIt) { 90431055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 90531055Sminshall } 90631055Sminshall } 90731055Sminshall if (!GotIt) { 90831100Sminshall #if !defined(MSDOS) 90931055Sminshall fprintf(stderr, "Using default key mappings.\n"); 91031100Sminshall #endif /* !defined(MSDOS) */ 91131055Sminshall usePointer = 1; /* flag use of non-file */ 91231135Sminshall whichkey = keysgeneric; 91331135Sminshall environPointer = *whichkey; /* use default table */ 91431055Sminshall } 91531055Sminshall } else { 91631055Sminshall usePointer = 1; 91731055Sminshall } 91831055Sminshall (void) GetEntry(); 91931055Sminshall return(firstentry.address); 92031055Sminshall } 921