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