]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/amd/fsinfo/fsi_lex.l
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / amd / fsinfo / fsi_lex.l
1 %{
2 /*
3  * Copyright (c) 1997-2006 Erez Zadok
4  * Copyright (c) 1989 Jan-Simon Pendry
5  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
6  * Copyright (c) 1989 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Jan-Simon Pendry at Imperial College, London.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgment:
22  *      This product includes software developed by the University of
23  *      California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  *
41  * File: am-utils/fsinfo/fsi_lex.l
42  *
43  */
44
45 /*
46  * Lexical analyzer for fsinfo.
47  * TODO: Needs rewriting.
48  */
49
50 static int ayylineno;
51
52 #ifdef FLEX_SCANNER
53 # define INIT_STATE {                           \
54                 switch ((yy_start - 1) / 2) {   \
55                 case 0:                         \
56                         BEGIN F;                \
57                         break;                  \
58                 }                               \
59 }
60
61 #else /* not FLEX_SCANNER */
62
63 /*
64  * Using old lex...
65  */
66 # define        INIT_STATE {                    \
67                 switch (yybgin - yysvec - 1) {  \
68                 case 0:                         \
69                         BEGIN F;                \
70                         break;                  \
71                 }                               \
72 }
73
74 #endif /* end FLEX_SCANNER */
75
76 #ifdef HAVE_CONFIG_H
77 # include <config.h>
78 #endif /* HAVE_CONFIG_H */
79 /*
80  * Some systems include a definition for the macro ECHO in <sys/ioctl.h>,
81  * and their (bad) version of lex defines it too at the very beginning of
82  * the generated lex.yy.c file (before it can be easily undefined),
83  * resulting in a conflict.  So undefine it here before needed.
84  * Luckily, it does not appear that this macro is actually used in the rest
85  * of the generated lex.yy.c file.
86  */
87 #ifdef ECHO
88 # undef ECHO
89 #endif /* ECHO */
90 #include <am_defs.h>
91 #include <fsi_data.h>
92 #include <fsinfo.h>
93 #include <fsi_gram.h>
94 /* and once again undefine this, just in case */
95 #ifdef ECHO
96 # undef ECHO
97 #endif /* ECHO */
98
99 /*
100  * There are some things that need to be defined only if using GNU flex.
101  * These must not be defined if using standard lex
102  */
103 #ifdef FLEX_SCANNER
104 # ifndef ECHO
105 #  define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
106 # endif /* not ECHO */
107 #endif /* FLEX_SCANNER */
108
109 /*
110  * some systems such as DU-4.x have a different GNU flex in /usr/bin
111  * which automatically generates yywrap macros and symbols.  So I must
112  * distinguish between them and when yywrap is actually needed.
113  */
114 #ifndef yywrap
115 int yywrap(void);
116 #endif /* not yywrap */
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   { 0, 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
166 /* allocate more output slots so lex scanners don't run out of mem */
167 %o 1024
168
169 %start F Q
170
171 %%
172                 INIT_STATE;     /* witchcraft */
173
174 <F>[^ \t\n"={}]+        { return find_resword(yytext); } /* dummy " */
175 <F>[ \t]                ;
176 <F>"\n"                 { ayylineno++; }
177 <F>[={}]                { return *yytext; }
178
179 <F>\"                   { BEGIN Q; optr = ostr; quoted = 1; }
180 <Q>\n                   { ayylineno++; yyerror("\" expected"); BEGIN F; }
181 <Q>\\b                  { *optr++ = '\b'; /* escape */ }
182 <Q>\\t                  { *optr++ = '\t'; /* escape */ }
183 <Q>\\\"                 { *optr++ = '\"'; /* escape */ }
184 <Q>\\\\                 { *optr++ = '\\'; /* escape */ }
185 <Q>\\\n                 { ayylineno++; /* continue */ }
186 <Q>\\r                  { *optr++ = '\r'; /* escape */ }
187 <Q>\\n                  { *optr++ = '\n'; /* escape */ }
188 <Q>\\f                  { *optr++ = '\f'; /* escape */ }
189 <Q>"\\ "                { *optr++ = ' '; /* force space */ }
190 <Q>\\.                  { yyerror("Unknown \\ sequence"); }
191 <Q>([ \t]|"\\\n"){2,}   { char *p = (char *) yytext-1; while ((p = strchr(p+1, '\n'))) ayylineno++; }
192 <Q>\"                   { BEGIN F; quoted = 0;
193                                 *optr = '\0';
194                                 yylval.s = strdup(ostr);
195                                 return tSTR;
196                         }
197 <Q>.                    { *optr++ = *yytext; }
198
199 %%
200
201
202 static int
203 find_resword(char *s)
204 {
205   int tok = 0;
206   int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1;
207   int rc = 0;
208
209   m = NRES_WORDS/2;
210
211 #define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q))
212
213   while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) {
214     if (rc < 0)
215       h = m - 1;
216     else
217       l = m + 1;
218     m = (h + l) / 2;
219   }
220
221   if (rc == 0)
222     tok = rr[m].tok;
223
224   switch (tok) {
225   case tLOCALHOST:
226     s = "${host}";
227     /* fall through... */
228   case 0:
229     yylval.s = strdup(s);
230     tok = tSTR;
231     /* fall through... */
232   default:
233     return tok;
234   }
235 }
236
237
238 int
239 yyerror(char *fmt, ...)
240 {
241   va_list ap;
242
243   va_start(ap, fmt);
244   col_cleanup(0);
245   fprintf(stderr, "%s:%d: ", fsi_filename ? fsi_filename : "/dev/stdin", ayylineno);
246   vfprintf(stderr, fmt, ap);
247   fputc('\n', stderr);
248   parse_errors++;
249   va_end(ap);
250   return 0;
251 }
252
253
254 ioloc *
255 current_location(void)
256 {
257   ioloc *ip = CALLOC(struct ioloc);
258   ip->i_line = ayylineno;
259   ip->i_file = fsi_filename;
260   return ip;
261 }
262
263
264 /*
265  * some systems such as DU-4.x have a different GNU flex in /usr/bin
266  * which automatically generates yywrap macros and symbols.  So I must
267  * distinguish between them and when yywrap is actually needed.
268  */
269 #ifndef yywrap
270 int yywrap(void)
271 {
272   return 1;
273 }
274 #endif /* not yywrap */