1*779fc935Sceastha /* 2*779fc935Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*779fc935Sceastha * Use is subject to license terms. 4*779fc935Sceastha */ 5*779fc935Sceastha 67c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 77c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate /* 107c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 137c478bd9Sstevel@tonic-gate */ 147c478bd9Sstevel@tonic-gate 15*779fc935Sceastha #pragma ident "%Z%%M% %I% %E% SMI" 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate #include "e.h" 187c478bd9Sstevel@tonic-gate #include "e.def" 197c478bd9Sstevel@tonic-gate #include <locale.h> 207c478bd9Sstevel@tonic-gate 217c478bd9Sstevel@tonic-gate #define SSIZE 400 227c478bd9Sstevel@tonic-gate char token[SSIZE]; 237c478bd9Sstevel@tonic-gate int sp; 247c478bd9Sstevel@tonic-gate #define putbak(c) *ip++ = c; 257c478bd9Sstevel@tonic-gate #define PUSHBACK 300 /* maximum pushback characters */ 267c478bd9Sstevel@tonic-gate char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */ 277c478bd9Sstevel@tonic-gate char *ip = ibuf; 287c478bd9Sstevel@tonic-gate 29*779fc935Sceastha void define(int); 30*779fc935Sceastha void delim(void); 31*779fc935Sceastha void getstr(char *, int); 32*779fc935Sceastha void include(void); 33*779fc935Sceastha int openinfile(void); 34*779fc935Sceastha void pbstr(char *); 35*779fc935Sceastha void space(void); 36*779fc935Sceastha 37*779fc935Sceastha int 38*779fc935Sceastha gtc(void) 39*779fc935Sceastha { 407c478bd9Sstevel@tonic-gate loop: 417c478bd9Sstevel@tonic-gate if (ip > ibuf) 427c478bd9Sstevel@tonic-gate return (*--ip); /* already present */ 437c478bd9Sstevel@tonic-gate lastchar = getc(curfile); 447c478bd9Sstevel@tonic-gate if (lastchar == '\n') 457c478bd9Sstevel@tonic-gate linect++; 467c478bd9Sstevel@tonic-gate if (lastchar != EOF) 477c478bd9Sstevel@tonic-gate return (lastchar); 487c478bd9Sstevel@tonic-gate if (++ifile > svargc) { 497c478bd9Sstevel@tonic-gate return (EOF); 507c478bd9Sstevel@tonic-gate } 51*779fc935Sceastha (void) fclose(curfile); 527c478bd9Sstevel@tonic-gate linect = 1; 537c478bd9Sstevel@tonic-gate if (openinfile() == 0) 547c478bd9Sstevel@tonic-gate goto loop; 557c478bd9Sstevel@tonic-gate return (EOF); 567c478bd9Sstevel@tonic-gate } 577c478bd9Sstevel@tonic-gate /* 587c478bd9Sstevel@tonic-gate * open file indexed by ifile in svargv, return non zero if fail 597c478bd9Sstevel@tonic-gate */ 60*779fc935Sceastha int 61*779fc935Sceastha openinfile(void) 627c478bd9Sstevel@tonic-gate { 637c478bd9Sstevel@tonic-gate if (strcmp(svargv[ifile], "-") == 0) { 647c478bd9Sstevel@tonic-gate curfile = stdin; 657c478bd9Sstevel@tonic-gate return (0); 667c478bd9Sstevel@tonic-gate } else if ((curfile = fopen(svargv[ifile], "r")) != NULL) { 677c478bd9Sstevel@tonic-gate return (0); 687c478bd9Sstevel@tonic-gate } 697c478bd9Sstevel@tonic-gate error(FATAL, gettext("can't open file %s"), svargv[ifile]); 707c478bd9Sstevel@tonic-gate return (1); 717c478bd9Sstevel@tonic-gate } 727c478bd9Sstevel@tonic-gate 73*779fc935Sceastha void 74*779fc935Sceastha pbstr(char *str) 757c478bd9Sstevel@tonic-gate { 76*779fc935Sceastha char *p; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate p = str; 79*779fc935Sceastha while (*p++) 80*779fc935Sceastha ; 817c478bd9Sstevel@tonic-gate --p; 827c478bd9Sstevel@tonic-gate if (ip >= &ibuf[PUSHBACK]) 837c478bd9Sstevel@tonic-gate error(FATAL, gettext("pushback overflow")); 847c478bd9Sstevel@tonic-gate while (p > str) 857c478bd9Sstevel@tonic-gate putbak(*--p); 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate 88*779fc935Sceastha int 89*779fc935Sceastha yylex(void) 90*779fc935Sceastha { 91*779fc935Sceastha int c; 927c478bd9Sstevel@tonic-gate tbl *tp, *lookup(); 937c478bd9Sstevel@tonic-gate extern tbl **keytbl, **deftbl; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate beg: 967c478bd9Sstevel@tonic-gate while ((c = gtc()) == ' ' || c == '\n') 977c478bd9Sstevel@tonic-gate ; 987c478bd9Sstevel@tonic-gate yylval = c; 997c478bd9Sstevel@tonic-gate switch (c) { 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate case EOF: 1027c478bd9Sstevel@tonic-gate return (EOF); 1037c478bd9Sstevel@tonic-gate case '~': 1047c478bd9Sstevel@tonic-gate return (SPACE); 1057c478bd9Sstevel@tonic-gate case '^': 1067c478bd9Sstevel@tonic-gate return (THIN); 1077c478bd9Sstevel@tonic-gate case '\t': 1087c478bd9Sstevel@tonic-gate return (TAB); 1097c478bd9Sstevel@tonic-gate case '{': 1107c478bd9Sstevel@tonic-gate return ('{'); 1117c478bd9Sstevel@tonic-gate case '}': 1127c478bd9Sstevel@tonic-gate return ('}'); 1137c478bd9Sstevel@tonic-gate case '"': 1147c478bd9Sstevel@tonic-gate for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) { 1157c478bd9Sstevel@tonic-gate if (c == '\\') 1167c478bd9Sstevel@tonic-gate if ((c = gtc()) != '"') 1177c478bd9Sstevel@tonic-gate token[sp++] = '\\'; 1187c478bd9Sstevel@tonic-gate token[sp++] = c; 1197c478bd9Sstevel@tonic-gate if (sp >= SSIZE) 120*779fc935Sceastha error(FATAL, gettext( 121*779fc935Sceastha "quoted string %.20s... too long"), token); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate token[sp] = '\0'; 1247c478bd9Sstevel@tonic-gate yylval = (int)&token[0]; 1257c478bd9Sstevel@tonic-gate if (c == '\n') 1267c478bd9Sstevel@tonic-gate error(!FATAL, gettext("missing \" in %.20s"), token); 1277c478bd9Sstevel@tonic-gate return (QTEXT); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate if (c == righteq) 1307c478bd9Sstevel@tonic-gate return (EOF); 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate putbak(c); 1337c478bd9Sstevel@tonic-gate getstr(token, SSIZE); 1347c478bd9Sstevel@tonic-gate if (dbg) printf(".\tlex token = |%s|\n", token); 135*779fc935Sceastha if ((tp = lookup(deftbl, token, NULL)) != NULL) { 1367c478bd9Sstevel@tonic-gate putbak(' '); 1377c478bd9Sstevel@tonic-gate pbstr(tp->defn); 1387c478bd9Sstevel@tonic-gate putbak(' '); 1397c478bd9Sstevel@tonic-gate if (dbg) 1407c478bd9Sstevel@tonic-gate printf(".\tfound %s|=%s|\n", token, tp->defn); 141*779fc935Sceastha } else if ((tp = lookup(keytbl, token, NULL)) == NULL) { 1427c478bd9Sstevel@tonic-gate if (dbg) printf(".\t%s is not a keyword\n", token); 1437c478bd9Sstevel@tonic-gate return (CONTIG); 144*779fc935Sceastha } else if (tp->defn == (char *)DEFINE || 145*779fc935Sceastha tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE) 146*779fc935Sceastha define((int)tp->defn); 1477c478bd9Sstevel@tonic-gate else if (tp->defn == (char *)DELIM) 1487c478bd9Sstevel@tonic-gate delim(); 1497c478bd9Sstevel@tonic-gate else if (tp->defn == (char *)GSIZE) 1507c478bd9Sstevel@tonic-gate globsize(); 1517c478bd9Sstevel@tonic-gate else if (tp->defn == (char *)GFONT) 1527c478bd9Sstevel@tonic-gate globfont(); 1537c478bd9Sstevel@tonic-gate else if (tp->defn == (char *)INCLUDE) 1547c478bd9Sstevel@tonic-gate include(); 1557c478bd9Sstevel@tonic-gate else if (tp->defn == (char *)SPACE) 1567c478bd9Sstevel@tonic-gate space(); 1577c478bd9Sstevel@tonic-gate else { 1587c478bd9Sstevel@tonic-gate return ((int)tp->defn); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate goto beg; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 163*779fc935Sceastha void 164*779fc935Sceastha getstr(char *s, int n) 165*779fc935Sceastha { 166*779fc935Sceastha int c; 167*779fc935Sceastha char *p; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate p = s; 1707c478bd9Sstevel@tonic-gate while ((c = gtc()) == ' ' || c == '\n') 1717c478bd9Sstevel@tonic-gate ; 1727c478bd9Sstevel@tonic-gate if (c == EOF) { 1737c478bd9Sstevel@tonic-gate *s = 0; 1747c478bd9Sstevel@tonic-gate return; 1757c478bd9Sstevel@tonic-gate } 176*779fc935Sceastha while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' && 177*779fc935Sceastha c != '"' && c != '~' && c != '^' && c != righteq) { 1787c478bd9Sstevel@tonic-gate if (c == '\\') 1797c478bd9Sstevel@tonic-gate if ((c = gtc()) != '"') 1807c478bd9Sstevel@tonic-gate *p++ = '\\'; 1817c478bd9Sstevel@tonic-gate *p++ = c; 1827c478bd9Sstevel@tonic-gate if (--n <= 0) 1837c478bd9Sstevel@tonic-gate error(FATAL, gettext("token %.20s... too long"), s); 1847c478bd9Sstevel@tonic-gate c = gtc(); 1857c478bd9Sstevel@tonic-gate } 186*779fc935Sceastha if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' || 187*779fc935Sceastha c == '\t' || c == righteq) 1887c478bd9Sstevel@tonic-gate putbak(c); 1897c478bd9Sstevel@tonic-gate *p = '\0'; 1907c478bd9Sstevel@tonic-gate yylval = (int)s; 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 193*779fc935Sceastha int 194*779fc935Sceastha cstr(char *s, int quote, int maxs) 195*779fc935Sceastha { 1967c478bd9Sstevel@tonic-gate int del, c, i; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate s[0] = 0; 199*779fc935Sceastha while ((del = gtc()) == ' ' || del == '\t') 200*779fc935Sceastha ; 201*779fc935Sceastha if (quote) { 2027c478bd9Sstevel@tonic-gate for (i = 0; (c = gtc()) != del && c != EOF; ) { 2037c478bd9Sstevel@tonic-gate s[i++] = c; 2047c478bd9Sstevel@tonic-gate if (i >= maxs) 2057c478bd9Sstevel@tonic-gate return (1); /* disaster */ 2067c478bd9Sstevel@tonic-gate } 207*779fc935Sceastha } else { 2087c478bd9Sstevel@tonic-gate if (del == '\n') 2097c478bd9Sstevel@tonic-gate return (1); 2107c478bd9Sstevel@tonic-gate s[0] = del; 211*779fc935Sceastha for (i = 1; (c = gtc()) != ' ' && c != '\t' && 212*779fc935Sceastha c != '\n' && c != EOF; /* empty */) { 2137c478bd9Sstevel@tonic-gate s[i++] = c; 2147c478bd9Sstevel@tonic-gate if (i >= maxs) 2157c478bd9Sstevel@tonic-gate return (1); /* disaster */ 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate s[i] = '\0'; 2197c478bd9Sstevel@tonic-gate if (c == EOF) 2207c478bd9Sstevel@tonic-gate error(FATAL, gettext("Unexpected end of input at %.20s"), s); 2217c478bd9Sstevel@tonic-gate return (0); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 224*779fc935Sceastha void 225*779fc935Sceastha define(int type) 226*779fc935Sceastha { 2277c478bd9Sstevel@tonic-gate char *strsave(), *p1, *p2; 2287c478bd9Sstevel@tonic-gate tbl *lookup(); 2297c478bd9Sstevel@tonic-gate extern tbl **deftbl; 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate getstr(token, SSIZE); /* get name */ 2327c478bd9Sstevel@tonic-gate if (type != DEFINE) { 233*779fc935Sceastha (void) cstr(token, 1, SSIZE); /* skip the definition too */ 2347c478bd9Sstevel@tonic-gate return; 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate p1 = strsave(token); 2377c478bd9Sstevel@tonic-gate if (cstr(token, 1, SSIZE)) 238*779fc935Sceastha error(FATAL, gettext( 239*779fc935Sceastha "Unterminated definition at %.20s"), token); 2407c478bd9Sstevel@tonic-gate p2 = strsave(token); 241*779fc935Sceastha lookup(deftbl, p1, p2); 2427c478bd9Sstevel@tonic-gate if (dbg) printf(".\tname %s defined as %s\n", p1, p2); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate char *spaceval = NULL; 2467c478bd9Sstevel@tonic-gate 247*779fc935Sceastha void 248*779fc935Sceastha space(void) /* collect line of form "space amt" to replace \x in output */ 2497c478bd9Sstevel@tonic-gate { 2507c478bd9Sstevel@tonic-gate char *strsave(); 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate getstr(token, SSIZE); 2537c478bd9Sstevel@tonic-gate spaceval = strsave(token); 2547c478bd9Sstevel@tonic-gate if (dbg) printf(".\tsetting space to %s\n", token); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate 258*779fc935Sceastha char * 259*779fc935Sceastha strsave(char *s) 2607c478bd9Sstevel@tonic-gate { 2617c478bd9Sstevel@tonic-gate char *malloc(); 262*779fc935Sceastha char *q; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate q = malloc(strlen(s)+1); 2657c478bd9Sstevel@tonic-gate if (q == NULL) 2667c478bd9Sstevel@tonic-gate error(FATAL, gettext("out of space in strsave on %s"), s); 2677c478bd9Sstevel@tonic-gate strcpy(q, s); 2687c478bd9Sstevel@tonic-gate return (q); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 271*779fc935Sceastha void 272*779fc935Sceastha include(void) 273*779fc935Sceastha { 2747c478bd9Sstevel@tonic-gate error(!FATAL, gettext("Include not yet implemented")); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 277*779fc935Sceastha void 278*779fc935Sceastha delim(void) 279*779fc935Sceastha { 2807c478bd9Sstevel@tonic-gate yyval = eqnreg = 0; 2817c478bd9Sstevel@tonic-gate if (cstr(token, 0, SSIZE)) 2827c478bd9Sstevel@tonic-gate error(FATAL, gettext("Bizarre delimiters at %.20s"), token); 2837c478bd9Sstevel@tonic-gate lefteq = token[0]; 2847c478bd9Sstevel@tonic-gate righteq = token[1]; 2857c478bd9Sstevel@tonic-gate if (lefteq == 'o' && righteq == 'f') 2867c478bd9Sstevel@tonic-gate lefteq = righteq = '\0'; 2877c478bd9Sstevel@tonic-gate } 288