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