1 /*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
8
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
13 */
14
15 #include "e.h"
16 #include "e.def"
17 #include <locale.h>
18
19 #define SSIZE 400
20 char token[SSIZE];
21 int sp;
22 #define putbak(c) *ip++ = c;
23 #define PUSHBACK 300 /* maximum pushback characters */
24 char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */
25 char *ip = ibuf;
26
27 extern tbl *keytbl[];
28 extern tbl *deftbl[];
29
30 void define(int);
31 void delim(void);
32 void getstr(char *, int);
33 void include(void);
34 int openinfile(void);
35 void pbstr(char *);
36 void space(void);
37
38 int
gtc(void)39 gtc(void)
40 {
41 loop:
42 if (ip > ibuf)
43 return (*--ip); /* already present */
44 lastchar = getc(curfile);
45 if (lastchar == '\n')
46 linect++;
47 if (lastchar != EOF)
48 return (lastchar);
49 if (++ifile > svargc) {
50 return (EOF);
51 }
52 (void) fclose(curfile);
53 linect = 1;
54 if (openinfile() == 0)
55 goto loop;
56 return (EOF);
57 }
58 /*
59 * open file indexed by ifile in svargv, return non zero if fail
60 */
61 int
openinfile(void)62 openinfile(void)
63 {
64 if (strcmp(svargv[ifile], "-") == 0) {
65 curfile = stdin;
66 return (0);
67 } else if ((curfile = fopen(svargv[ifile], "r")) != NULL) {
68 return (0);
69 }
70 error(FATAL, gettext("can't open file %s"), svargv[ifile]);
71 return (1);
72 }
73
74 void
pbstr(char * str)75 pbstr(char *str)
76 {
77 char *p;
78
79 p = str;
80 while (*p++)
81 ;
82 --p;
83 if (ip >= &ibuf[PUSHBACK])
84 error(FATAL, gettext("pushback overflow"));
85 while (p > str)
86 putbak(*--p);
87 }
88
89 int
yylex(void)90 yylex(void)
91 {
92 int c;
93 tbl *tp, *lookup();
94
95 beg:
96 while ((c = gtc()) == ' ' || c == '\n')
97 ;
98 yylval = c;
99 switch (c) {
100
101 case EOF:
102 return (EOF);
103 case '~':
104 return (SPACE);
105 case '^':
106 return (THIN);
107 case '\t':
108 return (TAB);
109 case '{':
110 return ('{');
111 case '}':
112 return ('}');
113 case '"':
114 for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) {
115 if (c == '\\')
116 if ((c = gtc()) != '"')
117 token[sp++] = '\\';
118 token[sp++] = c;
119 if (sp >= SSIZE)
120 error(FATAL, gettext(
121 "quoted string %.20s... too long"), token);
122 }
123 token[sp] = '\0';
124 yylval = (int)&token[0];
125 if (c == '\n')
126 error(!FATAL, gettext("missing \" in %.20s"), token);
127 return (QTEXT);
128 }
129 if (c == righteq)
130 return (EOF);
131
132 putbak(c);
133 getstr(token, SSIZE);
134 if (dbg) printf(".\tlex token = |%s|\n", token);
135 if ((tp = lookup(deftbl, token, NULL)) != NULL) {
136 putbak(' ');
137 pbstr(tp->defn);
138 putbak(' ');
139 if (dbg)
140 printf(".\tfound %s|=%s|\n", token, tp->defn);
141 } else if ((tp = lookup(keytbl, token, NULL)) == NULL) {
142 if (dbg) printf(".\t%s is not a keyword\n", token);
143 return (CONTIG);
144 } else if (tp->defn == (char *)DEFINE ||
145 tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE)
146 define((int)tp->defn);
147 else if (tp->defn == (char *)DELIM)
148 delim();
149 else if (tp->defn == (char *)GSIZE)
150 globsize();
151 else if (tp->defn == (char *)GFONT)
152 globfont();
153 else if (tp->defn == (char *)INCLUDE)
154 include();
155 else if (tp->defn == (char *)SPACE)
156 space();
157 else {
158 return ((int)tp->defn);
159 }
160 goto beg;
161 }
162
163 void
getstr(char * s,int n)164 getstr(char *s, int n)
165 {
166 int c;
167 char *p;
168
169 p = s;
170 while ((c = gtc()) == ' ' || c == '\n')
171 ;
172 if (c == EOF) {
173 *s = 0;
174 return;
175 }
176 while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' &&
177 c != '"' && c != '~' && c != '^' && c != righteq) {
178 if (c == '\\')
179 if ((c = gtc()) != '"')
180 *p++ = '\\';
181 *p++ = c;
182 if (--n <= 0)
183 error(FATAL, gettext("token %.20s... too long"), s);
184 c = gtc();
185 }
186 if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' ||
187 c == '\t' || c == righteq)
188 putbak(c);
189 *p = '\0';
190 yylval = (int)s;
191 }
192
193 int
cstr(char * s,int quote,int maxs)194 cstr(char *s, int quote, int maxs)
195 {
196 int del, c, i;
197
198 s[0] = 0;
199 while ((del = gtc()) == ' ' || del == '\t')
200 ;
201 if (quote) {
202 for (i = 0; (c = gtc()) != del && c != EOF; ) {
203 s[i++] = c;
204 if (i >= maxs)
205 return (1); /* disaster */
206 }
207 } else {
208 if (del == '\n')
209 return (1);
210 s[0] = del;
211 for (i = 1; (c = gtc()) != ' ' && c != '\t' &&
212 c != '\n' && c != EOF; /* empty */) {
213 s[i++] = c;
214 if (i >= maxs)
215 return (1); /* disaster */
216 }
217 }
218 s[i] = '\0';
219 if (c == EOF)
220 error(FATAL, gettext("Unexpected end of input at %.20s"), s);
221 return (0);
222 }
223
224 void
define(int type)225 define(int type)
226 {
227 char *strsave(), *p1, *p2;
228 tbl *lookup();
229
230 getstr(token, SSIZE); /* get name */
231 if (type != DEFINE) {
232 (void) cstr(token, 1, SSIZE); /* skip the definition too */
233 return;
234 }
235 p1 = strsave(token);
236 if (cstr(token, 1, SSIZE))
237 error(FATAL, gettext(
238 "Unterminated definition at %.20s"), token);
239 p2 = strsave(token);
240 lookup(deftbl, p1, p2);
241 if (dbg) printf(".\tname %s defined as %s\n", p1, p2);
242 }
243
244 char *spaceval = NULL;
245
246 void
space(void)247 space(void) /* collect line of form "space amt" to replace \x in output */
248 {
249 char *strsave();
250
251 getstr(token, SSIZE);
252 spaceval = strsave(token);
253 if (dbg) printf(".\tsetting space to %s\n", token);
254 }
255
256
257 char *
strsave(char * s)258 strsave(char *s)
259 {
260 char *malloc();
261 char *q;
262
263 q = malloc(strlen(s)+1);
264 if (q == NULL)
265 error(FATAL, gettext("out of space in strsave on %s"), s);
266 strcpy(q, s);
267 return (q);
268 }
269
270 void
include(void)271 include(void)
272 {
273 error(!FATAL, gettext("Include not yet implemented"));
274 }
275
276 void
delim(void)277 delim(void)
278 {
279 yyval = eqnreg = 0;
280 if (cstr(token, 0, SSIZE))
281 error(FATAL, gettext("Bizarre delimiters at %.20s"), token);
282 lefteq = token[0];
283 righteq = token[1];
284 if (lefteq == 'o' && righteq == 'f')
285 lefteq = righteq = '\0';
286 }
287