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