1 #include "e.h"
2 #include "y.tab.h"
3 #include <ctype.h>
4
5 #define SSIZE 1000
6 char token[SSIZE];
7 int sp;
8
9 void space(void);
10 void dodef(tbl *);
11 void define(int);
12 void ifdef(void);
13 void include(void);
14 void delim(void);
15
yylex(void)16 yylex(void)
17 {
18 register int c;
19 tbl *tp;
20
21 begin:
22 while ((c = input()) == ' ' || c == '\n' || c == '\t')
23 ;
24 yylval = c;
25 switch (c) {
26 case EOF:
27 ERROR "unexpected end of input inside equation" WARNING;
28 return(EOF);
29 case '~':
30 return(SPACE);
31 case '^':
32 return(THIN);
33 /* case '\t':
34 return(TAB);
35 */
36 case '{':
37 return('{');
38 case '}':
39 return('}');
40 case '"':
41 for (sp = 0; (c=input())!='"' && c != '\n'; ) {
42 if (c == '\\')
43 if ((c = input()) != '"')
44 token[sp++] = '\\';
45 token[sp++] = c;
46 if (sp >= SSIZE)
47 ERROR "quoted string %.20s... too long", token FATAL;
48 }
49 token[sp] = '\0';
50 yylval = (int) &token[0];
51 if (c == '\n')
52 ERROR "missing \" in %.20s", token WARNING;
53 return(QTEXT);
54 }
55 if (!display && c == righteq)
56 return(EOF);
57
58 unput(c);
59 getstr(token, SSIZE);
60 dprintf(".\tlex token = |%s|\n", token);
61 if ((tp = lookup(deftbl, token)) != NULL) { /* defined term */
62 c = input();
63 unput(c);
64 if (c == '(') /* macro with args */
65 dodef(tp);
66 else { /* no args */
67 unput(' ');
68 pbstr(tp->cval);
69 dprintf(".\tfound %s|=%s|\n", token, tp->cval);
70 }
71 goto begin;
72 }
73
74 if ((tp = lookup(keytbl, token)) == NULL) /* not a keyword */
75 return CONTIG;
76
77 switch (tp->ival) { /* some kind of keyword */
78 case DEFINE: case TDEFINE: case NDEFINE:
79 define(tp->ival);
80 break;
81 case IFDEF:
82 ifdef();
83 break;
84 case DELIM:
85 delim();
86 break;
87 case GSIZE:
88 globsize();
89 break;
90 case GFONT:
91 globfont();
92 break;
93 case INCLUDE:
94 include();
95 break;
96 case SPACE:
97 space();
98 break;
99 case DOTEQ:
100 /* .EQ inside equation -- should warn if at bottom level */
101 break;
102 case DOTEN:
103 if (curfile == infile)
104 return EOF;
105 /* else ignore nested .EN */
106 break;
107 default:
108 return tp->ival;
109 }
110 goto begin;
111 }
112
getstr(char * s,int n)113 void getstr(char *s, int n)
114 {
115 register int c;
116 register char *p;
117
118 p = s;
119 while ((c = input()) == ' ' || c == '\n')
120 ;
121 if (c == EOF) {
122 *s = 0;
123 return;
124 }
125 while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
126 && c != '"' && c != '~' && c != '^') {
127 if (!display && c == righteq)
128 break;
129 if (c == '(' && p > s) { /* might be defined(...) */
130 *p = '\0';
131 if (lookup(deftbl, s) != NULL)
132 break;
133 }
134 if (c == '\\')
135 if ((c = input()) != '"')
136 *p++ = '\\';
137 *p++ = c;
138 if (--n <= 0)
139 ERROR "token %.20s... too long", s FATAL;
140 c = input();
141 }
142 unput(c);
143 *p = '\0';
144 yylval = (int) s;
145 }
146
cstr(char * s,int quote,int maxs)147 cstr(char *s, int quote, int maxs)
148 {
149 int del, c, i;
150
151 s[0] = 0;
152 while ((del=input()) == ' ' || del == '\t')
153 ;
154 if (quote)
155 for (i=0; (c=input()) != del && c != EOF;) {
156 s[i++] = c;
157 if (i >= maxs)
158 return(1); /* disaster */
159 }
160 else {
161 if (del == '\n')
162 return(1);
163 s[0] = del;
164 for (i=1; (c=input())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
165 s[i++] = c;
166 if (i >= maxs)
167 return(1); /* disaster */
168 }
169 }
170 s[i] = '\0';
171 if (c == EOF)
172 ERROR "Unexpected end of input at %.20s", s FATAL;
173 return(0);
174 }
175
define(int type)176 void define(int type)
177 {
178 char *p1, *p2;
179 extern int ftune(char *, char *);
180
181 getstr(token, SSIZE); /* get name */
182 if (type != DEFINE) {
183 cstr(token, 1, SSIZE); /* skip the definition too */
184 return;
185 }
186 p1 = strsave(token);
187 if (cstr(token, 1, SSIZE))
188 ERROR "Unterminated definition at %.20s", token FATAL;
189 if (lookup(ftunetbl, p1) != NULL) { /* double tuning param */
190 dprintf(".\ttune %s %s\n", p1, token);
191 ftune(p1, token);
192 } else {
193 p2 = strsave(token);
194 install(deftbl, p1, p2, 0);
195 dprintf(".\tname %s defined as %s\n", p1, p2);
196 }
197 }
198
ifdef(void)199 void ifdef(void) /* do body if name is defined */
200 {
201 char name[100], *p;
202
203 getstr(name, sizeof(name)); /* get name */
204 cstr(token, 1, SSIZE); /* and body */
205 if (lookup(deftbl, name) != NULL) { /* found it */
206 p = strsave(token);
207 pushsrc(Free, p);
208 pushsrc(String, p);
209 }
210 }
211
212 char *spaceval = NULL;
213
space(void)214 void space(void) /* collect line of form "space amt" to replace \x in output */
215 {
216 getstr(token, SSIZE);
217 spaceval = strsave(token);
218 dprintf(".\tsetting spaceval to %s\n", token);
219 }
220
strsave(char * s)221 char *strsave(char *s)
222 {
223 register char *q;
224
225 q = malloc(strlen(s)+1);
226 if (q == NULL)
227 ERROR "out of space in strsave on %s", s FATAL;
228 strcpy(q, s);
229 return(q);
230 }
231
include(void)232 void include(void)
233 {
234 char name[100];
235 FILE *fin;
236 int c;
237 extern int errno;
238
239 while ((c = input()) == ' ')
240 ;
241 unput(c);
242 cstr(name, c == '"', sizeof(name)); /* gets it quoted or not */
243 if ((fin = fopen(name, "r")) == NULL)
244 ERROR "can't open file %s", name FATAL;
245 errno = 0;
246 curfile++;
247 curfile->fin = fin;
248 curfile->fname = strsave(name);
249 curfile->lineno = 0;
250 printf(".lf 1 %s\n", curfile->fname);
251 pushsrc(File, curfile->fname);
252 }
253
delim(void)254 void delim(void)
255 {
256 yyval = eqnreg = 0;
257 if (cstr(token, 0, SSIZE))
258 ERROR "Bizarre delimiters" FATAL;
259 lefteq = token[0];
260 righteq = token[1];
261 if (!isprint(lefteq) || !isprint(righteq))
262 ERROR "Bizarre delimiters" FATAL;
263 if (lefteq == 'o' && righteq == 'f')
264 lefteq = righteq = '\0';
265 }
266