mkdev: default to ../home for TBASE
[troff.git] / eqn / lex.c
blob454a39abcd4578d283069149e2b2e5fa3a225962
1 #include "e.h"
2 #include "y.tab.h"
3 #include <ctype.h>
4 #include <errno.h>
6 #define SSIZE 1000
7 char token[SSIZE];
8 int sp;
10 void space(void);
11 void dodef(tbl *);
12 void define(int);
13 void ifdef(void);
14 void include(void);
15 void delim(void);
17 yylex(void)
19 register int c;
20 tbl *tp;
22 begin:
23 while ((c = input()) == ' ' || c == '\n' || c == '\t')
25 yylval = c;
26 switch (c) {
27 case EOF:
28 ERROR "unexpected end of input inside equation" WARNING;
29 return(EOF);
30 case '~':
31 return(SPACE);
32 case '^':
33 return(THIN);
34 /* case '\t':
35 return(TAB);
37 case '{':
38 return('{');
39 case '}':
40 return('}');
41 case '"':
42 for (sp = 0; (c=input())!='"' && c != '\n'; ) {
43 if (c == '\\')
44 if ((c = input()) != '"')
45 token[sp++] = '\\';
46 token[sp++] = c;
47 if (sp >= SSIZE)
48 ERROR "quoted string %.20s... too long", token FATAL;
50 token[sp] = '\0';
51 yylval = (int) &token[0];
52 if (c == '\n')
53 ERROR "missing \" in %.20s", token WARNING;
54 return(QTEXT);
56 if (!display && c == righteq)
57 return(EOF);
59 unput(c);
60 getstr(token, SSIZE);
61 dprintf(".\tlex token = |%s|\n", token);
62 if ((tp = lookup(deftbl, token)) != NULL) { /* defined term */
63 c = input();
64 unput(c);
65 if (c == '(') /* macro with args */
66 dodef(tp);
67 else { /* no args */
68 unput(' ');
69 pbstr(tp->cval);
70 dprintf(".\tfound %s|=%s|\n", token, tp->cval);
72 goto begin;
75 if ((tp = lookup(keytbl, token)) == NULL) /* not a keyword */
76 return CONTIG;
78 switch (tp->ival) { /* some kind of keyword */
79 case DEFINE: case TDEFINE: case NDEFINE:
80 define(tp->ival);
81 break;
82 case IFDEF:
83 ifdef();
84 break;
85 case DELIM:
86 delim();
87 break;
88 case GSIZE:
89 globsize();
90 break;
91 case GFONT:
92 globfont();
93 break;
94 case INCLUDE:
95 include();
96 break;
97 case SPACE:
98 space();
99 break;
100 case DOTEQ:
101 /* .EQ inside equation -- should warn if at bottom level */
102 break;
103 case DOTEN:
104 if (curfile == infile)
105 return EOF;
106 /* else ignore nested .EN */
107 break;
108 default:
109 return tp->ival;
111 goto begin;
114 void getstr(char *s, int n)
116 register int c;
117 register char *p;
119 p = s;
120 while ((c = input()) == ' ' || c == '\n')
122 if (c == EOF) {
123 *s = 0;
124 return;
126 while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
127 && c != '"' && c != '~' && c != '^') {
128 if (!display && c == righteq)
129 break;
130 if (c == '(' && p > s) { /* might be defined(...) */
131 *p = '\0';
132 if (lookup(deftbl, s) != NULL)
133 break;
135 if (c == '\\')
136 if ((c = input()) != '"')
137 *p++ = '\\';
138 *p++ = c;
139 if (--n <= 0)
140 ERROR "token %.20s... too long", s FATAL;
141 c = input();
143 unput(c);
144 *p = '\0';
145 yylval = (int) s;
148 cstr(char *s, int quote, int maxs)
150 int del, c, i;
152 s[0] = 0;
153 while ((del=input()) == ' ' || del == '\t')
155 if (quote)
156 for (i=0; (c=input()) != del && c != EOF;) {
157 s[i++] = c;
158 if (i >= maxs)
159 return(1); /* disaster */
161 else {
162 if (del == '\n')
163 return(1);
164 s[0] = del;
165 for (i=1; (c=input())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
166 s[i++] = c;
167 if (i >= maxs)
168 return(1); /* disaster */
171 s[i] = '\0';
172 if (c == EOF)
173 ERROR "Unexpected end of input at %.20s", s FATAL;
174 return(0);
177 void define(int type)
179 char *p1, *p2;
180 extern int ftune(char *, char *);
182 getstr(token, SSIZE); /* get name */
183 if (type != DEFINE) {
184 cstr(token, 1, SSIZE); /* skip the definition too */
185 return;
187 p1 = strsave(token);
188 if (cstr(token, 1, SSIZE))
189 ERROR "Unterminated definition at %.20s", token FATAL;
190 if (lookup(ftunetbl, p1) != NULL) { /* double tuning param */
191 dprintf(".\ttune %s %s\n", p1, token);
192 ftune(p1, token);
193 } else {
194 p2 = strsave(token);
195 install(deftbl, p1, p2, 0);
196 dprintf(".\tname %s defined as %s\n", p1, p2);
200 void ifdef(void) /* do body if name is defined */
202 char name[100], *p;
204 getstr(name, sizeof(name)); /* get name */
205 cstr(token, 1, SSIZE); /* and body */
206 if (lookup(deftbl, name) != NULL) { /* found it */
207 p = strsave(token);
208 pushsrc(Free, p);
209 pushsrc(String, p);
213 char *spaceval = NULL;
215 void space(void) /* collect line of form "space amt" to replace \x in output */
217 getstr(token, SSIZE);
218 spaceval = strsave(token);
219 dprintf(".\tsetting spaceval to %s\n", token);
222 char *strsave(char *s)
224 register char *q;
226 q = malloc(strlen(s)+1);
227 if (q == NULL)
228 ERROR "out of space in strsave on %s", s FATAL;
229 strcpy(q, s);
230 return(q);
233 void include(void)
235 char name[100];
236 FILE *fin;
237 int c;
239 while ((c = input()) == ' ')
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);
254 void delim(void)
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';