date and time created 91/03/17 11:02:47 by pendry
[unix-history] / usr / src / usr.sbin / amd / fsinfo / fsi_lex.l
CommitLineData
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
35static int xinput();
36static void xunput();
37
38#ifdef FLEX_SCANNER
39static 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
86static char *filename;
87static char *optr;
88static char ostr[1024];
89static find_resword();
90static unsigned char ibuf[64];
91static unsigned char *iptr = ibuf;
92static int quoted;
93static int lastch, nextch = '\n';
94YYSTYPE yylval;
95
96struct 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
163static int find_resword(s)
164char *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
201int yyerror(s, s1, s2, s3, s4)
202char *s;
203char *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
212ioloc *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
224int yywrap()
225{
226static 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
264static int xinput(need)
265int need;
266{
267static 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
380static void xunput(c)
381int 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}