Commit | Line | Data |
---|---|---|
04e42ac7 JSP |
1 | %{ |
2 | /* | |
04e42ac7 JSP |
3 | * Copyright (c) 1989 Jan-Simon Pendry |
4 | * Copyright (c) 1989 Imperial College of Science, Technology & Medicine | |
5 | * Copyright (c) 1989 The Regents of the University of California. | |
6 | * All rights reserved. | |
7 | * | |
8 | * This code is derived from software contributed to Berkeley by | |
9 | * Jan-Simon Pendry at Imperial College, London. | |
10 | * | |
2f619045 | 11 | * %sccs.include.redist.c% |
04e42ac7 | 12 | * |
8d2991d5 JSP |
13 | * @(#)fsi_lex.l 5.3 (Berkeley) %G% |
14 | * | |
15 | * $Id: fsi_lex.l,v 5.2.1.3 91/05/07 22:19:03 jsp Alpha $ | |
16 | * | |
04e42ac7 JSP |
17 | */ |
18 | ||
19 | /* | |
20 | * Lexical analyzer for fsinfo. | |
21 | * TODO: Needs rewriting. | |
22 | */ | |
23 | ||
24 | static int xinput(); | |
25 | static void xunput(); | |
26 | ||
27 | #ifdef FLEX_SCANNER | |
28 | static int yylineno; | |
29 | /* Flex support with help from Vern Paxson <vern@helios.ee.lbl.gov> */ | |
30 | #undef YY_INPUT | |
31 | #define YY_INPUT(buf,result,max_size) \ | |
32 | { \ | |
33 | int i; \ | |
34 | for (i = 0; i < max_size; i++) { \ | |
35 | int ch = xinput(i == 0); \ | |
36 | if (ch == 0) \ | |
37 | break; \ | |
38 | buf[i] = ch; \ | |
39 | } \ | |
40 | result = i; \ | |
41 | } | |
42 | ||
43 | #define INIT_STATE { \ | |
44 | switch ((yy_start - 1) / 2) { \ | |
45 | case 0: \ | |
46 | BEGIN F; \ | |
47 | break; \ | |
48 | } \ | |
49 | } | |
50 | ||
51 | ||
52 | #else | |
53 | /* | |
54 | * Using old lex... | |
55 | */ | |
56 | #undef unput | |
57 | #define unput(ch) xunput(ch) | |
58 | #undef input | |
59 | #define input() xinput(1) | |
60 | ||
61 | #define INIT_STATE { \ | |
62 | switch (yybgin - yysvec - 1) { \ | |
63 | case 0: \ | |
64 | BEGIN F; \ | |
65 | break; \ | |
66 | } \ | |
67 | } | |
68 | ||
69 | #endif /* FLEX_SCANNER */ | |
70 | ||
71 | #include "../fsinfo/fsinfo.h" | |
72 | #include "fsi_gram.h" | |
73 | #include <ctype.h> | |
74 | ||
75 | static char *filename; | |
76 | static char *optr; | |
77 | static char ostr[1024]; | |
78 | static find_resword(); | |
79 | static unsigned char ibuf[64]; | |
80 | static unsigned char *iptr = ibuf; | |
81 | static int quoted; | |
82 | static int lastch, nextch = '\n'; | |
83 | YYSTYPE yylval; | |
84 | ||
85 | struct r { | |
86 | char *rw; | |
87 | int tok; | |
88 | } rr[] = { | |
89 | { "->", tEQ }, | |
90 | { "arch", tARCH }, | |
91 | { "as", tAS }, | |
92 | { "automount", tAUTOMOUNT }, | |
93 | { "cluster", tCLUSTER }, | |
94 | { "config", tCONFIG }, | |
95 | { "dumpset", tDUMPSET }, | |
96 | { "exportfs", tEXPORTFS }, | |
97 | { "freq", tFREQ }, | |
98 | { "from", tFROM }, | |
99 | { "fs", tFS }, | |
100 | { "fstype", tFSTYPE }, | |
101 | { "host", tHOST }, | |
102 | { "hwaddr", tHWADDR }, | |
103 | { "inaddr", tINADDR }, | |
104 | { "localhost", tLOCALHOST }, | |
105 | { "log", tLOG }, | |
106 | { "mount", tMOUNT }, | |
107 | { "netif", tNETIF }, | |
108 | { "netmask", tNETMASK }, | |
109 | { "opts", tOPTS }, | |
110 | { "os", tOS }, | |
111 | { "passno", tPASSNO }, | |
112 | { "sel", tSEL }, | |
113 | { "volname", tVOLNAME }, | |
114 | { 0, 0 }, | |
115 | }; | |
116 | #define NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1) | |
117 | ||
118 | %} | |
119 | ||
120 | %start F Q | |
121 | ||
122 | %% | |
123 | INIT_STATE; /* witchcraft */ | |
124 | ||
125 | <F>[^ \t\n"={}]+ { return find_resword(yytext); } | |
126 | <F>[ \t] ; | |
127 | <F>"\n" { yylineno++; } | |
128 | <F>[={}] { return *yytext; } | |
129 | ||
130 | <F>\" { BEGIN Q; optr = ostr; quoted = 1; } | |
131 | <Q>\n { yylineno++; yyerror("\" expected"); BEGIN F; } | |
132 | <Q>\\b { *optr++ = '\b'; /* escape */ } | |
133 | <Q>\\t { *optr++ = '\t'; /* escape */ } | |
134 | <Q>\\\" { *optr++ = '\"'; /* escape */ } | |
135 | <Q>\\\\ { *optr++ = '\\'; /* escape */ } | |
136 | <Q>\\\n { yylineno++; /* continue */ } | |
137 | <Q>\\r { *optr++ = '\r'; /* escape */ } | |
138 | <Q>\\n { *optr++ = '\n'; /* escape */ } | |
139 | <Q>\\f { *optr++ = '\f'; /* escape */ } | |
140 | <Q>\\. { yyerror("Unknown \\ sequence"); } | |
141 | <Q>([ \t]|"\\\n"){2,} { char *p = yytext-1; while (p = strchr(p+1, '\n')) yylineno++; } | |
142 | <Q>"\\ " { *optr++ = ' '; /* force space */ } | |
143 | <Q>\" { BEGIN F; quoted = 0; | |
144 | *optr = '\0'; | |
145 | yylval.s = strdup(ostr); | |
146 | return tSTR; | |
147 | } | |
148 | <Q>. { *optr++ = *yytext; } | |
149 | ||
150 | %% | |
151 | ||
152 | static int find_resword(s) | |
153 | char *s; | |
154 | { | |
155 | int tok = 0; | |
156 | ||
157 | int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1; | |
158 | int rc = 0; | |
159 | ||
160 | m = NRES_WORDS/2; | |
161 | ||
162 | #define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q)) | |
163 | ||
164 | while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) { | |
165 | /*fprintf(stderr, "failed to cmp(%s, %s), %d, %d, %d\n", s, rr[m].rw, l, m, h);*/ | |
166 | if (rc < 0) | |
167 | h = m - 1; | |
168 | else | |
169 | l = m + 1; | |
170 | m = (h + l) / 2; | |
171 | } | |
172 | ||
173 | if (rc == 0) | |
174 | tok = rr[m].tok; | |
175 | ||
176 | switch (tok) { | |
177 | case tLOCALHOST: | |
178 | s = "${host}"; | |
179 | /* fall through... */ | |
180 | case 0: | |
181 | yylval.s = strdup(s); | |
182 | tok = tSTR; | |
183 | /* fall through... */ | |
184 | default: | |
185 | return tok; | |
186 | } | |
187 | ||
188 | } | |
189 | ||
190 | int yyerror(s, s1, s2, s3, s4) | |
191 | char *s; | |
192 | char *s1, *s2, *s3, *s4; | |
193 | { | |
194 | col_cleanup(0); | |
195 | fprintf(stderr, "%s:%d: ", filename ? filename : "/dev/stdin", yylineno); | |
196 | fprintf(stderr, s, s1, s2, s3, s4); | |
197 | fputc('\n', stderr); | |
198 | parse_errors++; | |
199 | } | |
200 | ||
201 | ioloc *current_location() | |
202 | { | |
203 | ioloc *ip = ALLOC(ioloc); | |
204 | ip->i_line = yylineno; | |
205 | ip->i_file = filename; | |
206 | return ip; | |
207 | } | |
208 | ||
209 | #ifdef FLEX_SCANNER | |
210 | #undef yywrap | |
211 | #endif | |
212 | ||
213 | int yywrap() | |
214 | { | |
215 | static int first = 1; | |
216 | if (first) { | |
217 | char prog[16*1024]; | |
218 | strcpy(prog, "for file in "); | |
219 | while (*++g_argv) { | |
220 | if (access(*g_argv, 4) < 0) { | |
221 | error("\"%s\": Cannot open for reading", *g_argv); | |
222 | file_io_errors++; | |
223 | } else { | |
224 | strcat(prog, *g_argv); | |
225 | strcat(prog, " "); | |
226 | } | |
227 | } | |
228 | strcat(prog, "; do /lib/cpp "); | |
229 | strcat(prog, idvbuf); | |
230 | strcat(prog, " -DHOSTNAME=\'"); | |
231 | strcat(prog, hostname); | |
232 | strcat(prog, "\' \"$file\"; done"); | |
233 | yyin = popen(prog, "r"); | |
234 | if (yyin) { | |
235 | /*if (filename) free(filename);*/ | |
236 | filename = strdup("unknown"); | |
237 | yylineno = 1; | |
238 | first = 0; | |
239 | return 0; | |
240 | } else { | |
241 | perror(prog); | |
242 | } | |
243 | } | |
244 | ||
245 | if (!first && yyin && pclose(yyin) != 0) | |
246 | parse_errors++; | |
247 | ||
248 | return 1; | |
249 | } | |
250 | ||
251 | #define xgetc(fp) ((iptr > ibuf) ? (*--iptr) : (lastch = nextch, nextch = getc(fp), (nextch == EOF ? nextch = lastch, EOF : nextch))) | |
252 | ||
253 | static int xinput(need) | |
254 | int need; | |
255 | { | |
256 | static int c_comment = 0; | |
257 | int ch, ch2; | |
258 | ||
259 | do { | |
260 | ch = xgetc(yyin); | |
261 | /* fprintf(stderr, "ch = %c, %#x, %d\n", ch, ibuf,iptr-ibuf); */ | |
262 | if (ch == EOF) return 0; | |
263 | if (quoted) | |
264 | return ch; | |
265 | if (c_comment) { | |
266 | ch2 = ch; | |
267 | do { | |
268 | if (ch2 == '\n') { | |
269 | nextch = '\n'; | |
270 | return ch2; | |
271 | } | |
272 | /* C style comment */ | |
273 | do { | |
274 | ch2 = getc(yyin); | |
275 | if (ch2 == '\n') { | |
276 | nextch = '\n'; | |
277 | return ch2; | |
278 | } | |
279 | } while (ch2 != '*' && ch2 != EOF); | |
280 | ||
281 | while (ch2 == '*') | |
282 | ch2 = getc(yyin); | |
283 | } while (ch2 != '/' && ch2 != EOF); | |
284 | c_comment = 0; | |
285 | if (ch2 == EOF) | |
286 | break; | |
287 | continue; | |
288 | } | |
289 | ||
290 | if (ch == '#') { | |
291 | /*log("lastch = '%c' (%#x)", lastch, lastch);*/ | |
292 | if (lastch == '\n') { | |
293 | char fname[MAXPATHLEN]; | |
294 | char *fptr; | |
295 | if (!need) { | |
296 | xunput('#'); | |
297 | nextch = '\n'; | |
298 | return 0; | |
299 | } | |
300 | fname[0] = '\0'; | |
301 | /* Skip past space */ | |
302 | do { | |
303 | ch2 = getc(yyin); | |
304 | } while (ch2 != EOF && ch2 != '\n' && !isdigit(ch2)); | |
305 | if (isdigit(ch2)) { | |
306 | /* Read in line number */ | |
307 | fptr = fname; | |
308 | do { | |
309 | *fptr++ = ch2; | |
310 | ch2 = getc(yyin); | |
311 | } while (isdigit(ch2)); | |
312 | *fptr = '\0'; | |
313 | if (fptr != fname) | |
314 | yylineno = atoi(fname) - 1; | |
315 | } | |
316 | /* Skip past space */ | |
317 | while (ch2 != EOF && ch2 != '\"' && ch2 != '\n') | |
318 | ch2 = getc(yyin); | |
319 | if (ch2 == '\"') { | |
320 | /* Read file name */ | |
321 | fptr = fname; | |
322 | ch2 = getc(yyin); | |
323 | while (ch2 != '\"' && ch2 != EOF && ch2 != EOF) { | |
324 | *fptr++ = ch2; | |
325 | ch2 = getc(yyin); | |
326 | } | |
327 | *fptr = '\0'; | |
328 | if (fname[0]) { | |
329 | log("Setting filename to \"%s\"", fname); | |
330 | /*if (filename) free(filename);*/ | |
331 | filename = strdup(fname); | |
332 | } | |
333 | } | |
334 | while (ch2 != '\n' && ch2 != EOF) | |
335 | ch2 = getc(yyin); | |
336 | } else do { | |
337 | ch2 = getc(yyin); | |
338 | } while (ch2 != '\n' && ch2 != EOF); | |
339 | if (ch2 == '\n') { | |
340 | nextch = '\n'; | |
341 | return ch2; | |
342 | } | |
343 | } else if (ch == '/') { | |
344 | ch2 = getc(yyin); | |
345 | if (ch2 == '/') { | |
346 | /* C++ style comment */ | |
347 | do { | |
348 | ch2 = getc(yyin); | |
349 | } while (ch2 != '\n' && ch2 != EOF); | |
350 | if (ch2 == '\n') { | |
351 | nextch = '\n'; | |
352 | return ch2; | |
353 | } | |
354 | } else if (ch2 == '*') { | |
355 | c_comment = 1; | |
356 | continue; | |
357 | } else { | |
358 | xunput(ch2); | |
359 | return ch; | |
360 | } | |
361 | } else { | |
362 | return ch; | |
363 | } | |
364 | } while (ch2 != EOF); | |
365 | error("End of file within comment"); | |
366 | return 0; | |
367 | } | |
368 | ||
369 | static void xunput(c) | |
370 | int c; | |
371 | { | |
372 | if (c && c != EOF) { | |
373 | if (iptr == ibuf + sizeof(ibuf) - 1) | |
374 | fatal("Out of space in lexical pushback"); | |
375 | *iptr++ = c; | |
376 | } | |
377 | } |