xref: /netbsd-src/external/bsd/am-utils/dist/fsinfo/fsi_lex.l (revision f89f6560d453f5e37386cc7938c072d2f528b9fa)
1 /*	$NetBSD: fsi_lex.l,v 1.5 2015/01/17 17:46:31 christos Exp $	*/
2 
3 %{
4 /*
5  * Copyright (c) 1997-2014 Erez Zadok
6  * Copyright (c) 1989 Jan-Simon Pendry
7  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
8  * Copyright (c) 1989 The Regents of the University of California.
9  * All rights reserved.
10  *
11  * This code is derived from software contributed to Berkeley by
12  * Jan-Simon Pendry at Imperial College, London.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *
39  * File: am-utils/fsinfo/fsi_lex.l
40  *
41  */
42 
43 /*
44  * Lexical analyzer for fsinfo.
45  * TODO: Needs rewriting.
46  */
47 
48 static int ayylineno;
49 
50 #ifdef FLEX_SCANNER
51 # define INIT_STATE {				\
52 		switch ((yy_start - 1) / 2) {	\
53 		case 0:				\
54 			BEGIN F;		\
55 			break;			\
56 		}				\
57 }
58 
59 #else /* not FLEX_SCANNER */
60 
61 /*
62  * Using old lex...
63  */
64 # define	INIT_STATE {			\
65 		switch (yybgin - yysvec - 1) {	\
66 		case 0:				\
67 			BEGIN F;		\
68 			break;			\
69 		}				\
70 }
71 
72 #endif /* end FLEX_SCANNER */
73 
74 #ifdef HAVE_CONFIG_H
75 # include <config.h>
76 #endif /* HAVE_CONFIG_H */
77 /*
78  * Some systems include a definition for the macro ECHO in <sys/ioctl.h>,
79  * and their (bad) version of lex defines it too at the very beginning of
80  * the generated lex.yy.c file (before it can be easily undefined),
81  * resulting in a conflict.  So undefine it here before needed.
82  * Luckily, it does not appear that this macro is actually used in the rest
83  * of the generated lex.yy.c file.
84  */
85 #ifdef ECHO
86 # undef ECHO
87 #endif /* ECHO */
88 #include <am_defs.h>
89 #include <fsi_data.h>
90 #include <fsinfo.h>
91 #include <fsi_gram.h>
92 /* and once again undefine this, just in case */
93 #ifdef ECHO
94 # undef ECHO
95 #endif /* ECHO */
96 
97 /*
98  * There are some things that need to be defined only if using GNU flex.
99  * These must not be defined if using standard lex
100  */
101 #ifdef FLEX_SCANNER
102 # ifndef ECHO
103 #  define ECHO __IGNORE(fwrite( yytext, yyleng, 1, yyout ))
104 # endif /* not ECHO */
105 #endif /* FLEX_SCANNER */
106 
107 /*
108  * some systems such as DU-4.x have a different GNU flex in /usr/bin
109  * which automatically generates yywrap macros and symbols.  So I must
110  * distinguish between them and when yywrap is actually needed.
111  */
112 #if !defined(yywrap) || defined(yylex)
113 int yywrap(void);
114 #endif /* not yywrap or yylex */
115 
116 int fsi_error(const char *, ...);
117 
118 YYSTYPE yylval;
119 static char *fsi_filename;
120 static char *optr;
121 static char ostr[1024];
122 static int find_resword(char *);
123 static int quoted;
124 
125 struct r {
126   char *rw;
127   int tok;
128 } rr[] = {
129   { "->", tEQ },
130   { "arch", tARCH },
131   { "as", tAS },
132   { "automount", tAUTOMOUNT },
133   { "cluster", tCLUSTER },
134   { "config", tCONFIG },
135   { "direct", tDIRECT },
136   { "dumpset", tDUMPSET },
137   { "exportfs", tEXPORTFS },
138   { "freq", tFREQ },
139   { "from", tFROM },
140   { "fs", tFS },
141   { "fstype", tFSTYPE },
142   { "host", tHOST },
143   { "hwaddr", tHWADDR },
144   { "inaddr", tINADDR },
145   { "localhost", tLOCALHOST },
146   { "log", tLOG },
147   { "mount", tMOUNT },
148   { "netif", tNETIF },
149   { "netmask", tNETMASK },
150   { "nfsalias", tNFSEQ },
151   { "opts", tOPTS },
152   { "os", tOS },
153   { "passno", tPASSNO },
154   { "sel", tSEL },
155   { "volname", tVOLNAME },
156   { NULL, 0 },
157 };
158 #define	NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1)
159 
160 %}
161 
162 /* This option causes Solaris lex to fail.  Use flex.  See BUGS file */
163 /* no need to use yyunput() */
164 %option nounput
165 %option noinput
166 
167 /* allocate more output slots so lex scanners don't run out of mem */
168 %o 1024
169 
170 %start F Q
171 
172 %%
173 		INIT_STATE;	/* witchcraft */
174 
175 <F>[^ \t\n"={}]+	{ return find_resword(yytext); } /* dummy " */
176 <F>[ \t]		;
177 <F>"\n"			{ ayylineno++; }
178 <F>[={}]		{ return *yytext; }
179 
180 <F>\"			{ BEGIN Q; optr = ostr; quoted = 1; }
181 <Q>\n			{ ayylineno++; fsi_error("\" expected"); BEGIN F; }
182 <Q>\\b			{ *optr++ = '\b'; /* escape */ }
183 <Q>\\t			{ *optr++ = '\t'; /* escape */ }
184 <Q>\\\"			{ *optr++ = '\"'; /* escape */ }
185 <Q>\\\\			{ *optr++ = '\\'; /* escape */ }
186 <Q>\\\n			{ ayylineno++; /* continue */ }
187 <Q>\\r			{ *optr++ = '\r'; /* escape */ }
188 <Q>\\n			{ *optr++ = '\n'; /* escape */ }
189 <Q>\\f			{ *optr++ = '\f'; /* escape */ }
190 <Q>"\\ "		{ *optr++ = ' '; /* force space */ }
191 <Q>\\.			{ fsi_error("Unknown \\ sequence"); }
192 <Q>([ \t]|"\\\n"){2,}	{ char *p = (char *) yytext-1; while ((p = strchr(p+1, '\n'))) ayylineno++; }
193 <Q>\"			{ BEGIN F; quoted = 0;
194 				*optr = '\0';
195 				yylval.s = xstrdup(ostr);
196 				return tSTR;
197 			}
198 <Q>.			{ *optr++ = *yytext; }
199 
200 %%
201 
202 
203 static int
204 find_resword(char *s)
205 {
206   int tok = 0;
207   int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1;
208   int rc = 0;
209 
210   m = NRES_WORDS/2;
211 
212 #define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q))
213 
214   while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) {
215     if (rc < 0)
216       h = m - 1;
217     else
218       l = m + 1;
219     m = (h + l) / 2;
220   }
221 
222   if (rc == 0)
223     tok = rr[m].tok;
224 
225   switch (tok) {
226   case tLOCALHOST:
227     s = "${host}";
228     /*FALLTHROUGH*/
229   case 0:
230     yylval.s = xstrdup(s);
231     tok = tSTR;
232     /*FALLTHROUGH*/
233   default:
234     return tok;
235   }
236 }
237 
238 
239 int
240 fsi_error(const char *fmt, ...)
241 {
242   va_list ap;
243 
244   va_start(ap, fmt);
245   col_cleanup(0);
246   fprintf(stderr, "%s:%d: ", fsi_filename ? fsi_filename : "/dev/stdin", ayylineno);
247   vfprintf(stderr, fmt, ap);
248   fputc('\n', stderr);
249   parse_errors++;
250   va_end(ap);
251   return 0;
252 }
253 
254 
255 ioloc *
256 current_location(void)
257 {
258   ioloc *ip = CALLOC(struct ioloc);
259   ip->i_line = ayylineno;
260   ip->i_file = fsi_filename;
261   return ip;
262 }
263 
264 
265 /*
266  * some systems such as DU-4.x have a different GNU flex in /usr/bin
267  * which automatically generates yywrap macros and symbols.  So I must
268  * distinguish between them and when yywrap is actually needed.
269  */
270 #if !defined(yywrap) || defined(yylex)
271 int yywrap(void)
272 {
273   return 1;
274 }
275 #endif /* not yywrap or yylex */
276