1779fc935Sceastha /*
2779fc935Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3779fc935Sceastha * Use is subject to license terms.
4779fc935Sceastha */
5779fc935Sceastha
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 */
14779fc935Sceastha
157c478bd9Sstevel@tonic-gate #include "e.h"
167c478bd9Sstevel@tonic-gate #include "e.def"
177c478bd9Sstevel@tonic-gate #include <locale.h>
187c478bd9Sstevel@tonic-gate
197c478bd9Sstevel@tonic-gate #define SSIZE 400
207c478bd9Sstevel@tonic-gate char token[SSIZE];
217c478bd9Sstevel@tonic-gate int sp;
227c478bd9Sstevel@tonic-gate #define putbak(c) *ip++ = c;
237c478bd9Sstevel@tonic-gate #define PUSHBACK 300 /* maximum pushback characters */
247c478bd9Sstevel@tonic-gate char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */
257c478bd9Sstevel@tonic-gate char *ip = ibuf;
267c478bd9Sstevel@tonic-gate
27*b5cda42eSceastha extern tbl *keytbl[];
28*b5cda42eSceastha extern tbl *deftbl[];
29*b5cda42eSceastha
30779fc935Sceastha void define(int);
31779fc935Sceastha void delim(void);
32779fc935Sceastha void getstr(char *, int);
33779fc935Sceastha void include(void);
34779fc935Sceastha int openinfile(void);
35779fc935Sceastha void pbstr(char *);
36779fc935Sceastha void space(void);
37779fc935Sceastha
38779fc935Sceastha int
gtc(void)39779fc935Sceastha gtc(void)
40779fc935Sceastha {
41779fc935Sceastha loop:
427c478bd9Sstevel@tonic-gate if (ip > ibuf)
43779fc935Sceastha return (*--ip); /* already present */
447c478bd9Sstevel@tonic-gate lastchar = getc(curfile);
45779fc935Sceastha if (lastchar == '\n')
467c478bd9Sstevel@tonic-gate linect++;
477c478bd9Sstevel@tonic-gate if (lastchar != EOF)
48779fc935Sceastha return (lastchar);
497c478bd9Sstevel@tonic-gate if (++ifile > svargc) {
50779fc935Sceastha return (EOF);
517c478bd9Sstevel@tonic-gate }
52779fc935Sceastha (void) fclose(curfile);
537c478bd9Sstevel@tonic-gate linect = 1;
547c478bd9Sstevel@tonic-gate if (openinfile() == 0)
557c478bd9Sstevel@tonic-gate goto loop;
56779fc935Sceastha return (EOF);
577c478bd9Sstevel@tonic-gate }
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate * open file indexed by ifile in svargv, return non zero if fail
607c478bd9Sstevel@tonic-gate */
61779fc935Sceastha int
openinfile(void)62779fc935Sceastha openinfile(void)
637c478bd9Sstevel@tonic-gate {
64779fc935Sceastha if (strcmp(svargv[ifile], "-") == 0) {
657c478bd9Sstevel@tonic-gate curfile = stdin;
66779fc935Sceastha return (0);
67779fc935Sceastha } else if ((curfile = fopen(svargv[ifile], "r")) != NULL) {
68779fc935Sceastha return (0);
697c478bd9Sstevel@tonic-gate }
707c478bd9Sstevel@tonic-gate error(FATAL, gettext("can't open file %s"), svargv[ifile]);
71779fc935Sceastha return (1);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate
74779fc935Sceastha void
pbstr(char * str)75779fc935Sceastha pbstr(char *str)
767c478bd9Sstevel@tonic-gate {
77779fc935Sceastha char *p;
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate p = str;
80779fc935Sceastha while (*p++)
81779fc935Sceastha ;
827c478bd9Sstevel@tonic-gate --p;
837c478bd9Sstevel@tonic-gate if (ip >= &ibuf[PUSHBACK])
84779fc935Sceastha error(FATAL, gettext("pushback overflow"));
857c478bd9Sstevel@tonic-gate while (p > str)
867c478bd9Sstevel@tonic-gate putbak(*--p);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate
89779fc935Sceastha int
yylex(void)90779fc935Sceastha yylex(void)
91779fc935Sceastha {
92779fc935Sceastha int c;
937c478bd9Sstevel@tonic-gate tbl *tp, *lookup();
947c478bd9Sstevel@tonic-gate
95779fc935Sceastha beg:
96779fc935Sceastha while ((c = gtc()) == ' ' || c == '\n')
977c478bd9Sstevel@tonic-gate ;
98779fc935Sceastha yylval = c;
99779fc935Sceastha switch (c) {
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate case EOF:
102779fc935Sceastha return (EOF);
1037c478bd9Sstevel@tonic-gate case '~':
104779fc935Sceastha return (SPACE);
1057c478bd9Sstevel@tonic-gate case '^':
106779fc935Sceastha return (THIN);
1077c478bd9Sstevel@tonic-gate case '\t':
108779fc935Sceastha return (TAB);
1097c478bd9Sstevel@tonic-gate case '{':
110779fc935Sceastha return ('{');
1117c478bd9Sstevel@tonic-gate case '}':
112779fc935Sceastha return ('}');
1137c478bd9Sstevel@tonic-gate case '"':
114779fc935Sceastha 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;
119779fc935Sceastha if (sp >= SSIZE)
120779fc935Sceastha error(FATAL, gettext(
121779fc935Sceastha "quoted string %.20s... too long"), token);
1227c478bd9Sstevel@tonic-gate }
123779fc935Sceastha token[sp] = '\0';
124779fc935Sceastha yylval = (int)&token[0];
1257c478bd9Sstevel@tonic-gate if (c == '\n')
1267c478bd9Sstevel@tonic-gate error(!FATAL, gettext("missing \" in %.20s"), token);
127779fc935Sceastha return (QTEXT);
1287c478bd9Sstevel@tonic-gate }
129779fc935Sceastha if (c == righteq)
130779fc935Sceastha return (EOF);
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate putbak(c);
1337c478bd9Sstevel@tonic-gate getstr(token, SSIZE);
134779fc935Sceastha if (dbg) printf(".\tlex token = |%s|\n", token);
135779fc935Sceastha 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);
141779fc935Sceastha } else if ((tp = lookup(keytbl, token, NULL)) == NULL) {
142779fc935Sceastha if (dbg) printf(".\t%s is not a keyword\n", token);
143779fc935Sceastha return (CONTIG);
144779fc935Sceastha } else if (tp->defn == (char *)DEFINE ||
145779fc935Sceastha tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE)
146779fc935Sceastha define((int)tp->defn);
147779fc935Sceastha else if (tp->defn == (char *)DELIM)
1487c478bd9Sstevel@tonic-gate delim();
149779fc935Sceastha else if (tp->defn == (char *)GSIZE)
1507c478bd9Sstevel@tonic-gate globsize();
151779fc935Sceastha else if (tp->defn == (char *)GFONT)
1527c478bd9Sstevel@tonic-gate globfont();
153779fc935Sceastha else if (tp->defn == (char *)INCLUDE)
1547c478bd9Sstevel@tonic-gate include();
155779fc935Sceastha else if (tp->defn == (char *)SPACE)
1567c478bd9Sstevel@tonic-gate space();
1577c478bd9Sstevel@tonic-gate else {
158779fc935Sceastha return ((int)tp->defn);
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate goto beg;
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate
163779fc935Sceastha void
getstr(char * s,int n)164779fc935Sceastha getstr(char *s, int n)
165779fc935Sceastha {
166779fc935Sceastha int c;
167779fc935Sceastha 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 }
176779fc935Sceastha while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' &&
177779fc935Sceastha 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 }
186779fc935Sceastha if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' ||
187779fc935Sceastha c == '\t' || c == righteq)
1887c478bd9Sstevel@tonic-gate putbak(c);
1897c478bd9Sstevel@tonic-gate *p = '\0';
190779fc935Sceastha yylval = (int)s;
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate
193779fc935Sceastha int
cstr(char * s,int quote,int maxs)194779fc935Sceastha cstr(char *s, int quote, int maxs)
195779fc935Sceastha {
1967c478bd9Sstevel@tonic-gate int del, c, i;
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate s[0] = 0;
199779fc935Sceastha while ((del = gtc()) == ' ' || del == '\t')
200779fc935Sceastha ;
201779fc935Sceastha if (quote) {
202779fc935Sceastha for (i = 0; (c = gtc()) != del && c != EOF; ) {
2037c478bd9Sstevel@tonic-gate s[i++] = c;
2047c478bd9Sstevel@tonic-gate if (i >= maxs)
205779fc935Sceastha return (1); /* disaster */
2067c478bd9Sstevel@tonic-gate }
207779fc935Sceastha } else {
2087c478bd9Sstevel@tonic-gate if (del == '\n')
2097c478bd9Sstevel@tonic-gate return (1);
2107c478bd9Sstevel@tonic-gate s[0] = del;
211779fc935Sceastha for (i = 1; (c = gtc()) != ' ' && c != '\t' &&
212779fc935Sceastha c != '\n' && c != EOF; /* empty */) {
213779fc935Sceastha s[i++] = c;
2147c478bd9Sstevel@tonic-gate if (i >= maxs)
215779fc935Sceastha 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);
221779fc935Sceastha return (0);
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate
224779fc935Sceastha void
define(int type)225779fc935Sceastha define(int type)
226779fc935Sceastha {
2277c478bd9Sstevel@tonic-gate char *strsave(), *p1, *p2;
2287c478bd9Sstevel@tonic-gate tbl *lookup();
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate getstr(token, SSIZE); /* get name */
2317c478bd9Sstevel@tonic-gate if (type != DEFINE) {
232779fc935Sceastha (void) cstr(token, 1, SSIZE); /* skip the definition too */
2337c478bd9Sstevel@tonic-gate return;
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate p1 = strsave(token);
2367c478bd9Sstevel@tonic-gate if (cstr(token, 1, SSIZE))
237779fc935Sceastha error(FATAL, gettext(
238779fc935Sceastha "Unterminated definition at %.20s"), token);
2397c478bd9Sstevel@tonic-gate p2 = strsave(token);
240779fc935Sceastha lookup(deftbl, p1, p2);
241779fc935Sceastha if (dbg) printf(".\tname %s defined as %s\n", p1, p2);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate char *spaceval = NULL;
2457c478bd9Sstevel@tonic-gate
246779fc935Sceastha void
space(void)247779fc935Sceastha space(void) /* collect line of form "space amt" to replace \x in output */
2487c478bd9Sstevel@tonic-gate {
2497c478bd9Sstevel@tonic-gate char *strsave();
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate getstr(token, SSIZE);
2527c478bd9Sstevel@tonic-gate spaceval = strsave(token);
2537c478bd9Sstevel@tonic-gate if (dbg) printf(".\tsetting space to %s\n", token);
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate
257779fc935Sceastha char *
strsave(char * s)258779fc935Sceastha strsave(char *s)
2597c478bd9Sstevel@tonic-gate {
2607c478bd9Sstevel@tonic-gate char *malloc();
261779fc935Sceastha char *q;
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate q = malloc(strlen(s)+1);
2647c478bd9Sstevel@tonic-gate if (q == NULL)
2657c478bd9Sstevel@tonic-gate error(FATAL, gettext("out of space in strsave on %s"), s);
2667c478bd9Sstevel@tonic-gate strcpy(q, s);
267779fc935Sceastha return (q);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate
270779fc935Sceastha void
include(void)271779fc935Sceastha include(void)
272779fc935Sceastha {
2737c478bd9Sstevel@tonic-gate error(!FATAL, gettext("Include not yet implemented"));
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate
276779fc935Sceastha void
delim(void)277779fc935Sceastha delim(void)
278779fc935Sceastha {
2797c478bd9Sstevel@tonic-gate yyval = eqnreg = 0;
2807c478bd9Sstevel@tonic-gate if (cstr(token, 0, SSIZE))
2817c478bd9Sstevel@tonic-gate error(FATAL, gettext("Bizarre delimiters at %.20s"), token);
2827c478bd9Sstevel@tonic-gate lefteq = token[0];
2837c478bd9Sstevel@tonic-gate righteq = token[1];
2847c478bd9Sstevel@tonic-gate if (lefteq == 'o' && righteq == 'f')
2857c478bd9Sstevel@tonic-gate lefteq = righteq = '\0';
2867c478bd9Sstevel@tonic-gate }
287