1364Sceastha /*
2364Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3364Sceastha * Use is subject to license terms.
4364Sceastha */
5364Sceastha
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 */
14364Sceastha
15364Sceastha #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*413Sceastha extern tbl *keytbl[];
30*413Sceastha extern tbl *deftbl[];
31*413Sceastha
32364Sceastha void define(int);
33364Sceastha void delim(void);
34364Sceastha void getstr(char *, int);
35364Sceastha void include(void);
36364Sceastha int openinfile(void);
37364Sceastha void pbstr(char *);
38364Sceastha void space(void);
39364Sceastha
40364Sceastha int
gtc(void)41364Sceastha gtc(void)
42364Sceastha {
43364Sceastha loop:
440Sstevel@tonic-gate if (ip > ibuf)
45364Sceastha return (*--ip); /* already present */
460Sstevel@tonic-gate lastchar = getc(curfile);
47364Sceastha if (lastchar == '\n')
480Sstevel@tonic-gate linect++;
490Sstevel@tonic-gate if (lastchar != EOF)
50364Sceastha return (lastchar);
510Sstevel@tonic-gate if (++ifile > svargc) {
52364Sceastha return (EOF);
530Sstevel@tonic-gate }
54364Sceastha (void) fclose(curfile);
550Sstevel@tonic-gate linect = 1;
560Sstevel@tonic-gate if (openinfile() == 0)
570Sstevel@tonic-gate goto loop;
58364Sceastha return (EOF);
590Sstevel@tonic-gate }
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate * open file indexed by ifile in svargv, return non zero if fail
620Sstevel@tonic-gate */
63364Sceastha int
openinfile(void)64364Sceastha openinfile(void)
650Sstevel@tonic-gate {
66364Sceastha if (strcmp(svargv[ifile], "-") == 0) {
670Sstevel@tonic-gate curfile = stdin;
68364Sceastha return (0);
69364Sceastha } else if ((curfile = fopen(svargv[ifile], "r")) != NULL) {
70364Sceastha return (0);
710Sstevel@tonic-gate }
720Sstevel@tonic-gate error(FATAL, gettext("can't open file %s"), svargv[ifile]);
73364Sceastha return (1);
740Sstevel@tonic-gate }
750Sstevel@tonic-gate
76364Sceastha void
pbstr(char * str)77364Sceastha pbstr(char *str)
780Sstevel@tonic-gate {
79364Sceastha char *p;
800Sstevel@tonic-gate
810Sstevel@tonic-gate p = str;
82364Sceastha while (*p++)
83364Sceastha ;
840Sstevel@tonic-gate --p;
850Sstevel@tonic-gate if (ip >= &ibuf[PUSHBACK])
86364Sceastha error(FATAL, gettext("pushback overflow"));
870Sstevel@tonic-gate while (p > str)
880Sstevel@tonic-gate putbak(*--p);
890Sstevel@tonic-gate }
900Sstevel@tonic-gate
91364Sceastha int
yylex(void)92364Sceastha yylex(void)
93364Sceastha {
94364Sceastha int c;
950Sstevel@tonic-gate tbl *tp, *lookup();
960Sstevel@tonic-gate
97364Sceastha beg:
98364Sceastha while ((c = gtc()) == ' ' || c == '\n')
990Sstevel@tonic-gate ;
100364Sceastha yylval = c;
101364Sceastha switch (c) {
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate case EOF:
104364Sceastha return (EOF);
1050Sstevel@tonic-gate case '~':
106364Sceastha return (SPACE);
1070Sstevel@tonic-gate case '^':
108364Sceastha return (THIN);
1090Sstevel@tonic-gate case '\t':
110364Sceastha return (TAB);
1110Sstevel@tonic-gate case '{':
112364Sceastha return ('{');
1130Sstevel@tonic-gate case '}':
114364Sceastha return ('}');
1150Sstevel@tonic-gate case '"':
116364Sceastha for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) {
1170Sstevel@tonic-gate if (c == '\\')
1180Sstevel@tonic-gate if ((c = gtc()) != '"')
1190Sstevel@tonic-gate token[sp++] = '\\';
1200Sstevel@tonic-gate token[sp++] = c;
121364Sceastha if (sp >= SSIZE)
122364Sceastha error(FATAL, gettext(
123364Sceastha "quoted string %.20s... too long"), token);
1240Sstevel@tonic-gate }
125364Sceastha token[sp] = '\0';
126364Sceastha yylval = (int)&token[0];
1270Sstevel@tonic-gate if (c == '\n')
1280Sstevel@tonic-gate error(!FATAL, gettext("missing \" in %.20s"), token);
129364Sceastha return (QTEXT);
1300Sstevel@tonic-gate }
131364Sceastha if (c == righteq)
132364Sceastha return (EOF);
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate putbak(c);
1350Sstevel@tonic-gate getstr(token, SSIZE);
136364Sceastha if (dbg) printf(".\tlex token = |%s|\n", token);
137364Sceastha if ((tp = lookup(deftbl, token, NULL)) != NULL) {
1380Sstevel@tonic-gate putbak(' ');
1390Sstevel@tonic-gate pbstr(tp->defn);
1400Sstevel@tonic-gate putbak(' ');
1410Sstevel@tonic-gate if (dbg)
1420Sstevel@tonic-gate printf(".\tfound %s|=%s|\n", token, tp->defn);
143364Sceastha } else if ((tp = lookup(keytbl, token, NULL)) == NULL) {
144364Sceastha if (dbg) printf(".\t%s is not a keyword\n", token);
145364Sceastha return (CONTIG);
146364Sceastha } else if (tp->defn == (char *)DEFINE ||
147364Sceastha tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE)
148364Sceastha define((int)tp->defn);
149364Sceastha else if (tp->defn == (char *)DELIM)
1500Sstevel@tonic-gate delim();
151364Sceastha else if (tp->defn == (char *)GSIZE)
1520Sstevel@tonic-gate globsize();
153364Sceastha else if (tp->defn == (char *)GFONT)
1540Sstevel@tonic-gate globfont();
155364Sceastha else if (tp->defn == (char *)INCLUDE)
1560Sstevel@tonic-gate include();
157364Sceastha else if (tp->defn == (char *)SPACE)
1580Sstevel@tonic-gate space();
1590Sstevel@tonic-gate else {
160364Sceastha return ((int)tp->defn);
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate goto beg;
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate
165364Sceastha void
getstr(char * s,int n)166364Sceastha getstr(char *s, int n)
167364Sceastha {
168364Sceastha int c;
169364Sceastha char *p;
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate p = s;
1720Sstevel@tonic-gate while ((c = gtc()) == ' ' || c == '\n')
1730Sstevel@tonic-gate ;
1740Sstevel@tonic-gate if (c == EOF) {
1750Sstevel@tonic-gate *s = 0;
1760Sstevel@tonic-gate return;
1770Sstevel@tonic-gate }
178364Sceastha while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' &&
179364Sceastha c != '"' && c != '~' && c != '^' && c != righteq) {
1800Sstevel@tonic-gate if (c == '\\')
1810Sstevel@tonic-gate if ((c = gtc()) != '"')
1820Sstevel@tonic-gate *p++ = '\\';
1830Sstevel@tonic-gate *p++ = c;
1840Sstevel@tonic-gate if (--n <= 0)
1850Sstevel@tonic-gate error(FATAL, gettext("token %.20s... too long"), s);
1860Sstevel@tonic-gate c = gtc();
1870Sstevel@tonic-gate }
188364Sceastha if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' ||
189364Sceastha c == '\t' || c == righteq)
1900Sstevel@tonic-gate putbak(c);
1910Sstevel@tonic-gate *p = '\0';
192364Sceastha yylval = (int)s;
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate
195364Sceastha int
cstr(char * s,int quote,int maxs)196364Sceastha cstr(char *s, int quote, int maxs)
197364Sceastha {
1980Sstevel@tonic-gate int del, c, i;
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate s[0] = 0;
201364Sceastha while ((del = gtc()) == ' ' || del == '\t')
202364Sceastha ;
203364Sceastha if (quote) {
204364Sceastha for (i = 0; (c = gtc()) != del && c != EOF; ) {
2050Sstevel@tonic-gate s[i++] = c;
2060Sstevel@tonic-gate if (i >= maxs)
207364Sceastha return (1); /* disaster */
2080Sstevel@tonic-gate }
209364Sceastha } else {
2100Sstevel@tonic-gate if (del == '\n')
2110Sstevel@tonic-gate return (1);
2120Sstevel@tonic-gate s[0] = del;
213364Sceastha for (i = 1; (c = gtc()) != ' ' && c != '\t' &&
214364Sceastha c != '\n' && c != EOF; /* empty */) {
215364Sceastha s[i++] = c;
2160Sstevel@tonic-gate if (i >= maxs)
217364Sceastha return (1); /* disaster */
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate s[i] = '\0';
2210Sstevel@tonic-gate if (c == EOF)
2220Sstevel@tonic-gate error(FATAL, gettext("Unexpected end of input at %.20s"), s);
223364Sceastha return (0);
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate
226364Sceastha void
define(int type)227364Sceastha define(int type)
228364Sceastha {
2290Sstevel@tonic-gate char *strsave(), *p1, *p2;
2300Sstevel@tonic-gate tbl *lookup();
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate getstr(token, SSIZE); /* get name */
2330Sstevel@tonic-gate if (type != DEFINE) {
234364Sceastha (void) cstr(token, 1, SSIZE); /* skip the definition too */
2350Sstevel@tonic-gate return;
2360Sstevel@tonic-gate }
2370Sstevel@tonic-gate p1 = strsave(token);
2380Sstevel@tonic-gate if (cstr(token, 1, SSIZE))
239364Sceastha error(FATAL, gettext(
240364Sceastha "Unterminated definition at %.20s"), token);
2410Sstevel@tonic-gate p2 = strsave(token);
242364Sceastha lookup(deftbl, p1, p2);
243364Sceastha if (dbg) printf(".\tname %s defined as %s\n", p1, p2);
2440Sstevel@tonic-gate }
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate char *spaceval = NULL;
2470Sstevel@tonic-gate
248364Sceastha void
space(void)249364Sceastha space(void) /* collect line of form "space amt" to replace \x in output */
2500Sstevel@tonic-gate {
2510Sstevel@tonic-gate char *strsave();
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate getstr(token, SSIZE);
2540Sstevel@tonic-gate spaceval = strsave(token);
2550Sstevel@tonic-gate if (dbg) printf(".\tsetting space to %s\n", token);
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate
259364Sceastha char *
strsave(char * s)260364Sceastha strsave(char *s)
2610Sstevel@tonic-gate {
2620Sstevel@tonic-gate char *malloc();
263364Sceastha char *q;
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate q = malloc(strlen(s)+1);
2660Sstevel@tonic-gate if (q == NULL)
2670Sstevel@tonic-gate error(FATAL, gettext("out of space in strsave on %s"), s);
2680Sstevel@tonic-gate strcpy(q, s);
269364Sceastha return (q);
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate
272364Sceastha void
include(void)273364Sceastha include(void)
274364Sceastha {
2750Sstevel@tonic-gate error(!FATAL, gettext("Include not yet implemented"));
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate
278364Sceastha void
delim(void)279364Sceastha delim(void)
280364Sceastha {
2810Sstevel@tonic-gate yyval = eqnreg = 0;
2820Sstevel@tonic-gate if (cstr(token, 0, SSIZE))
2830Sstevel@tonic-gate error(FATAL, gettext("Bizarre delimiters at %.20s"), token);
2840Sstevel@tonic-gate lefteq = token[0];
2850Sstevel@tonic-gate righteq = token[1];
2860Sstevel@tonic-gate if (lefteq == 'o' && righteq == 'f')
2870Sstevel@tonic-gate lefteq = righteq = '\0';
2880Sstevel@tonic-gate }
289