checkpoint for network tape
[unix-history] / usr / src / usr.sbin / amd / fsinfo / fsi_lex.l
CommitLineData
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
24static int xinput();
25static void xunput();
26
27#ifdef FLEX_SCANNER
28static 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
75static char *filename;
76static char *optr;
77static char ostr[1024];
78static find_resword();
79static unsigned char ibuf[64];
80static unsigned char *iptr = ibuf;
81static int quoted;
82static int lastch, nextch = '\n';
83YYSTYPE yylval;
84
85struct 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
152static int find_resword(s)
153char *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
190int yyerror(s, s1, s2, s3, s4)
191char *s;
192char *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
201ioloc *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
213int yywrap()
214{
215static 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
253static int xinput(need)
254int need;
255{
256static 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
369static void xunput(c)
370int 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}