]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
16 | #define LKC_DIRECT_LINK | |
17 | #include "lkc.h" | |
18 | ||
19 | #define START_STRSIZE 16 | |
20 | ||
21 | char *text; | |
22 | static char *text_ptr; | |
23 | static int text_size, text_asize; | |
24 | ||
25 | struct buffer { | |
26 | struct buffer *parent; | |
27 | YY_BUFFER_STATE state; | |
28 | }; | |
29 | ||
30 | struct buffer *current_buf; | |
31 | ||
32 | static int last_ts, first_ts; | |
33 | ||
34 | static void zconf_endhelp(void); | |
35 | static struct buffer *zconf_endfile(void); | |
36 | ||
37 | void 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 | ||
46 | void 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 | ||
60 | void 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 | ||
68 | ws [ \n\t] | |
69 | n [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; | |
99 | "menuconfig" BEGIN(PARAM); return T_MENUCONFIG; | |
100 | "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; | |
109 | "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE; | |
110 | "bool" BEGIN(PARAM); return T_BOOLEAN; | |
111 | "boolean" BEGIN(PARAM); return T_BOOLEAN; | |
112 | "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN; | |
113 | "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN; | |
114 | "int" BEGIN(PARAM); return T_INT; | |
115 | "hex" BEGIN(PARAM); return T_HEX; | |
116 | "string" BEGIN(PARAM); return T_STRING; | |
117 | "select" BEGIN(PARAM); return T_SELECT; | |
118 | "enable" BEGIN(PARAM); return T_SELECT; | |
119 | "range" BEGIN(PARAM); return T_RANGE; | |
120 | {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 | } | |
151 | #.* /* comment */ | |
152 | \\\n current_file->lineno++; | |
153 | . | |
154 | <<EOF>> { | |
155 | BEGIN(INITIAL); | |
156 | } | |
157 | } | |
158 | ||
159 | <STRING>{ | |
160 | [^'"\\\n]+/\n { | |
161 | append_string(yytext, yyleng); | |
162 | zconflval.string = text; | |
163 | return T_WORD_QUOTE; | |
164 | } | |
165 | [^'"\\\n]+ { | |
166 | append_string(yytext, yyleng); | |
167 | } | |
168 | \\.?/\n { | |
169 | append_string(yytext + 1, yyleng - 1); | |
170 | zconflval.string = text; | |
171 | return T_WORD_QUOTE; | |
172 | } | |
173 | \\.? { | |
174 | append_string(yytext + 1, yyleng - 1); | |
175 | } | |
176 | \'|\" { | |
177 | if (str == yytext[0]) { | |
178 | BEGIN(PARAM); | |
179 | zconflval.string = text; | |
180 | return T_WORD_QUOTE; | |
181 | } else | |
182 | append_string(yytext, 1); | |
183 | } | |
184 | \n { | |
185 | printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); | |
186 | current_file->lineno++; | |
187 | 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 | } | |
217 | } | |
218 | [ \t]*\n/[^ \t\n] { | |
219 | 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 | %% | |
248 | void zconf_starthelp(void) | |
249 | { | |
250 | new_string(); | |
251 | last_ts = first_ts = 0; | |
252 | BEGIN(HELP); | |
253 | } | |
254 | ||
255 | static void zconf_endhelp(void) | |
256 | { | |
257 | zconflval.string = text; | |
258 | 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 | */ | |
270 | FILE *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; | |
284 | } | |
285 | ||
286 | void zconf_initscan(const char *name) | |
287 | { | |
288 | yyin = zconf_fopen(name); | |
289 | 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 | ||
302 | void 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; | |
309 | yyin = zconf_fopen(name); | |
310 | 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 | ||
332 | static 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 | ||
352 | int zconf_lineno(void) | |
353 | { | |
354 | if (current_buf) | |
355 | return current_file->lineno - 1; | |
356 | else | |
357 | return 0; | |
358 | } | |
359 | ||
360 | char *zconf_curname(void) | |
361 | { | |
362 | if (current_buf) | |
363 | return current_file->name; | |
364 | else | |
365 | return "<none>"; | |
366 | } |