blob: 55517b2877cdb610c57acaae904647e57cfe5d8f [file] [log] [blame]
Eric Andersenc9f20d92002-12-05 08:41:41 +00001%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
Eric Andersen72d8e442003-08-05 02:18:25 +000010#include <limits.h>
Eric Andersenc9f20d92002-12-05 08:41:41 +000011#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15
16#define LKC_DIRECT_LINK
17#include "lkc.h"
Eric Andersenc9f20d92002-12-05 08:41:41 +000018
19#define START_STRSIZE 16
20
21char *text;
22static char *text_ptr;
23static int text_size, text_asize;
24
25struct buffer {
26 struct buffer *parent;
27 YY_BUFFER_STATE state;
28};
29
30struct buffer *current_buf;
31
32static int last_ts, first_ts;
33
34static void zconf_endhelp(void);
35static struct buffer *zconf_endfile(void);
36
37void new_string(void)
38{
39 text = malloc(START_STRSIZE);
40 text_asize = START_STRSIZE;
41 text_ptr = text;
42 text_size = 0;
43 *text_ptr = 0;
44}
45
46void append_string(const char *str, int size)
47{
48 int new_size = text_size + size + 1;
49 if (new_size > text_asize) {
50 text = realloc(text, new_size);
51 text_asize = new_size;
52 text_ptr = text + text_size;
53 }
54 memcpy(text_ptr, str, size);
55 text_ptr += size;
56 text_size += size;
57 *text_ptr = 0;
58}
59
60void alloc_string(const char *str, int size)
61{
62 text = malloc(size + 1);
63 memcpy(text, str, size);
64 text[size] = 0;
65}
66%}
67
68ws [ \n\t]
69n [A-Za-z0-9_]
70
71%%
72 int str = 0;
73 int ts, i;
74
75[ \t]*#.*\n current_file->lineno++;
76[ \t]*#.*
77
78[ \t]*\n current_file->lineno++; return T_EOL;
79
80[ \t]+ {
81 BEGIN(COMMAND);
82}
83
84. {
85 unput(yytext[0]);
86 BEGIN(COMMAND);
87}
88
89
90<COMMAND>{
91 "mainmenu" BEGIN(PARAM); return T_MAINMENU;
92 "menu" BEGIN(PARAM); return T_MENU;
93 "endmenu" BEGIN(PARAM); return T_ENDMENU;
94 "source" BEGIN(PARAM); return T_SOURCE;
95 "choice" BEGIN(PARAM); return T_CHOICE;
96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
97 "comment" BEGIN(PARAM); return T_COMMENT;
98 "config" BEGIN(PARAM); return T_CONFIG;
Eric Andersen72d8e442003-08-05 02:18:25 +000099 "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000100 "help" BEGIN(PARAM); return T_HELP;
101 "if" BEGIN(PARAM); return T_IF;
102 "endif" BEGIN(PARAM); return T_ENDIF;
103 "depends" BEGIN(PARAM); return T_DEPENDS;
104 "requires" BEGIN(PARAM); return T_REQUIRES;
105 "optional" BEGIN(PARAM); return T_OPTIONAL;
106 "default" BEGIN(PARAM); return T_DEFAULT;
107 "prompt" BEGIN(PARAM); return T_PROMPT;
108 "tristate" BEGIN(PARAM); return T_TRISTATE;
Eric Andersen72d8e442003-08-05 02:18:25 +0000109 "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000110 "bool" BEGIN(PARAM); return T_BOOLEAN;
111 "boolean" BEGIN(PARAM); return T_BOOLEAN;
Eric Andersen72d8e442003-08-05 02:18:25 +0000112 "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
113 "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000114 "int" BEGIN(PARAM); return T_INT;
115 "hex" BEGIN(PARAM); return T_HEX;
116 "string" BEGIN(PARAM); return T_STRING;
Eric Andersen72d8e442003-08-05 02:18:25 +0000117 "select" BEGIN(PARAM); return T_SELECT;
118 "enable" BEGIN(PARAM); return T_SELECT;
119 "range" BEGIN(PARAM); return T_RANGE;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000120 {n}+ {
121 alloc_string(yytext, yyleng);
122 zconflval.string = text;
123 return T_WORD;
124 }
125 .
126 \n current_file->lineno++; BEGIN(INITIAL);
127}
128
129<PARAM>{
130 "&&" return T_AND;
131 "||" return T_OR;
132 "(" return T_OPEN_PAREN;
133 ")" return T_CLOSE_PAREN;
134 "!" return T_NOT;
135 "=" return T_EQUAL;
136 "!=" return T_UNEQUAL;
137 "if" return T_IF;
138 "on" return T_ON;
139 \"|\' {
140 str = yytext[0];
141 new_string();
142 BEGIN(STRING);
143 }
144 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
145 --- /* ignore */
146 ({n}|[-/.])+ {
147 alloc_string(yytext, yyleng);
148 zconflval.string = text;
149 return T_WORD;
150 }
Eric Andersen72d8e442003-08-05 02:18:25 +0000151 #.* /* comment */
152 \\\n current_file->lineno++;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000153 .
154 <<EOF>> {
155 BEGIN(INITIAL);
156 }
157}
158
159<STRING>{
160 [^'"\\\n]+/\n {
161 append_string(yytext, yyleng);
162 zconflval.string = text;
Eric Andersen72d8e442003-08-05 02:18:25 +0000163 return T_WORD_QUOTE;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000164 }
165 [^'"\\\n]+ {
166 append_string(yytext, yyleng);
167 }
168 \\.?/\n {
Eric Andersen72d8e442003-08-05 02:18:25 +0000169 append_string(yytext + 1, yyleng - 1);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000170 zconflval.string = text;
Eric Andersen72d8e442003-08-05 02:18:25 +0000171 return T_WORD_QUOTE;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000172 }
173 \\.? {
Eric Andersen72d8e442003-08-05 02:18:25 +0000174 append_string(yytext + 1, yyleng - 1);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000175 }
176 \'|\" {
177 if (str == yytext[0]) {
178 BEGIN(PARAM);
179 zconflval.string = text;
Eric Andersen72d8e442003-08-05 02:18:25 +0000180 return T_WORD_QUOTE;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000181 } else
182 append_string(yytext, 1);
183 }
184 \n {
185 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
Eric Andersen72d8e442003-08-05 02:18:25 +0000186 current_file->lineno++;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000187 BEGIN(INITIAL);
188 return T_EOL;
189 }
190 <<EOF>> {
191 BEGIN(INITIAL);
192 }
193}
194
195<HELP>{
196 [ \t]+ {
197 ts = 0;
198 for (i = 0; i < yyleng; i++) {
199 if (yytext[i] == '\t')
200 ts = (ts & ~7) + 8;
201 else
202 ts++;
203 }
204 last_ts = ts;
205 if (first_ts) {
206 if (ts < first_ts) {
207 zconf_endhelp();
208 return T_HELPTEXT;
209 }
210 ts -= first_ts;
211 while (ts > 8) {
212 append_string(" ", 8);
213 ts -= 8;
214 }
215 append_string(" ", ts);
216 }
Eric Andersenc9f20d92002-12-05 08:41:41 +0000217 }
Eric Andersen72d8e442003-08-05 02:18:25 +0000218 [ \t]*\n/[^ \t\n] {
Eric Andersenc9f20d92002-12-05 08:41:41 +0000219 current_file->lineno++;
220 zconf_endhelp();
221 return T_HELPTEXT;
222 }
223 [ \t]*\n {
224 current_file->lineno++;
225 append_string("\n", 1);
226 }
227 [^ \t\n].* {
228 append_string(yytext, yyleng);
229 if (!first_ts)
230 first_ts = last_ts;
231 }
232 <<EOF>> {
233 zconf_endhelp();
234 return T_HELPTEXT;
235 }
236}
237
238<<EOF>> {
239 if (current_buf) {
240 zconf_endfile();
241 return T_EOF;
242 }
243 fclose(yyin);
244 yyterminate();
245}
246
247%%
248void zconf_starthelp(void)
249{
250 new_string();
251 last_ts = first_ts = 0;
252 BEGIN(HELP);
253}
254
255static void zconf_endhelp(void)
256{
257 zconflval.string = text;
Eric Andersen72d8e442003-08-05 02:18:25 +0000258 BEGIN(INITIAL);
259}
260
261
262/*
263 * Try to open specified file with following names:
264 * ./name
265 * $(srctree)/name
266 * The latter is used when srctree is separate from objtree
267 * when compiling the kernel.
268 * Return NULL if file is not found.
269 */
270FILE *zconf_fopen(const char *name)
271{
272 char *env, fullname[PATH_MAX+1];
273 FILE *f;
274
275 f = fopen(name, "r");
276 if (!f && name[0] != '/') {
277 env = getenv(SRCTREE);
278 if (env) {
279 sprintf(fullname, "%s/%s", env, name);
280 f = fopen(fullname, "r");
281 }
282 }
283 return f;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000284}
285
286void zconf_initscan(const char *name)
287{
Eric Andersen72d8e442003-08-05 02:18:25 +0000288 yyin = zconf_fopen(name);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000289 if (!yyin) {
290 printf("can't find file %s\n", name);
291 exit(1);
292 }
293
294 current_buf = malloc(sizeof(*current_buf));
295 memset(current_buf, 0, sizeof(*current_buf));
296
297 current_file = file_lookup(name);
298 current_file->lineno = 1;
299 current_file->flags = FILE_BUSY;
300}
301
302void zconf_nextfile(const char *name)
303{
304 struct file *file = file_lookup(name);
305 struct buffer *buf = malloc(sizeof(*buf));
306 memset(buf, 0, sizeof(*buf));
307
308 current_buf->state = YY_CURRENT_BUFFER;
Eric Andersen72d8e442003-08-05 02:18:25 +0000309 yyin = zconf_fopen(name);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000310 if (!yyin) {
311 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
312 exit(1);
313 }
314 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
315 buf->parent = current_buf;
316 current_buf = buf;
317
318 if (file->flags & FILE_BUSY) {
319 printf("recursive scan (%s)?\n", name);
320 exit(1);
321 }
322 if (file->flags & FILE_SCANNED) {
323 printf("file %s already scanned?\n", name);
324 exit(1);
325 }
326 file->flags |= FILE_BUSY;
327 file->lineno = 1;
328 file->parent = current_file;
329 current_file = file;
330}
331
332static struct buffer *zconf_endfile(void)
333{
334 struct buffer *parent;
335
336 current_file->flags |= FILE_SCANNED;
337 current_file->flags &= ~FILE_BUSY;
338 current_file = current_file->parent;
339
340 parent = current_buf->parent;
341 if (parent) {
342 fclose(yyin);
343 yy_delete_buffer(YY_CURRENT_BUFFER);
344 yy_switch_to_buffer(parent->state);
345 }
346 free(current_buf);
347 current_buf = parent;
348
349 return parent;
350}
351
352int zconf_lineno(void)
353{
354 if (current_buf)
Eric Andersen72d8e442003-08-05 02:18:25 +0000355 return current_file->lineno - 1;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000356 else
357 return 0;
358}
359
360char *zconf_curname(void)
361{
362 if (current_buf)
363 return current_file->name;
364 else
365 return "<none>";
366}