131055Sminshall /* 233817Sbostic * Copyright (c) 1988 Regents of the University of California. 333817Sbostic * All rights reserved. 431055Sminshall * 533817Sbostic * Redistribution and use in source and binary forms are permitted 6*34891Sbostic * provided that the above copyright notice and this paragraph are 7*34891Sbostic * duplicated in all such forms and that any documentation, 8*34891Sbostic * advertising materials, and other materials related to such 9*34891Sbostic * distribution and use acknowledge that the software was developed 10*34891Sbostic * by the University of California, Berkeley. The name of the 11*34891Sbostic * University may not be used to endorse or promote products derived 12*34891Sbostic * from this software without specific prior written permission. 13*34891Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34891Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34891Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1631055Sminshall */ 1731055Sminshall 1833817Sbostic #ifndef lint 19*34891Sbostic static char sccsid[] = "@(#)map3270.c 3.3 (Berkeley) 06/29/88"; 2033817Sbostic #endif /* not lint */ 2131055Sminshall 2231055Sminshall /* This program reads a description file, somewhat like /etc/termcap, 2331055Sminshall that describes the mapping between the current terminal's keyboard and 2431055Sminshall a 3270 keyboard. 2531055Sminshall */ 2631055Sminshall #ifdef DOCUMENTATION_ONLY 2731055Sminshall /* here is a sample (very small) entry... 2831055Sminshall 2931055Sminshall # this table is sensitive to position on a line. In particular, 3031055Sminshall # a terminal definition for a terminal is terminated whenever a 3131055Sminshall # (non-comment) line beginning in column one is found. 3231055Sminshall # 3331055Sminshall # this is an entry to map tvi924 to 3270 keys... 3431055Sminshall v8|tvi924|924|televideo model 924 { 3531055Sminshall pfk1 = '\E1'; 3631055Sminshall pfk2 = '\E2'; 3731055Sminshall clear = '^z'; # clear the screen 3831055Sminshall } 3931055Sminshall */ 4031055Sminshall #endif /* DOCUMENTATION_ONLY */ 4131055Sminshall 4231055Sminshall #include <stdio.h> 4331055Sminshall #include <ctype.h> 4431100Sminshall #if defined(unix) 4531055Sminshall #include <strings.h> 4631100Sminshall #else /* defined(unix) */ 4731100Sminshall #include <string.h> 4831100Sminshall #endif /* defined(unix) */ 4931055Sminshall 5031055Sminshall #define IsPrint(c) ((isprint(c) && !isspace(c)) || ((c) == ' ')) 5131055Sminshall 5231055Sminshall #include "state.h" 5331055Sminshall 5431176Sminshall #include "../general/globals.h" 5531055Sminshall #include "map3270.ext" 5631055Sminshall 5731055Sminshall /* this is the list of types returned by the lex processor */ 5831245Sminshall #define LEX_CHAR 400 /* plain unadorned character */ 5931055Sminshall #define LEX_ESCAPED LEX_CHAR+1 /* escaped with \ */ 6031055Sminshall #define LEX_CARETED LEX_ESCAPED+1 /* escaped with ^ */ 6131055Sminshall #define LEX_END_OF_FILE LEX_CARETED+1 /* end of file encountered */ 6231055Sminshall #define LEX_ILLEGAL LEX_END_OF_FILE+1 /* trailing escape character */ 6331055Sminshall 6431055Sminshall /* the following is part of our character set dependancy... */ 6531055Sminshall #define ESCAPE 0x1b 6631055Sminshall #define TAB 0x09 6731055Sminshall #define NEWLINE 0x0a 6831055Sminshall #define CARRIAGE_RETURN 0x0d 6931055Sminshall 7031055Sminshall typedef struct { 7131055Sminshall int type; /* LEX_* - type of character */ 7231055Sminshall int value; /* character this was */ 7331055Sminshall } lexicon; 7431055Sminshall 7531055Sminshall typedef struct { 7631055Sminshall int length; /* length of character string */ 7731055Sminshall char array[500]; /* character string */ 7831055Sminshall } stringWithLength; 7931055Sminshall 8031055Sminshall #define panic(s) { fprintf(stderr, s); exit(1); } 8131055Sminshall 8231245Sminshall static state firstentry = { 0, STATE_NULL, 0, 0 }; 8331055Sminshall static state *headOfQueue = &firstentry; 8431055Sminshall 8531055Sminshall /* the following is a primitive adm3a table, to be used when nothing 8631055Sminshall * else seems to be avaliable. 8731055Sminshall */ 8831055Sminshall 8931055Sminshall #ifdef DEBUG 9031055Sminshall static int debug = 0; /* debug flag (for debuggin tables) */ 9131055Sminshall #endif /* DEBUG */ 9231055Sminshall 9331245Sminshall static int (*GetTc)(); 9431245Sminshall static int doPaste = 1; /* should we have side effects */ 9531245Sminshall static int picky = 0; /* do we complain of unknown functions? */ 9631245Sminshall static char usePointer = 0; /* use pointer, or file */ 9731055Sminshall static FILE *ourFile= 0; 9831245Sminshall static char *environPointer = 0;/* if non-zero, point to input 9931245Sminshall * string in core. 10031245Sminshall */ 10131135Sminshall static char **whichkey = 0; 10231135Sminshall static char *keysgeneric[] = { 10331055Sminshall #include "default.map" /* Define the default default */ 10431135Sminshall 10531135Sminshall 0, /* Terminate list of entries */ 10631135Sminshall }; 10731055Sminshall ; 10831055Sminshall 10931055Sminshall static int Empty = 1, /* is the unget lifo empty? */ 11031055Sminshall Full = 0; /* is the unget lifo full? */ 11131100Sminshall static lexicon lifo[200] = { 0 }; /* character stack for parser */ 11231055Sminshall static int rp = 0, /* read pointer into lifo */ 11331055Sminshall wp = 0; /* write pointer into lifo */ 11431055Sminshall 11531055Sminshall static int 11631055Sminshall GetC() 11731055Sminshall { 11831055Sminshall int character; 11931055Sminshall 12031055Sminshall if (usePointer) { 12131135Sminshall if ((*environPointer) == 0) { 12231135Sminshall /* 12331135Sminshall * If we have reached the end of this string, go on to 12431135Sminshall * the next (if there is a next). 12531135Sminshall */ 12631135Sminshall if (whichkey == 0) { 12731135Sminshall static char suffix = 'A'; /* From environment */ 12831135Sminshall char envname[9]; 12931135Sminshall extern char *getenv(); 13031055Sminshall 13131135Sminshall (void) sprintf(envname, "MAP3270%c", suffix++); 13231135Sminshall environPointer = getenv(envname); 13331055Sminshall } else { 13431135Sminshall whichkey++; /* default map */ 13531135Sminshall environPointer = *whichkey; 13631055Sminshall } 13731055Sminshall } 13831135Sminshall if (*environPointer) { 13931135Sminshall character = 0xff&*environPointer++; 14031135Sminshall } else { 14131135Sminshall character = EOF; 14231135Sminshall } 14331055Sminshall } else { 14431055Sminshall character = getc(ourFile); 14531055Sminshall } 14631055Sminshall return(character); 14731055Sminshall } 14831055Sminshall 14931055Sminshall static lexicon 15031055Sminshall Get() 15131055Sminshall { 15231055Sminshall lexicon c; 15331055Sminshall register lexicon *pC = &c; 15431055Sminshall register int character; 15531055Sminshall 15631055Sminshall if (!Empty) { 15731055Sminshall *pC = lifo[rp]; 15831055Sminshall rp++; 15931055Sminshall if (rp == sizeof lifo/sizeof (lexicon)) { 16031055Sminshall rp = 0; 16131055Sminshall } 16231055Sminshall if (rp == wp) { 16331055Sminshall Empty = 1; 16431055Sminshall } 16531055Sminshall Full = 0; 16631055Sminshall } else { 16731055Sminshall character = GetC(); 16831055Sminshall switch (character) { 16931055Sminshall case EOF: 17031055Sminshall pC->type = LEX_END_OF_FILE; 17131055Sminshall break; 17231055Sminshall case '^': 17331055Sminshall character = GetC(); 17431055Sminshall if (!IsPrint(character)) { 17531055Sminshall pC->type = LEX_ILLEGAL; 17631055Sminshall } else { 17731055Sminshall pC->type = LEX_CARETED; 17831055Sminshall if (character == '?') { 17931055Sminshall character |= 0x40; /* rubout */ 18031055Sminshall } else { 18131055Sminshall character &= 0x1f; 18231055Sminshall } 18331055Sminshall } 18431055Sminshall break; 18531055Sminshall case '\\': 18631055Sminshall character = GetC(); 18731055Sminshall if (!IsPrint(character)) { 18831055Sminshall pC->type = LEX_ILLEGAL; 18931055Sminshall } else { 19031055Sminshall pC->type = LEX_ESCAPED; 19131055Sminshall switch (character) { 19231055Sminshall case 'E': case 'e': 19331055Sminshall character = ESCAPE; 19431055Sminshall break; 19531055Sminshall case 't': 19631055Sminshall character = TAB; 19731055Sminshall break; 19831055Sminshall case 'n': 19931055Sminshall character = NEWLINE; 20031055Sminshall break; 20131055Sminshall case 'r': 20231055Sminshall character = CARRIAGE_RETURN; 20331055Sminshall break; 20431055Sminshall default: 20531055Sminshall pC->type = LEX_ILLEGAL; 20631055Sminshall break; 20731055Sminshall } 20831055Sminshall } 20931055Sminshall break; 21031055Sminshall default: 21131055Sminshall if ((IsPrint(character)) || isspace(character)) { 21231055Sminshall pC->type = LEX_CHAR; 21331055Sminshall } else { 21431055Sminshall pC->type = LEX_ILLEGAL; 21531055Sminshall } 21631055Sminshall break; 21731055Sminshall } 21831055Sminshall pC->value = character; 21931055Sminshall } 22031055Sminshall return(*pC); 22131055Sminshall } 22231055Sminshall 22331055Sminshall static void 22431055Sminshall UnGet(c) 22531055Sminshall lexicon c; /* character to unget */ 22631055Sminshall { 22731055Sminshall if (Full) { 22831055Sminshall fprintf(stderr, "attempt to put too many characters in lifo\n"); 22931055Sminshall panic("map3270"); 23031055Sminshall /* NOTREACHED */ 23131055Sminshall } else { 23231055Sminshall lifo[wp] = c; 23331055Sminshall wp++; 23431055Sminshall if (wp == sizeof lifo/sizeof (lexicon)) { 23531055Sminshall wp = 0; 23631055Sminshall } 23731055Sminshall if (wp == rp) { 23831055Sminshall Full = 1; 23931055Sminshall } 24031055Sminshall Empty = 0; 24131055Sminshall } 24231055Sminshall } 24331055Sminshall 24431100Sminshall /* 24531100Sminshall * Construct a control character sequence 24631100Sminshall * for a special character. 24731100Sminshall */ 24831100Sminshall char * 24931100Sminshall uncontrol(c) 25031100Sminshall register int c; 25131100Sminshall { 25231100Sminshall static char buf[3]; 25331100Sminshall 25431100Sminshall if (c == 0x7f) 25531100Sminshall return ("^?"); 25631100Sminshall if (c == '\377') { 25731100Sminshall return "-1"; 25831100Sminshall } 25931100Sminshall if (c >= 0x20) { 26031100Sminshall buf[0] = c; 26131100Sminshall buf[1] = 0; 26231100Sminshall } else { 26331100Sminshall buf[0] = '^'; 26431100Sminshall buf[1] = '@'+c; 26531100Sminshall buf[2] = 0; 26631100Sminshall } 26731100Sminshall return (buf); 26831100Sminshall } 26931100Sminshall 27031055Sminshall /* compare two strings, ignoring case */ 27131055Sminshall 27231055Sminshall ustrcmp(string1, string2) 27331055Sminshall register char *string1; 27431055Sminshall register char *string2; 27531055Sminshall { 27631055Sminshall register int c1, c2; 27731055Sminshall 27831055Sminshall while ((c1 = (unsigned char) *string1++) != 0) { 27931055Sminshall if (isupper(c1)) { 28031055Sminshall c1 = tolower(c1); 28131055Sminshall } 28231055Sminshall if (isupper(c2 = (unsigned char) *string2++)) { 28331055Sminshall c2 = tolower(c2); 28431055Sminshall } 28531055Sminshall if (c1 < c2) { 28631055Sminshall return(-1); 28731055Sminshall } else if (c1 > c2) { 28831055Sminshall return(1); 28931055Sminshall } 29031055Sminshall } 29131055Sminshall if (*string2) { 29231055Sminshall return(-1); 29331055Sminshall } else { 29431055Sminshall return(0); 29531055Sminshall } 29631055Sminshall } 29731055Sminshall 29831055Sminshall 29931055Sminshall static stringWithLength * 30031055Sminshall GetQuotedString() 30131055Sminshall { 30231055Sminshall lexicon lex; 30331055Sminshall static stringWithLength output = { 0 }; /* where return value is held */ 30431055Sminshall char *pointer = output.array; 30531055Sminshall 30631055Sminshall lex = Get(); 30731055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != '\'')) { 30831055Sminshall UnGet(lex); 30931055Sminshall return(0); 31031055Sminshall } 31131055Sminshall while (1) { 31231055Sminshall lex = Get(); 31331055Sminshall if ((lex.type == LEX_CHAR) && (lex.value == '\'')) { 31431055Sminshall break; 31531055Sminshall } 31631055Sminshall if ((lex.type == LEX_CHAR) && !IsPrint(lex.value)) { 31731055Sminshall UnGet(lex); 31831055Sminshall return(0); /* illegal character in quoted string */ 31931055Sminshall } 32031055Sminshall if (pointer >= output.array+sizeof output.array) { 32131055Sminshall return(0); /* too long */ 32231055Sminshall } 32331055Sminshall *pointer++ = lex.value; 32431055Sminshall } 32531055Sminshall output.length = pointer-output.array; 32631055Sminshall return(&output); 32731055Sminshall } 32831055Sminshall 32931055Sminshall #ifdef NOTUSED 33031055Sminshall static stringWithLength * 33131055Sminshall GetCharString() 33231055Sminshall { 33331055Sminshall lexicon lex; 33431055Sminshall static stringWithLength output; 33531055Sminshall char *pointer = output.array; 33631055Sminshall 33731055Sminshall lex = Get(); 33831055Sminshall 33931055Sminshall while ((lex.type == LEX_CHAR) && 34031055Sminshall !isspace(lex.value) && (lex.value != '=')) { 34131055Sminshall *pointer++ = lex.value; 34231055Sminshall lex = Get(); 34331055Sminshall if (pointer >= output.array + sizeof output.array) { 34431055Sminshall return(0); /* too long */ 34531055Sminshall } 34631055Sminshall } 34731055Sminshall UnGet(lex); 34831055Sminshall output.length = pointer-output.array; 34931055Sminshall return(&output); 35031055Sminshall } 35131055Sminshall #endif /* NOTUSED */ 35231055Sminshall 35331055Sminshall static 35431055Sminshall GetCharacter(character) 35531055Sminshall int character; /* desired character */ 35631055Sminshall { 35731055Sminshall lexicon lex; 35831055Sminshall 35931055Sminshall lex = Get(); 36031055Sminshall 36131055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != character)) { 36231055Sminshall UnGet(lex); 36331055Sminshall return(0); 36431055Sminshall } 36531055Sminshall return(1); 36631055Sminshall } 36731055Sminshall 36831055Sminshall #ifdef NOTUSED 36931055Sminshall static 37031055Sminshall GetString(string) 37131055Sminshall char *string; /* string to get */ 37231055Sminshall { 37331055Sminshall lexicon lex; 37431055Sminshall 37531055Sminshall while (*string) { 37631055Sminshall lex = Get(); 37731055Sminshall if ((lex.type != LEX_CHAR) || (lex.value != *string&0xff)) { 37831055Sminshall UnGet(lex); 37931055Sminshall return(0); /* XXX restore to state on entry */ 38031055Sminshall } 38131055Sminshall string++; 38231055Sminshall } 38331055Sminshall return(1); 38431055Sminshall } 38531055Sminshall #endif /* NOTUSED */ 38631055Sminshall 38731055Sminshall 38831055Sminshall static stringWithLength * 38931055Sminshall GetAlphaMericString() 39031055Sminshall { 39131055Sminshall lexicon lex; 39231055Sminshall static stringWithLength output = { 0 }; 39331055Sminshall char *pointer = output.array; 39431055Sminshall # define IsAlnum(c) (isalnum(c) || (c == '_') \ 39531055Sminshall || (c == '-') || (c == '.')) 39631055Sminshall 39731055Sminshall lex = Get(); 39831055Sminshall 39931055Sminshall if ((lex.type != LEX_CHAR) || !IsAlnum(lex.value)) { 40031055Sminshall UnGet(lex); 40131055Sminshall return(0); 40231055Sminshall } 40331055Sminshall 40431055Sminshall while ((lex.type == LEX_CHAR) && IsAlnum(lex.value)) { 40531055Sminshall *pointer++ = lex.value; 40631055Sminshall lex = Get(); 40731055Sminshall } 40831055Sminshall UnGet(lex); 40931055Sminshall *pointer = 0; 41031055Sminshall output.length = pointer-output.array; 41131055Sminshall return(&output); 41231055Sminshall } 41331055Sminshall 41431055Sminshall 41531055Sminshall /* eat up characters until a new line, or end of file. returns terminating 41631055Sminshall character. 41731055Sminshall */ 41831055Sminshall 41931055Sminshall static lexicon 42031055Sminshall EatToNL() 42131055Sminshall { 42231055Sminshall lexicon lex; 42331055Sminshall 42431055Sminshall lex = Get(); 42531055Sminshall 42631055Sminshall while (!((lex.type != LEX_ESCAPED) && (lex.type != LEX_CARETED) && 42731055Sminshall (lex.value == '\n')) && (!(lex.type == LEX_END_OF_FILE))) { 42831055Sminshall lex = Get(); 42931055Sminshall } 43031055Sminshall if (lex.type != LEX_END_OF_FILE) { 43131055Sminshall return(Get()); 43231055Sminshall } else { 43331055Sminshall return(lex); 43431055Sminshall } 43531055Sminshall } 43631055Sminshall 43731055Sminshall 43831055Sminshall static void 43931055Sminshall GetWS() 44031055Sminshall { 44131055Sminshall lexicon lex; 44231055Sminshall 44331055Sminshall lex = Get(); 44431055Sminshall 44531055Sminshall while ((lex.type == LEX_CHAR) && 44631055Sminshall (isspace(lex.value) || (lex.value == '#'))) { 44731055Sminshall if (lex.value == '#') { 44831055Sminshall lex = EatToNL(); 44931055Sminshall } else { 45031055Sminshall lex = Get(); 45131055Sminshall } 45231055Sminshall } 45331055Sminshall UnGet(lex); 45431055Sminshall } 45531055Sminshall 45631055Sminshall static void 45731055Sminshall FreeState(pState) 45831055Sminshall state *pState; 45931055Sminshall { 46031055Sminshall extern void free(); 46131055Sminshall 46231055Sminshall free((char *)pState); 46331055Sminshall } 46431055Sminshall 46531055Sminshall 46631055Sminshall static state * 46731055Sminshall GetState() 46831055Sminshall { 46931055Sminshall state *pState; 47031055Sminshall extern char *malloc(); 47131055Sminshall 47231055Sminshall pState = (state *) malloc(sizeof (state)); 47331055Sminshall 47431245Sminshall pState->result = STATE_NULL; 47531055Sminshall pState->next = 0; 47631055Sminshall 47731055Sminshall return(pState); 47831055Sminshall } 47931055Sminshall 48031055Sminshall 48131055Sminshall static state * 48231055Sminshall FindMatchAtThisLevel(pState, character) 48331055Sminshall state *pState; 48431055Sminshall int character; 48531055Sminshall { 48631055Sminshall while (pState) { 48731055Sminshall if (pState->match == character) { 48831055Sminshall return(pState); 48931055Sminshall } 49031055Sminshall pState = pState->next; 49131055Sminshall } 49231055Sminshall return(0); 49331055Sminshall } 49431055Sminshall 49531055Sminshall 49631055Sminshall static state * 49731055Sminshall PasteEntry(head, string, count, identifier) 49831055Sminshall state *head; /* points to who should point here... */ 49931055Sminshall char *string; /* which characters to paste */ 50031055Sminshall int count; /* number of character to do */ 50131055Sminshall char *identifier; /* for error messages */ 50231055Sminshall { 50331055Sminshall state *pState, *other; 50431055Sminshall 50531055Sminshall if (!doPaste) { /* flag to not have any side effects */ 50631055Sminshall return((state *)1); 50731055Sminshall } 50831055Sminshall if (!count) { 50931055Sminshall return(head); /* return pointer to the parent */ 51031055Sminshall } 51131245Sminshall if ((head->result != STATE_NULL) && (head->result != STATE_GOTO)) { 51231055Sminshall /* this means that a previously defined sequence is an initial 51331055Sminshall * part of this one. 51431055Sminshall */ 51531055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 51631055Sminshall identifier); 51731055Sminshall return(0); 51831055Sminshall } 51931055Sminshall # ifdef DEBUG 52031055Sminshall if (debug) { 52131100Sminshall fprintf(stderr, "%s", uncontrol(*string)); 52231055Sminshall } 52331055Sminshall # endif /* DEBUG */ 52431055Sminshall pState = GetState(); 52531055Sminshall pState->match = *string; 52631245Sminshall if (head->result == STATE_NULL) { 52731245Sminshall head->result = STATE_GOTO; 52831055Sminshall head->address = pState; 52931055Sminshall other = pState; 53031055Sminshall } else { /* search for same character */ 53131055Sminshall if ((other = FindMatchAtThisLevel(head->address, *string)) != 0) { 53231055Sminshall FreeState(pState); 53331055Sminshall } else { 53431055Sminshall pState->next = head->address; 53531055Sminshall head->address = pState; 53631055Sminshall other = pState; 53731055Sminshall } 53831055Sminshall } 53931055Sminshall return(PasteEntry(other, string+1, count-1, identifier)); 54031055Sminshall } 54131055Sminshall 54231055Sminshall static 54331055Sminshall GetInput(tc, identifier) 54431055Sminshall int tc; 54531055Sminshall char *identifier; /* entry being parsed (for error messages) */ 54631055Sminshall { 54731055Sminshall stringWithLength *outputString; 54831055Sminshall state *head; 54931055Sminshall state fakeQueue; 55031055Sminshall 55131055Sminshall if (doPaste) { 55231055Sminshall head = headOfQueue; /* always points to level above this one */ 55331055Sminshall } else { 55431055Sminshall head = &fakeQueue; /* don't have any side effects... */ 55531055Sminshall } 55631055Sminshall 55731055Sminshall if ((outputString = GetQuotedString()) == 0) { 55831055Sminshall return(0); 55931055Sminshall } else if (IsPrint(outputString->array[0])) { 56031055Sminshall fprintf(stderr, 56131055Sminshall "first character of sequence for %s is not a control type character\n", 56231055Sminshall identifier); 56331055Sminshall return(0); 56431055Sminshall } else { 56531055Sminshall if ((head = PasteEntry(head, outputString->array, 56631055Sminshall outputString->length, identifier)) == 0) { 56731055Sminshall return(0); 56831055Sminshall } 56931055Sminshall GetWS(); 57031055Sminshall while ((outputString = GetQuotedString()) != 0) { 57131055Sminshall if ((head = PasteEntry(head, outputString->array, 57231055Sminshall outputString->length, identifier)) == 0) { 57331055Sminshall return(0); 57431055Sminshall } 57531055Sminshall GetWS(); 57631055Sminshall } 57731055Sminshall } 57831055Sminshall if (!doPaste) { 57931055Sminshall return(1); 58031055Sminshall } 58131245Sminshall if ((head->result != STATE_NULL) && (head->result != tc)) { 58231055Sminshall /* this means that this sequence is an initial part 58331055Sminshall * of a previously defined one. 58431055Sminshall */ 58531055Sminshall fprintf(stderr, "Conflicting entries found when scanning %s\n", 58631055Sminshall identifier); 58731055Sminshall return(0); 58831055Sminshall } else { 58931055Sminshall head->result = tc; 59031055Sminshall return(1); /* done */ 59131055Sminshall } 59231055Sminshall } 59331055Sminshall 59431055Sminshall static 59531055Sminshall GetDefinition() 59631055Sminshall { 59731055Sminshall stringWithLength *string; 59831055Sminshall int Tc; 59931055Sminshall 60031055Sminshall GetWS(); 60131055Sminshall if ((string = GetAlphaMericString()) == 0) { 60231055Sminshall return(0); 60331055Sminshall } 60431055Sminshall string->array[string->length] = 0; 60531055Sminshall if (doPaste) { 60631609Sminshall if ((Tc = (*GetTc)(string->array)) == -1) { 60731055Sminshall if (picky) { 60831055Sminshall fprintf(stderr, "%s: unknown 3270 key identifier\n", 60931055Sminshall string->array); 61031055Sminshall } 61131245Sminshall Tc = STATE_NULL; 61231055Sminshall } 61331055Sminshall } else { 61431245Sminshall Tc = STATE_NULL; /* XXX ? */ 61531055Sminshall } 61631055Sminshall GetWS(); 61731055Sminshall if (!GetCharacter('=')) { 61831055Sminshall fprintf(stderr, 61931055Sminshall "Required equal sign after 3270 key identifier %s missing\n", 62031055Sminshall string->array); 62131055Sminshall return(0); 62231055Sminshall } 62331055Sminshall GetWS(); 62431055Sminshall if (!GetInput(Tc, string->array)) { 62531055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 62631055Sminshall string->array); 62731055Sminshall return(0); 62831055Sminshall } else { 62931055Sminshall GetWS(); 63031055Sminshall while (GetCharacter('|')) { 63131055Sminshall # ifdef DEBUG 63231055Sminshall if (debug) { 63331055Sminshall fprintf(stderr, " or "); 63431055Sminshall } 63531055Sminshall # endif /* DEBUG */ 63631055Sminshall GetWS(); 63731055Sminshall if (!GetInput(Tc, string->array)) { 63831055Sminshall fprintf(stderr, "Missing definition part for 3270 key %s\n", 63931055Sminshall string->array); 64031055Sminshall return(0); 64131055Sminshall } 64231055Sminshall GetWS(); 64331055Sminshall } 64431055Sminshall } 64531055Sminshall GetWS(); 64631055Sminshall if (!GetCharacter(';')) { 64731055Sminshall fprintf(stderr, "Missing semi-colon for 3270 key %s\n", string->array); 64831055Sminshall return(0); 64931055Sminshall } 65031055Sminshall # ifdef DEBUG 65131055Sminshall if (debug) { 65231055Sminshall fprintf(stderr, ";\n"); 65331055Sminshall } 65431055Sminshall # endif /* DEBUG */ 65531055Sminshall return(1); 65631055Sminshall } 65731055Sminshall 65831055Sminshall 65931055Sminshall static 66031055Sminshall GetDefinitions() 66131055Sminshall { 66231055Sminshall if (!GetDefinition()) { 66331055Sminshall return(0); 66431055Sminshall } else { 66531055Sminshall while (GetDefinition()) { 66631055Sminshall ; 66731055Sminshall } 66831055Sminshall } 66931055Sminshall return(1); 67031055Sminshall } 67131055Sminshall 67231055Sminshall static 67331055Sminshall GetBegin() 67431055Sminshall { 67531055Sminshall GetWS(); 67631055Sminshall if (!GetCharacter('{')) { 67731055Sminshall return(0); 67831055Sminshall } 67931055Sminshall return(1); 68031055Sminshall } 68131055Sminshall 68231055Sminshall static 68331055Sminshall GetEnd() 68431055Sminshall { 68531055Sminshall GetWS(); 68631055Sminshall if (!GetCharacter('}')) { 68731055Sminshall return(0); 68831055Sminshall } 68931055Sminshall return(1); 69031055Sminshall } 69131055Sminshall 69231055Sminshall static 69331055Sminshall GetName() 69431055Sminshall { 69531055Sminshall if (!GetAlphaMericString()) { 69631055Sminshall return(0); 69731055Sminshall } 69831055Sminshall GetWS(); 69931055Sminshall while (GetAlphaMericString()) { 70031055Sminshall GetWS(); 70131055Sminshall } 70231055Sminshall return(1); 70331055Sminshall } 70431055Sminshall 70531055Sminshall static 70631055Sminshall GetNames() 70731055Sminshall { 70831055Sminshall GetWS(); 70931055Sminshall if (!GetName()) { 71031055Sminshall return(0); 71131055Sminshall } else { 71231055Sminshall GetWS(); 71331055Sminshall while (GetCharacter('|')) { 71431055Sminshall GetWS(); 71531055Sminshall if (!GetName()) { 71631055Sminshall return(0); 71731055Sminshall } 71831055Sminshall } 71931055Sminshall } 72031055Sminshall return(1); 72131055Sminshall } 72231055Sminshall 72331055Sminshall static 72431055Sminshall GetEntry0() 72531055Sminshall { 72631055Sminshall if (!GetBegin()) { 72731055Sminshall fprintf(stderr, "no '{'\n"); 72831055Sminshall return(0); 72931055Sminshall } else if (!GetDefinitions()) { 73031055Sminshall fprintf(stderr, "unable to parse the definitions\n"); 73131055Sminshall return(0); 73231055Sminshall } else if (!GetEnd()) { 73331055Sminshall fprintf(stderr, "No '}' or scanning stopped early due to error.\n"); 73431055Sminshall return(0); 73531055Sminshall } else { 73631055Sminshall /* done */ 73731055Sminshall return(1); 73831055Sminshall } 73931055Sminshall } 74031055Sminshall 74131055Sminshall 74231055Sminshall static 74331055Sminshall GetEntry() 74431055Sminshall { 74531055Sminshall if (!GetNames()) { 74631055Sminshall fprintf(stderr, "Invalid name field in entry.\n"); 74731055Sminshall return(0); 74831055Sminshall } else { 74931055Sminshall return(GetEntry0()); 75031055Sminshall } 75131055Sminshall } 75231055Sminshall 75331055Sminshall /* position ourselves within a given filename to the entry for the current 75431055Sminshall * KEYBD (or TERM) variable 75531055Sminshall */ 75631055Sminshall 75731055Sminshall Position(filename, keybdPointer) 75831055Sminshall char *filename; 75931055Sminshall char *keybdPointer; 76031055Sminshall { 76131055Sminshall lexicon lex; 76231055Sminshall stringWithLength *name = 0; 76331055Sminshall stringWithLength *oldName; 76431055Sminshall # define Return(x) {doPaste = 1; return(x);} 76531055Sminshall 76631055Sminshall doPaste = 0; 76731055Sminshall 76831055Sminshall if ((ourFile = fopen(filename, "r")) == NULL) { 76931100Sminshall # if !defined(MSDOS) 77031055Sminshall fprintf(stderr, "Unable to open file %s\n", filename); 77131100Sminshall # endif /* !defined(MSDOS) */ 77231055Sminshall Return(0); 77331055Sminshall } 77431055Sminshall lex = Get(); 77531055Sminshall while (lex.type != LEX_END_OF_FILE) { 77631055Sminshall UnGet(lex); 77731055Sminshall /* now, find an entry that is our type. */ 77831055Sminshall GetWS(); 77931055Sminshall oldName = name; 78031055Sminshall if ((name = GetAlphaMericString()) != 0) { 78131055Sminshall if (!ustrcmp(name->array, keybdPointer)) { 78231055Sminshall /* need to make sure there is a name here... */ 78331055Sminshall lex.type = LEX_CHAR; 78431055Sminshall lex.value = 'a'; 78531055Sminshall UnGet(lex); 78631055Sminshall Return(1); 78731055Sminshall } 78831055Sminshall } else if (GetCharacter('|')) { 78931055Sminshall ; /* more names coming */ 79031055Sminshall } else { 79131055Sminshall lex = Get(); 79231055Sminshall UnGet(lex); 79331055Sminshall if (lex.type != LEX_END_OF_FILE) { 79431055Sminshall if (!GetEntry0()) { /* start of an entry */ 79531055Sminshall fprintf(stderr, 79631055Sminshall "error was in entry for %s in file %s\n", 79731055Sminshall (oldName)? oldName->array:"(unknown)", filename); 79831055Sminshall Return(0); 79931055Sminshall } 80031055Sminshall } 80131055Sminshall } 80231055Sminshall lex = Get(); 80331055Sminshall } 80431100Sminshall #if !defined(MSDOS) 80531055Sminshall fprintf(stderr, "Unable to find entry for %s in file %s\n", keybdPointer, 80631055Sminshall filename); 80731100Sminshall #endif /* !defined(MSDOS) */ 80831055Sminshall Return(0); 80931055Sminshall } 81031055Sminshall 81131055Sminshall char * 81231055Sminshall strsave(string) 81331055Sminshall char *string; 81431055Sminshall { 81531055Sminshall char *p; 81631055Sminshall extern char *malloc(); 81731055Sminshall 81831055Sminshall p = malloc(strlen(string)+1); 81931055Sminshall if (p != 0) { 82031055Sminshall strcpy(p, string); 82131055Sminshall } 82231055Sminshall return(p); 82331055Sminshall } 82431055Sminshall 82531055Sminshall 82631055Sminshall /* 82731055Sminshall * InitControl - our interface to the outside. What we should 82831055Sminshall * do is figure out keyboard (or terminal) type, set up file pointer 82931055Sminshall * (or string pointer), etc. 83031055Sminshall */ 83131055Sminshall 83231055Sminshall state * 83331245Sminshall InitControl(keybdPointer, pickyarg, translator) 83431055Sminshall char *keybdPointer; 83531055Sminshall int pickyarg; /* Should we be picky? */ 83631245Sminshall int (*translator)(); /* Translates ascii string to integer */ 83731055Sminshall { 83831055Sminshall extern char *getenv(); 83931055Sminshall int GotIt; 84031055Sminshall 84131055Sminshall picky = pickyarg; 84231245Sminshall GetTc = translator; 84331055Sminshall 84431055Sminshall if (keybdPointer == 0) { 84531055Sminshall keybdPointer = getenv("KEYBD"); 84631055Sminshall } 84731055Sminshall if (keybdPointer == 0) { 84831055Sminshall keybdPointer = getenv("TERM"); 84931055Sminshall } 85031055Sminshall 85131055Sminshall /* 85231055Sminshall * Some environments have getenv() return 85331055Sminshall * out of a static area. So, save the keyboard name. 85431055Sminshall */ 85531055Sminshall if (keybdPointer) { 85631055Sminshall keybdPointer = strsave(keybdPointer); 85731055Sminshall } 85831055Sminshall environPointer = getenv("MAP3270"); 85931055Sminshall if (environPointer 86031055Sminshall && (environPointer[0] != '/') 86131100Sminshall #if defined(MSDOS) 86231055Sminshall && (environPointer[0] != '\\') 86331100Sminshall #endif /* defined(MSDOS) */ 86431055Sminshall && (strncmp(keybdPointer, environPointer, 86531055Sminshall strlen(keybdPointer) != 0) 86631055Sminshall || (environPointer[strlen(keybdPointer)] != '{'))) /* } */ 86731055Sminshall { 86831055Sminshall environPointer = 0; 86931055Sminshall } 87031055Sminshall 87131055Sminshall if ((!environPointer) 87231100Sminshall #if defined(MSDOS) 87331055Sminshall || (*environPointer == '\\') 87431100Sminshall #endif /* defined(MSDOS) */ 87531055Sminshall || (*environPointer == '/')) { 87631055Sminshall usePointer = 0; 87731055Sminshall GotIt = 0; 87831055Sminshall if (!keybdPointer) { 87931100Sminshall #if !defined(MSDOS) 88031055Sminshall fprintf(stderr, "%s%s%s%s", 88131055Sminshall "Neither the KEYBD environment variable nor the TERM ", 88231055Sminshall "environment variable\n(one of which is needed to determine ", 88331055Sminshall "the type of keyboard you are using)\n", 88431055Sminshall "is set. To set it, say 'setenv KEYBD <type>'\n"); 88531100Sminshall #endif /* !defined(MSDOS) */ 88631055Sminshall } else { 88731055Sminshall if (environPointer) { 88831055Sminshall GotIt = Position(environPointer, keybdPointer); 88931055Sminshall } 89031055Sminshall if (!GotIt) { 89131055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 89231055Sminshall } 89331055Sminshall } 89431055Sminshall if (!GotIt) { 89531055Sminshall if (environPointer) { 89631055Sminshall GotIt = Position(environPointer, "unknown"); 89731055Sminshall } 89831055Sminshall if (!GotIt) { 89931055Sminshall GotIt = Position("/etc/map3270", keybdPointer); 90031055Sminshall } 90131055Sminshall } 90231055Sminshall if (!GotIt) { 90331100Sminshall #if !defined(MSDOS) 90431055Sminshall fprintf(stderr, "Using default key mappings.\n"); 90531100Sminshall #endif /* !defined(MSDOS) */ 90631055Sminshall usePointer = 1; /* flag use of non-file */ 90731135Sminshall whichkey = keysgeneric; 90831135Sminshall environPointer = *whichkey; /* use default table */ 90931055Sminshall } 91031055Sminshall } else { 91131055Sminshall usePointer = 1; 91231055Sminshall } 91331055Sminshall (void) GetEntry(); 91431055Sminshall return(firstentry.address); 91531055Sminshall } 916