1*364Sceastha /* 2*364Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*364Sceastha * Use is subject to license terms. 4*364Sceastha */ 5*364Sceastha 60Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 70Sstevel@tonic-gate /* All Rights Reserved */ 80Sstevel@tonic-gate 90Sstevel@tonic-gate /* 100Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 110Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 120Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 130Sstevel@tonic-gate */ 14*364Sceastha 15*364Sceastha #pragma ident "%Z%%M% %I% %E% SMI" 160Sstevel@tonic-gate 170Sstevel@tonic-gate #include "e.h" 180Sstevel@tonic-gate #include "e.def" 190Sstevel@tonic-gate #include <locale.h> 200Sstevel@tonic-gate 210Sstevel@tonic-gate #define SSIZE 400 220Sstevel@tonic-gate char token[SSIZE]; 230Sstevel@tonic-gate int sp; 240Sstevel@tonic-gate #define putbak(c) *ip++ = c; 250Sstevel@tonic-gate #define PUSHBACK 300 /* maximum pushback characters */ 260Sstevel@tonic-gate char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */ 270Sstevel@tonic-gate char *ip = ibuf; 280Sstevel@tonic-gate 29*364Sceastha void define(int); 30*364Sceastha void delim(void); 31*364Sceastha void getstr(char *, int); 32*364Sceastha void include(void); 33*364Sceastha int openinfile(void); 34*364Sceastha void pbstr(char *); 35*364Sceastha void space(void); 36*364Sceastha 37*364Sceastha int 38*364Sceastha gtc(void) 39*364Sceastha { 40*364Sceastha loop: 410Sstevel@tonic-gate if (ip > ibuf) 42*364Sceastha return (*--ip); /* already present */ 430Sstevel@tonic-gate lastchar = getc(curfile); 44*364Sceastha if (lastchar == '\n') 450Sstevel@tonic-gate linect++; 460Sstevel@tonic-gate if (lastchar != EOF) 47*364Sceastha return (lastchar); 480Sstevel@tonic-gate if (++ifile > svargc) { 49*364Sceastha return (EOF); 500Sstevel@tonic-gate } 51*364Sceastha (void) fclose(curfile); 520Sstevel@tonic-gate linect = 1; 530Sstevel@tonic-gate if (openinfile() == 0) 540Sstevel@tonic-gate goto loop; 55*364Sceastha return (EOF); 560Sstevel@tonic-gate } 570Sstevel@tonic-gate /* 580Sstevel@tonic-gate * open file indexed by ifile in svargv, return non zero if fail 590Sstevel@tonic-gate */ 60*364Sceastha int 61*364Sceastha openinfile(void) 620Sstevel@tonic-gate { 63*364Sceastha if (strcmp(svargv[ifile], "-") == 0) { 640Sstevel@tonic-gate curfile = stdin; 65*364Sceastha return (0); 66*364Sceastha } else if ((curfile = fopen(svargv[ifile], "r")) != NULL) { 67*364Sceastha return (0); 680Sstevel@tonic-gate } 690Sstevel@tonic-gate error(FATAL, gettext("can't open file %s"), svargv[ifile]); 70*364Sceastha return (1); 710Sstevel@tonic-gate } 720Sstevel@tonic-gate 73*364Sceastha void 74*364Sceastha pbstr(char *str) 750Sstevel@tonic-gate { 76*364Sceastha char *p; 770Sstevel@tonic-gate 780Sstevel@tonic-gate p = str; 79*364Sceastha while (*p++) 80*364Sceastha ; 810Sstevel@tonic-gate --p; 820Sstevel@tonic-gate if (ip >= &ibuf[PUSHBACK]) 83*364Sceastha error(FATAL, gettext("pushback overflow")); 840Sstevel@tonic-gate while (p > str) 850Sstevel@tonic-gate putbak(*--p); 860Sstevel@tonic-gate } 870Sstevel@tonic-gate 88*364Sceastha int 89*364Sceastha yylex(void) 90*364Sceastha { 91*364Sceastha int c; 920Sstevel@tonic-gate tbl *tp, *lookup(); 930Sstevel@tonic-gate extern tbl **keytbl, **deftbl; 940Sstevel@tonic-gate 95*364Sceastha beg: 96*364Sceastha while ((c = gtc()) == ' ' || c == '\n') 970Sstevel@tonic-gate ; 98*364Sceastha yylval = c; 99*364Sceastha switch (c) { 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate case EOF: 102*364Sceastha return (EOF); 1030Sstevel@tonic-gate case '~': 104*364Sceastha return (SPACE); 1050Sstevel@tonic-gate case '^': 106*364Sceastha return (THIN); 1070Sstevel@tonic-gate case '\t': 108*364Sceastha return (TAB); 1090Sstevel@tonic-gate case '{': 110*364Sceastha return ('{'); 1110Sstevel@tonic-gate case '}': 112*364Sceastha return ('}'); 1130Sstevel@tonic-gate case '"': 114*364Sceastha for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) { 1150Sstevel@tonic-gate if (c == '\\') 1160Sstevel@tonic-gate if ((c = gtc()) != '"') 1170Sstevel@tonic-gate token[sp++] = '\\'; 1180Sstevel@tonic-gate token[sp++] = c; 119*364Sceastha if (sp >= SSIZE) 120*364Sceastha error(FATAL, gettext( 121*364Sceastha "quoted string %.20s... too long"), token); 1220Sstevel@tonic-gate } 123*364Sceastha token[sp] = '\0'; 124*364Sceastha yylval = (int)&token[0]; 1250Sstevel@tonic-gate if (c == '\n') 1260Sstevel@tonic-gate error(!FATAL, gettext("missing \" in %.20s"), token); 127*364Sceastha return (QTEXT); 1280Sstevel@tonic-gate } 129*364Sceastha if (c == righteq) 130*364Sceastha return (EOF); 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate putbak(c); 1330Sstevel@tonic-gate getstr(token, SSIZE); 134*364Sceastha if (dbg) printf(".\tlex token = |%s|\n", token); 135*364Sceastha if ((tp = lookup(deftbl, token, NULL)) != NULL) { 1360Sstevel@tonic-gate putbak(' '); 1370Sstevel@tonic-gate pbstr(tp->defn); 1380Sstevel@tonic-gate putbak(' '); 1390Sstevel@tonic-gate if (dbg) 1400Sstevel@tonic-gate printf(".\tfound %s|=%s|\n", token, tp->defn); 141*364Sceastha } else if ((tp = lookup(keytbl, token, NULL)) == NULL) { 142*364Sceastha if (dbg) printf(".\t%s is not a keyword\n", token); 143*364Sceastha return (CONTIG); 144*364Sceastha } else if (tp->defn == (char *)DEFINE || 145*364Sceastha tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE) 146*364Sceastha define((int)tp->defn); 147*364Sceastha else if (tp->defn == (char *)DELIM) 1480Sstevel@tonic-gate delim(); 149*364Sceastha else if (tp->defn == (char *)GSIZE) 1500Sstevel@tonic-gate globsize(); 151*364Sceastha else if (tp->defn == (char *)GFONT) 1520Sstevel@tonic-gate globfont(); 153*364Sceastha else if (tp->defn == (char *)INCLUDE) 1540Sstevel@tonic-gate include(); 155*364Sceastha else if (tp->defn == (char *)SPACE) 1560Sstevel@tonic-gate space(); 1570Sstevel@tonic-gate else { 158*364Sceastha return ((int)tp->defn); 1590Sstevel@tonic-gate } 1600Sstevel@tonic-gate goto beg; 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate 163*364Sceastha void 164*364Sceastha getstr(char *s, int n) 165*364Sceastha { 166*364Sceastha int c; 167*364Sceastha char *p; 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate p = s; 1700Sstevel@tonic-gate while ((c = gtc()) == ' ' || c == '\n') 1710Sstevel@tonic-gate ; 1720Sstevel@tonic-gate if (c == EOF) { 1730Sstevel@tonic-gate *s = 0; 1740Sstevel@tonic-gate return; 1750Sstevel@tonic-gate } 176*364Sceastha while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' && 177*364Sceastha c != '"' && c != '~' && c != '^' && c != righteq) { 1780Sstevel@tonic-gate if (c == '\\') 1790Sstevel@tonic-gate if ((c = gtc()) != '"') 1800Sstevel@tonic-gate *p++ = '\\'; 1810Sstevel@tonic-gate *p++ = c; 1820Sstevel@tonic-gate if (--n <= 0) 1830Sstevel@tonic-gate error(FATAL, gettext("token %.20s... too long"), s); 1840Sstevel@tonic-gate c = gtc(); 1850Sstevel@tonic-gate } 186*364Sceastha if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' || 187*364Sceastha c == '\t' || c == righteq) 1880Sstevel@tonic-gate putbak(c); 1890Sstevel@tonic-gate *p = '\0'; 190*364Sceastha yylval = (int)s; 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate 193*364Sceastha int 194*364Sceastha cstr(char *s, int quote, int maxs) 195*364Sceastha { 1960Sstevel@tonic-gate int del, c, i; 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate s[0] = 0; 199*364Sceastha while ((del = gtc()) == ' ' || del == '\t') 200*364Sceastha ; 201*364Sceastha if (quote) { 202*364Sceastha for (i = 0; (c = gtc()) != del && c != EOF; ) { 2030Sstevel@tonic-gate s[i++] = c; 2040Sstevel@tonic-gate if (i >= maxs) 205*364Sceastha return (1); /* disaster */ 2060Sstevel@tonic-gate } 207*364Sceastha } else { 2080Sstevel@tonic-gate if (del == '\n') 2090Sstevel@tonic-gate return (1); 2100Sstevel@tonic-gate s[0] = del; 211*364Sceastha for (i = 1; (c = gtc()) != ' ' && c != '\t' && 212*364Sceastha c != '\n' && c != EOF; /* empty */) { 213*364Sceastha s[i++] = c; 2140Sstevel@tonic-gate if (i >= maxs) 215*364Sceastha return (1); /* disaster */ 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate } 2180Sstevel@tonic-gate s[i] = '\0'; 2190Sstevel@tonic-gate if (c == EOF) 2200Sstevel@tonic-gate error(FATAL, gettext("Unexpected end of input at %.20s"), s); 221*364Sceastha return (0); 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate 224*364Sceastha void 225*364Sceastha define(int type) 226*364Sceastha { 2270Sstevel@tonic-gate char *strsave(), *p1, *p2; 2280Sstevel@tonic-gate tbl *lookup(); 2290Sstevel@tonic-gate extern tbl **deftbl; 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate getstr(token, SSIZE); /* get name */ 2320Sstevel@tonic-gate if (type != DEFINE) { 233*364Sceastha (void) cstr(token, 1, SSIZE); /* skip the definition too */ 2340Sstevel@tonic-gate return; 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate p1 = strsave(token); 2370Sstevel@tonic-gate if (cstr(token, 1, SSIZE)) 238*364Sceastha error(FATAL, gettext( 239*364Sceastha "Unterminated definition at %.20s"), token); 2400Sstevel@tonic-gate p2 = strsave(token); 241*364Sceastha lookup(deftbl, p1, p2); 242*364Sceastha if (dbg) printf(".\tname %s defined as %s\n", p1, p2); 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate char *spaceval = NULL; 2460Sstevel@tonic-gate 247*364Sceastha void 248*364Sceastha space(void) /* collect line of form "space amt" to replace \x in output */ 2490Sstevel@tonic-gate { 2500Sstevel@tonic-gate char *strsave(); 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate getstr(token, SSIZE); 2530Sstevel@tonic-gate spaceval = strsave(token); 2540Sstevel@tonic-gate if (dbg) printf(".\tsetting space to %s\n", token); 2550Sstevel@tonic-gate } 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate 258*364Sceastha char * 259*364Sceastha strsave(char *s) 2600Sstevel@tonic-gate { 2610Sstevel@tonic-gate char *malloc(); 262*364Sceastha char *q; 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate q = malloc(strlen(s)+1); 2650Sstevel@tonic-gate if (q == NULL) 2660Sstevel@tonic-gate error(FATAL, gettext("out of space in strsave on %s"), s); 2670Sstevel@tonic-gate strcpy(q, s); 268*364Sceastha return (q); 2690Sstevel@tonic-gate } 2700Sstevel@tonic-gate 271*364Sceastha void 272*364Sceastha include(void) 273*364Sceastha { 2740Sstevel@tonic-gate error(!FATAL, gettext("Include not yet implemented")); 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate 277*364Sceastha void 278*364Sceastha delim(void) 279*364Sceastha { 2800Sstevel@tonic-gate yyval = eqnreg = 0; 2810Sstevel@tonic-gate if (cstr(token, 0, SSIZE)) 2820Sstevel@tonic-gate error(FATAL, gettext("Bizarre delimiters at %.20s"), token); 2830Sstevel@tonic-gate lefteq = token[0]; 2840Sstevel@tonic-gate righteq = token[1]; 2850Sstevel@tonic-gate if (lefteq == 'o' && righteq == 'f') 2860Sstevel@tonic-gate lefteq = righteq = '\0'; 2870Sstevel@tonic-gate } 288