add some hardware info for soekris net4801
[openwrt.git] / package / config / zconf.l
1 %option backup nostdinit noyywrap never-interactive full ecs
2 %option 8bit backup nodefault perf-report perf-report
3 %x COMMAND HELP STRING PARAM
4 %{
5 /*
6  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
7  * Released under the terms of the GNU GPL v2.0.
8  */
9
10 #include <limits.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <glob.h>
16
17 #define LKC_DIRECT_LINK
18 #include "lkc.h"
19
20 #define START_STRSIZE   16
21
22 char *text;
23 static char *text_ptr;
24 static int text_size, text_asize;
25
26 struct buffer {
27         struct buffer *parent;
28         YY_BUFFER_STATE state;
29 };
30
31 struct buffer *current_buf;
32
33 static int last_ts, first_ts;
34
35 static void zconf_endhelp(void);
36 static struct buffer *zconf_endfile(void);
37
38 void new_string(void)
39 {
40         text = malloc(START_STRSIZE);
41         text_asize = START_STRSIZE;
42         text_ptr = text;
43         text_size = 0;
44         *text_ptr = 0;
45 }
46
47 void append_string(const char *str, int size)
48 {
49         int new_size = text_size + size + 1;
50         if (new_size > text_asize) {
51                 text = realloc(text, new_size);
52                 text_asize = new_size;
53                 text_ptr = text + text_size;
54         }
55         memcpy(text_ptr, str, size);
56         text_ptr += size;
57         text_size += size;
58         *text_ptr = 0;
59 }
60
61 void alloc_string(const char *str, int size)
62 {
63         text = malloc(size + 1);
64         memcpy(text, str, size);
65         text[size] = 0;
66 }
67 %}
68
69 ws      [ \n\t]
70 n       [A-Za-z0-9_]
71
72 %%
73         int str = 0;
74         int ts, i;
75
76 [ \t]*#.*\n     current_file->lineno++;
77 [ \t]*#.*
78
79 [ \t]*\n        current_file->lineno++; return T_EOL;
80
81 [ \t]+  {
82         BEGIN(COMMAND);
83 }
84
85 .       {
86         unput(yytext[0]);
87         BEGIN(COMMAND);
88 }
89
90
91 <COMMAND>{
92         "mainmenu"              BEGIN(PARAM); return T_MAINMENU;
93         "menu"                  BEGIN(PARAM); return T_MENU;
94         "endmenu"               BEGIN(PARAM); return T_ENDMENU;
95         "source"                BEGIN(PARAM); return T_SOURCE;
96         "choice"                BEGIN(PARAM); return T_CHOICE;
97         "endchoice"             BEGIN(PARAM); return T_ENDCHOICE;
98         "comment"               BEGIN(PARAM); return T_COMMENT;
99         "config"                BEGIN(PARAM); return T_CONFIG;
100         "menuconfig"            BEGIN(PARAM); return T_MENUCONFIG;
101         "help"                  BEGIN(PARAM); return T_HELP;
102         "if"                    BEGIN(PARAM); return T_IF;
103         "endif"                 BEGIN(PARAM); return T_ENDIF;
104         "depends"               BEGIN(PARAM); return T_DEPENDS;
105         "requires"              BEGIN(PARAM); return T_REQUIRES;
106         "optional"              BEGIN(PARAM); return T_OPTIONAL;
107         "default"               BEGIN(PARAM); return T_DEFAULT;
108         "prompt"                BEGIN(PARAM); return T_PROMPT;
109         "tristate"              BEGIN(PARAM); return T_TRISTATE;
110         "def_tristate"          BEGIN(PARAM); return T_DEF_TRISTATE;
111         "bool"                  BEGIN(PARAM); return T_BOOLEAN;
112         "boolean"               BEGIN(PARAM); return T_BOOLEAN;
113         "def_bool"              BEGIN(PARAM); return T_DEF_BOOLEAN;
114         "def_boolean"           BEGIN(PARAM); return T_DEF_BOOLEAN;
115         "int"                   BEGIN(PARAM); return T_INT;
116         "hex"                   BEGIN(PARAM); return T_HEX;
117         "string"                BEGIN(PARAM); return T_STRING;
118         "select"                BEGIN(PARAM); return T_SELECT;
119         "enable"                BEGIN(PARAM); return T_SELECT;
120         "range"                 BEGIN(PARAM); return T_RANGE;
121         {n}+    {
122                 alloc_string(yytext, yyleng);
123                 zconflval.string = text;
124                 return T_WORD;
125         }
126         .
127         \n      current_file->lineno++; BEGIN(INITIAL);
128 }
129
130 <PARAM>{
131         "&&"    return T_AND;
132         "||"    return T_OR;
133         "("     return T_OPEN_PAREN;
134         ")"     return T_CLOSE_PAREN;
135         "!"     return T_NOT;
136         "="     return T_EQUAL;
137         "!="    return T_UNEQUAL;
138         "if"    return T_IF;
139         "on"    return T_ON;
140         \"|\'   {
141                 str = yytext[0];
142                 new_string();
143                 BEGIN(STRING);
144         }
145         \n      BEGIN(INITIAL); current_file->lineno++; return T_EOL;
146         ---     /* ignore */
147         ({n}|[-/.])+    {
148                 alloc_string(yytext, yyleng);
149                 zconflval.string = text;
150                 return T_WORD;
151         }
152         #.*     /* comment */
153         \\\n    current_file->lineno++;
154         .
155         <<EOF>> {
156                 BEGIN(INITIAL);
157         }
158 }
159
160 <STRING>{
161         [^'"\\\n]+/\n   {
162                 append_string(yytext, yyleng);
163                 zconflval.string = text;
164                 return T_WORD_QUOTE;
165         }
166         [^'"\\\n]+      {
167                 append_string(yytext, yyleng);
168         }
169         \\.?/\n {
170                 append_string(yytext + 1, yyleng - 1);
171                 zconflval.string = text;
172                 return T_WORD_QUOTE;
173         }
174         \\.?    {
175                 append_string(yytext + 1, yyleng - 1);
176         }
177         \'|\"   {
178                 if (str == yytext[0]) {
179                         BEGIN(PARAM);
180                         zconflval.string = text;
181                         return T_WORD_QUOTE;
182                 } else
183                         append_string(yytext, 1);
184         }
185         \n      {
186                 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
187                 current_file->lineno++;
188                 BEGIN(INITIAL);
189                 return T_EOL;
190         }
191         <<EOF>> {
192                 BEGIN(INITIAL);
193         }
194 }
195
196 <HELP>{
197         [ \t]+  {
198                 ts = 0;
199                 for (i = 0; i < yyleng; i++) {
200                         if (yytext[i] == '\t')
201                                 ts = (ts & ~7) + 8;
202                         else
203                                 ts++;
204                 }
205                 last_ts = ts;
206                 if (first_ts) {
207                         if (ts < first_ts) {
208                                 zconf_endhelp();
209                                 return T_HELPTEXT;
210                         }
211                         ts -= first_ts;
212                         while (ts > 8) {
213                                 append_string("        ", 8);
214                                 ts -= 8;
215                         }
216                         append_string("        ", ts);
217                 }
218         }
219         [ \t]*\n/[^ \t\n] {
220                 current_file->lineno++;
221                 zconf_endhelp();
222                 return T_HELPTEXT;
223         }
224         [ \t]*\n        {
225                 current_file->lineno++;
226                 append_string("\n", 1);
227         }
228         [^ \t\n].* {
229                 append_string(yytext, yyleng);
230                 if (!first_ts)
231                         first_ts = last_ts;
232         }
233         <<EOF>> {
234                 zconf_endhelp();
235                 return T_HELPTEXT;
236         }
237 }
238
239 <<EOF>> {
240         if (current_buf) {
241                 zconf_endfile();
242                 return T_EOF;
243         }
244         fclose(yyin);
245         yyterminate();
246 }
247
248 %%
249 void zconf_starthelp(void)
250 {
251         new_string();
252         last_ts = first_ts = 0;
253         BEGIN(HELP);
254 }
255
256 static void zconf_endhelp(void)
257 {
258         zconflval.string = text;
259         BEGIN(INITIAL);
260 }
261
262
263 /*
264  * Try to open specified file with following names:
265  * ./name
266  * $(srctree)/name
267  * The latter is used when srctree is separate from objtree
268  * when compiling the kernel.
269  * Return NULL if file is not found.
270  */
271 FILE *zconf_fopen(const char *name)
272 {
273         char *env, fullname[PATH_MAX+1];
274         FILE *f;
275
276         f = fopen(name, "r");
277         if (!f && name[0] != '/') {
278                 env = getenv(SRCTREE);
279                 if (env) {
280                         sprintf(fullname, "%s/%s", env, name);
281                         f = fopen(fullname, "r");
282                 }
283         }
284         return f;
285 }
286
287 void zconf_initscan(const char *name)
288 {
289         yyin = zconf_fopen(name);
290         if (!yyin) {
291                 printf("can't find file %s\n", name);
292                 exit(1);
293         }
294
295         current_buf = malloc(sizeof(*current_buf));
296         memset(current_buf, 0, sizeof(*current_buf));
297
298         current_file = file_lookup(name);
299         current_file->lineno = 1;
300         current_file->flags = FILE_BUSY;
301 }
302
303 void zconf_nextfile(const char *name)
304 {
305         size_t i;
306         int retval;
307         glob_t files;
308         char *filename;
309         struct file *file;
310         struct buffer *buf;
311
312         retval = glob(name, GLOB_ERR | GLOB_MARK, NULL, &files);
313         if (retval == GLOB_NOSPACE || retval == GLOB_ABORTED || retval == GLOB_NOMATCH) {
314                 printf("%s:%d: glob failed: %s \"%s\"\n", zconf_curname(), zconf_lineno(),
315                         retval == GLOB_NOSPACE ? "failed to allocate memory" :
316                                 retval == GLOB_ABORTED ? "read error" : "no match",
317                         name);
318                 exit(1);
319         }
320
321         for (i = files.gl_pathc-1; i != (size_t)-1; --i) {
322                 filename = files.gl_pathv[i];
323
324                 file = file_lookup(filename);
325                 buf = malloc(sizeof(*buf));
326                 memset(buf, 0, sizeof(*buf));
327                 current_buf->state = YY_CURRENT_BUFFER;
328                 zconfin = zconf_fopen(filename);
329                 if (!zconfin) {
330                         printf("%s:%d: can't open file \"%s\"\n",
331                                 zconf_curname(), zconf_lineno(), filename);
332                         exit(1);
333                 }
334                 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
335                 buf->parent = current_buf;
336                 current_buf = buf;
337
338                 if (file->flags & FILE_BUSY) {
339                         printf("recursive scan (%s)?\n", filename);
340                         exit(1);
341                 }
342                 if (file->flags & FILE_SCANNED) {
343                         printf("file %s already scanned?\n", filename);
344                         exit(1);
345                 }
346                 file->flags |= FILE_BUSY;
347                 file->lineno = 1;
348                 file->parent = current_file;
349                 current_file = file;
350         }
351 }
352
353 static struct buffer *zconf_endfile(void)
354 {
355         struct buffer *parent;
356
357         current_file->flags |= FILE_SCANNED;
358         current_file->flags &= ~FILE_BUSY;
359         current_file = current_file->parent;
360
361         parent = current_buf->parent;
362         if (parent) {
363                 fclose(yyin);
364                 yy_delete_buffer(YY_CURRENT_BUFFER);
365                 yy_switch_to_buffer(parent->state);
366         }
367         free(current_buf);
368         current_buf = parent;
369
370         return parent;
371 }
372
373 int zconf_lineno(void)
374 {
375         if (current_buf)
376                 return current_file->lineno - 1;
377         else
378                 return 0;
379 }
380
381 char *zconf_curname(void)
382 {
383         if (current_buf)
384                 return current_file->name;
385         else
386                 return "<none>";
387 }