blob: 658495cda2aea0d6ef48a77f3de27eb489a0ab5a [file] [log] [blame]
Eric Andersenc9f20d92002-12-05 08:41:41 +00001%{
2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 * Released under the terms of the GNU GPL v2.0.
5 */
6
7#include <ctype.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <stdbool.h>
13
14#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
15
16#define PRINTD 0x0001
17#define DEBUG_PARSE 0x0002
18
19int cdebug = PRINTD;
20
21extern int zconflex(void);
22static void zconfprint(const char *err, ...);
23static void zconferror(const char *err);
24static bool zconf_endtoken(int token, int starttoken, int endtoken);
25
26struct symbol *symbol_hash[257];
27
28#define YYERROR_VERBOSE
29%}
Eric Andersen72d8e442003-08-05 02:18:25 +000030%expect 40
Eric Andersenc9f20d92002-12-05 08:41:41 +000031
32%union
33{
34 int token;
35 char *string;
36 struct symbol *symbol;
37 struct expr *expr;
38 struct menu *menu;
39}
40
41%token T_MAINMENU
42%token T_MENU
43%token T_ENDMENU
44%token T_SOURCE
45%token T_CHOICE
46%token T_ENDCHOICE
47%token T_COMMENT
48%token T_CONFIG
Eric Andersen72d8e442003-08-05 02:18:25 +000049%token T_MENUCONFIG
Eric Andersenc9f20d92002-12-05 08:41:41 +000050%token T_HELP
51%token <string> T_HELPTEXT
52%token T_IF
53%token T_ENDIF
54%token T_DEPENDS
55%token T_REQUIRES
56%token T_OPTIONAL
57%token T_PROMPT
58%token T_DEFAULT
59%token T_TRISTATE
Eric Andersen72d8e442003-08-05 02:18:25 +000060%token T_DEF_TRISTATE
Eric Andersenc9f20d92002-12-05 08:41:41 +000061%token T_BOOLEAN
Eric Andersen72d8e442003-08-05 02:18:25 +000062%token T_DEF_BOOLEAN
63%token T_STRING
Eric Andersenc9f20d92002-12-05 08:41:41 +000064%token T_INT
65%token T_HEX
66%token <string> T_WORD
Eric Andersen72d8e442003-08-05 02:18:25 +000067%token <string> T_WORD_QUOTE
Eric Andersenc9f20d92002-12-05 08:41:41 +000068%token T_UNEQUAL
69%token T_EOF
70%token T_EOL
71%token T_CLOSE_PAREN
72%token T_OPEN_PAREN
73%token T_ON
Eric Andersen72d8e442003-08-05 02:18:25 +000074%token T_SELECT
75%token T_RANGE
Eric Andersenc9f20d92002-12-05 08:41:41 +000076
77%left T_OR
78%left T_AND
79%left T_EQUAL T_UNEQUAL
80%nonassoc T_NOT
81
82%type <string> prompt
83%type <string> source
84%type <symbol> symbol
85%type <expr> expr
86%type <expr> if_expr
87%type <token> end
88
89%{
90#define LKC_DIRECT_LINK
91#include "lkc.h"
92%}
93%%
94input: /* empty */
95 | input block
96;
97
98block: common_block
99 | choice_stmt
100 | menu_stmt
101 | T_MAINMENU prompt nl_or_eof
102 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
103 | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
104 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
105 | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
106;
107
108common_block:
109 if_stmt
110 | comment_stmt
111 | config_stmt
Eric Andersen72d8e442003-08-05 02:18:25 +0000112 | menuconfig_stmt
Eric Andersenc9f20d92002-12-05 08:41:41 +0000113 | source_stmt
114 | nl_or_eof
115;
116
117
Eric Andersen72d8e442003-08-05 02:18:25 +0000118/* config/menuconfig entry */
Eric Andersenc9f20d92002-12-05 08:41:41 +0000119
Eric Andersen72d8e442003-08-05 02:18:25 +0000120config_entry_start: T_CONFIG T_WORD T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000121{
122 struct symbol *sym = sym_lookup($2, 0);
123 sym->flags |= SYMBOL_OPTIONAL;
124 menu_add_entry(sym);
125 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
126};
127
Eric Andersen72d8e442003-08-05 02:18:25 +0000128config_stmt: config_entry_start config_option_list
Eric Andersenc9f20d92002-12-05 08:41:41 +0000129{
130 menu_end_entry();
131 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
132};
133
Eric Andersen72d8e442003-08-05 02:18:25 +0000134menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
135{
136 struct symbol *sym = sym_lookup($2, 0);
137 sym->flags |= SYMBOL_OPTIONAL;
138 menu_add_entry(sym);
139 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
140};
141
142menuconfig_stmt: menuconfig_entry_start config_option_list
143{
144 if (current_entry->prompt)
145 current_entry->prompt->type = P_MENU;
146 else
147 zconfprint("warning: menuconfig statement without prompt");
148 menu_end_entry();
149 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
150};
151
Eric Andersenc9f20d92002-12-05 08:41:41 +0000152config_option_list:
153 /* empty */
Eric Andersen72d8e442003-08-05 02:18:25 +0000154 | config_option_list config_option
155 | config_option_list depends
Eric Andersenc9f20d92002-12-05 08:41:41 +0000156 | config_option_list help
157 | config_option_list T_EOL
Eric Andersen72d8e442003-08-05 02:18:25 +0000158;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000159
Eric Andersen72d8e442003-08-05 02:18:25 +0000160config_option: T_TRISTATE prompt_stmt_opt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000161{
162 menu_set_type(S_TRISTATE);
163 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
164};
165
Eric Andersen72d8e442003-08-05 02:18:25 +0000166config_option: T_DEF_TRISTATE expr if_expr T_EOL
167{
168 menu_add_expr(P_DEFAULT, $2, $3);
169 menu_set_type(S_TRISTATE);
170 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
171};
172
173config_option: T_BOOLEAN prompt_stmt_opt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000174{
175 menu_set_type(S_BOOLEAN);
176 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
177};
178
Eric Andersen72d8e442003-08-05 02:18:25 +0000179config_option: T_DEF_BOOLEAN expr if_expr T_EOL
180{
181 menu_add_expr(P_DEFAULT, $2, $3);
182 menu_set_type(S_BOOLEAN);
183 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
184};
185
186config_option: T_INT prompt_stmt_opt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000187{
188 menu_set_type(S_INT);
189 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
190};
191
Eric Andersen72d8e442003-08-05 02:18:25 +0000192config_option: T_HEX prompt_stmt_opt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000193{
194 menu_set_type(S_HEX);
195 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
196};
197
Eric Andersen72d8e442003-08-05 02:18:25 +0000198config_option: T_STRING prompt_stmt_opt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000199{
200 menu_set_type(S_STRING);
201 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
202};
203
Eric Andersen72d8e442003-08-05 02:18:25 +0000204config_option: T_PROMPT prompt if_expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000205{
Eric Andersen72d8e442003-08-05 02:18:25 +0000206 menu_add_prompt(P_PROMPT, $2, $3);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000207 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
208};
209
Eric Andersen72d8e442003-08-05 02:18:25 +0000210config_option: T_DEFAULT expr if_expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000211{
Eric Andersen72d8e442003-08-05 02:18:25 +0000212 menu_add_expr(P_DEFAULT, $2, $3);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000213 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
214};
215
Eric Andersen72d8e442003-08-05 02:18:25 +0000216config_option: T_SELECT T_WORD if_expr T_EOL
217{
218 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
219 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
220};
221
222config_option: T_RANGE symbol symbol if_expr T_EOL
223{
224 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
225 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
226};
227
Eric Andersenc9f20d92002-12-05 08:41:41 +0000228/* choice entry */
229
Eric Andersen72d8e442003-08-05 02:18:25 +0000230choice: T_CHOICE T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000231{
232 struct symbol *sym = sym_lookup(NULL, 0);
233 sym->flags |= SYMBOL_CHOICE;
234 menu_add_entry(sym);
Eric Andersen72d8e442003-08-05 02:18:25 +0000235 menu_add_expr(P_CHOICE, NULL, NULL);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000236 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
237};
238
Eric Andersen72d8e442003-08-05 02:18:25 +0000239choice_entry: choice choice_option_list
Eric Andersenc9f20d92002-12-05 08:41:41 +0000240{
241 menu_end_entry();
242 menu_add_menu();
243};
244
245choice_end: end
246{
247 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
248 menu_end_menu();
249 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
250 }
251};
252
253choice_stmt:
Eric Andersen72d8e442003-08-05 02:18:25 +0000254 choice_entry choice_block choice_end
Eric Andersenc9f20d92002-12-05 08:41:41 +0000255 | choice_entry choice_block
256{
257 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
258 zconfnerrs++;
259};
260
261choice_option_list:
262 /* empty */
Eric Andersen72d8e442003-08-05 02:18:25 +0000263 | choice_option_list choice_option
264 | choice_option_list depends
Eric Andersenc9f20d92002-12-05 08:41:41 +0000265 | choice_option_list help
266 | choice_option_list T_EOL
267;
268
Eric Andersen72d8e442003-08-05 02:18:25 +0000269choice_option: T_PROMPT prompt if_expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000270{
Eric Andersen72d8e442003-08-05 02:18:25 +0000271 menu_add_prompt(P_PROMPT, $2, $3);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000272 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
273};
274
Eric Andersen72d8e442003-08-05 02:18:25 +0000275choice_option: T_TRISTATE prompt_stmt_opt T_EOL
276{
277 menu_set_type(S_TRISTATE);
278 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
279};
280
281choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
282{
283 menu_set_type(S_BOOLEAN);
284 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
285};
286
287choice_option: T_OPTIONAL T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000288{
289 current_entry->sym->flags |= SYMBOL_OPTIONAL;
290 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
291};
292
Eric Andersen72d8e442003-08-05 02:18:25 +0000293choice_option: T_DEFAULT T_WORD if_expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000294{
Eric Andersen72d8e442003-08-05 02:18:25 +0000295 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000296 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
297};
298
299choice_block:
300 /* empty */
301 | choice_block common_block
302;
303
304/* if entry */
305
Eric Andersen72d8e442003-08-05 02:18:25 +0000306if: T_IF expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000307{
308 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
309 menu_add_entry(NULL);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000310 menu_add_dep($2);
311 menu_end_entry();
312 menu_add_menu();
313};
314
315if_end: end
316{
317 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
318 menu_end_menu();
319 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
320 }
321};
322
323if_stmt:
Eric Andersen72d8e442003-08-05 02:18:25 +0000324 if if_block if_end
325 | if if_block
Eric Andersenc9f20d92002-12-05 08:41:41 +0000326{
327 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
328 zconfnerrs++;
329};
330
331if_block:
332 /* empty */
333 | if_block common_block
334 | if_block menu_stmt
335 | if_block choice_stmt
336;
337
338/* menu entry */
339
Eric Andersen72d8e442003-08-05 02:18:25 +0000340menu: T_MENU prompt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000341{
342 menu_add_entry(NULL);
343 menu_add_prop(P_MENU, $2, NULL, NULL);
344 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
345};
346
Eric Andersen72d8e442003-08-05 02:18:25 +0000347menu_entry: menu depends_list
Eric Andersenc9f20d92002-12-05 08:41:41 +0000348{
349 menu_end_entry();
350 menu_add_menu();
351};
352
353menu_end: end
354{
355 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
356 menu_end_menu();
357 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
358 }
359};
360
361menu_stmt:
Eric Andersen72d8e442003-08-05 02:18:25 +0000362 menu_entry menu_block menu_end
Eric Andersenc9f20d92002-12-05 08:41:41 +0000363 | menu_entry menu_block
364{
365 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
366 zconfnerrs++;
367};
368
369menu_block:
370 /* empty */
371 | menu_block common_block
372 | menu_block menu_stmt
373 | menu_block choice_stmt
374 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
375;
376
Eric Andersen72d8e442003-08-05 02:18:25 +0000377source: T_SOURCE prompt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000378{
379 $$ = $2;
380 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
381};
382
Eric Andersen72d8e442003-08-05 02:18:25 +0000383source_stmt: source
Eric Andersenc9f20d92002-12-05 08:41:41 +0000384{
385 zconf_nextfile($1);
386};
387
388/* comment entry */
389
Eric Andersen72d8e442003-08-05 02:18:25 +0000390comment: T_COMMENT prompt T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000391{
392 menu_add_entry(NULL);
393 menu_add_prop(P_COMMENT, $2, NULL, NULL);
394 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
395};
396
Eric Andersen72d8e442003-08-05 02:18:25 +0000397comment_stmt: comment depends_list
Eric Andersenc9f20d92002-12-05 08:41:41 +0000398{
399 menu_end_entry();
400};
401
402/* help option */
403
404help_start: T_HELP T_EOL
405{
406 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
407 zconf_starthelp();
408};
409
410help: help_start T_HELPTEXT
411{
412 current_entry->sym->help = $2;
413};
414
415/* depends option */
416
417depends_list: /* empty */
Eric Andersen72d8e442003-08-05 02:18:25 +0000418 | depends_list depends
Eric Andersenc9f20d92002-12-05 08:41:41 +0000419 | depends_list T_EOL
Eric Andersen72d8e442003-08-05 02:18:25 +0000420;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000421
Eric Andersen72d8e442003-08-05 02:18:25 +0000422depends: T_DEPENDS T_ON expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000423{
424 menu_add_dep($3);
425 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
426}
Eric Andersen72d8e442003-08-05 02:18:25 +0000427 | T_DEPENDS expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000428{
429 menu_add_dep($2);
430 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
431}
Eric Andersen72d8e442003-08-05 02:18:25 +0000432 | T_REQUIRES expr T_EOL
Eric Andersenc9f20d92002-12-05 08:41:41 +0000433{
434 menu_add_dep($2);
435 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
436};
437
438/* prompt statement */
439
440prompt_stmt_opt:
441 /* empty */
Eric Andersen72d8e442003-08-05 02:18:25 +0000442 | prompt if_expr
Eric Andersenc9f20d92002-12-05 08:41:41 +0000443{
Eric Andersen72d8e442003-08-05 02:18:25 +0000444 menu_add_prop(P_PROMPT, $1, NULL, $2);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000445};
446
447prompt: T_WORD
Eric Andersen72d8e442003-08-05 02:18:25 +0000448 | T_WORD_QUOTE
Eric Andersenc9f20d92002-12-05 08:41:41 +0000449;
450
Eric Andersen72d8e442003-08-05 02:18:25 +0000451end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
452 | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
453 | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
Eric Andersenc9f20d92002-12-05 08:41:41 +0000454;
455
456nl_or_eof:
457 T_EOL | T_EOF;
458
459if_expr: /* empty */ { $$ = NULL; }
460 | T_IF expr { $$ = $2; }
461;
462
463expr: symbol { $$ = expr_alloc_symbol($1); }
464 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
465 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
466 | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
467 | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
468 | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
469 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
470;
471
472symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
Eric Andersen72d8e442003-08-05 02:18:25 +0000473 | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
Eric Andersenc9f20d92002-12-05 08:41:41 +0000474;
475
476%%
477
478void conf_parse(const char *name)
479{
Eric Andersen72d8e442003-08-05 02:18:25 +0000480 struct symbol *sym;
481 int i;
482
Eric Andersenc9f20d92002-12-05 08:41:41 +0000483 zconf_initscan(name);
484
485 sym_init();
486 menu_init();
Eric Andersen72d8e442003-08-05 02:18:25 +0000487 modules_sym = sym_lookup("MODULES", 0);
Eric Andersen70014802003-08-05 05:59:48 +0000488 rootmenu.prompt = menu_add_prop(P_MENU, "BusyBox Configuration", NULL, NULL);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000489
490 //zconfdebug = 1;
491 zconfparse();
492 if (zconfnerrs)
493 exit(1);
494 menu_finalize(&rootmenu);
Eric Andersen72d8e442003-08-05 02:18:25 +0000495 for_all_symbols(i, sym) {
496 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
497 printf("\n");
498 else
499 sym->flags |= SYMBOL_CHECK_DONE;
500 }
Eric Andersenc9f20d92002-12-05 08:41:41 +0000501
502 sym_change_count = 1;
503}
504
505const char *zconf_tokenname(int token)
506{
507 switch (token) {
508 case T_MENU: return "menu";
509 case T_ENDMENU: return "endmenu";
510 case T_CHOICE: return "choice";
511 case T_ENDCHOICE: return "endchoice";
512 case T_IF: return "if";
513 case T_ENDIF: return "endif";
514 }
515 return "<token>";
Eric Andersen72d8e442003-08-05 02:18:25 +0000516}
Eric Andersenc9f20d92002-12-05 08:41:41 +0000517
518static bool zconf_endtoken(int token, int starttoken, int endtoken)
519{
520 if (token != endtoken) {
521 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
522 zconfnerrs++;
523 return false;
524 }
525 if (current_menu->file != current_file) {
526 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
527 zconfprint("location of the '%s'", zconf_tokenname(starttoken));
528 zconfnerrs++;
529 return false;
530 }
531 return true;
532}
533
534static void zconfprint(const char *err, ...)
535{
536 va_list ap;
537
Eric Andersen72d8e442003-08-05 02:18:25 +0000538 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000539 va_start(ap, err);
540 vfprintf(stderr, err, ap);
541 va_end(ap);
542 fprintf(stderr, "\n");
543}
544
545static void zconferror(const char *err)
546{
Eric Andersen72d8e442003-08-05 02:18:25 +0000547 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000548}
549
550void print_quoted_string(FILE *out, const char *str)
551{
552 const char *p;
553 int len;
554
555 putc('"', out);
556 while ((p = strchr(str, '"'))) {
557 len = p - str;
558 if (len)
559 fprintf(out, "%.*s", len, str);
560 fputs("\\\"", out);
561 str = p + 1;
562 }
563 fputs(str, out);
564 putc('"', out);
565}
566
567void print_symbol(FILE *out, struct menu *menu)
568{
569 struct symbol *sym = menu->sym;
570 struct property *prop;
571
Eric Andersenc9f20d92002-12-05 08:41:41 +0000572 if (sym_is_choice(sym))
573 fprintf(out, "choice\n");
574 else
575 fprintf(out, "config %s\n", sym->name);
576 switch (sym->type) {
577 case S_BOOLEAN:
578 fputs(" boolean\n", out);
579 break;
580 case S_TRISTATE:
581 fputs(" tristate\n", out);
582 break;
583 case S_STRING:
584 fputs(" string\n", out);
585 break;
586 case S_INT:
587 fputs(" integer\n", out);
588 break;
589 case S_HEX:
590 fputs(" hex\n", out);
591 break;
592 default:
593 fputs(" ???\n", out);
594 break;
595 }
Eric Andersenc9f20d92002-12-05 08:41:41 +0000596 for (prop = sym->prop; prop; prop = prop->next) {
597 if (prop->menu != menu)
598 continue;
599 switch (prop->type) {
600 case P_PROMPT:
601 fputs(" prompt ", out);
602 print_quoted_string(out, prop->text);
Eric Andersen72d8e442003-08-05 02:18:25 +0000603 if (!expr_is_yes(prop->visible.expr)) {
Eric Andersenc9f20d92002-12-05 08:41:41 +0000604 fputs(" if ", out);
Eric Andersen72d8e442003-08-05 02:18:25 +0000605 expr_fprint(prop->visible.expr, out);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000606 }
607 fputc('\n', out);
608 break;
609 case P_DEFAULT:
610 fputs( " default ", out);
Eric Andersen72d8e442003-08-05 02:18:25 +0000611 expr_fprint(prop->expr, out);
612 if (!expr_is_yes(prop->visible.expr)) {
Eric Andersenc9f20d92002-12-05 08:41:41 +0000613 fputs(" if ", out);
Eric Andersen72d8e442003-08-05 02:18:25 +0000614 expr_fprint(prop->visible.expr, out);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000615 }
616 fputc('\n', out);
617 break;
618 case P_CHOICE:
619 fputs(" #choice value\n", out);
620 break;
621 default:
622 fprintf(out, " unknown prop %d!\n", prop->type);
623 break;
624 }
625 }
626 if (sym->help) {
627 int len = strlen(sym->help);
628 while (sym->help[--len] == '\n')
629 sym->help[len] = 0;
630 fprintf(out, " help\n%s\n", sym->help);
631 }
632 fputc('\n', out);
633}
634
635void zconfdump(FILE *out)
636{
Eric Andersenc9f20d92002-12-05 08:41:41 +0000637 struct property *prop;
638 struct symbol *sym;
639 struct menu *menu;
640
641 menu = rootmenu.list;
642 while (menu) {
643 if ((sym = menu->sym))
644 print_symbol(out, menu);
645 else if ((prop = menu->prompt)) {
646 switch (prop->type) {
Eric Andersenc9f20d92002-12-05 08:41:41 +0000647 case P_COMMENT:
648 fputs("\ncomment ", out);
649 print_quoted_string(out, prop->text);
650 fputs("\n", out);
651 break;
652 case P_MENU:
653 fputs("\nmenu ", out);
654 print_quoted_string(out, prop->text);
655 fputs("\n", out);
656 break;
Eric Andersenc9f20d92002-12-05 08:41:41 +0000657 default:
658 ;
659 }
Eric Andersen72d8e442003-08-05 02:18:25 +0000660 if (!expr_is_yes(prop->visible.expr)) {
Eric Andersenc9f20d92002-12-05 08:41:41 +0000661 fputs(" depends ", out);
Eric Andersen72d8e442003-08-05 02:18:25 +0000662 expr_fprint(prop->visible.expr, out);
Eric Andersenc9f20d92002-12-05 08:41:41 +0000663 fputc('\n', out);
664 }
665 fputs("\n", out);
666 }
667
668 if (menu->list)
669 menu = menu->list;
670 else if (menu->next)
671 menu = menu->next;
672 else while ((menu = menu->parent)) {
673 if (menu->prompt && menu->prompt->type == P_MENU)
674 fputs("\nendmenu\n", out);
675 if (menu->next) {
676 menu = menu->next;
677 break;
678 }
679 }
680 }
681}
682
683#include "lex.zconf.c"
684#include "confdata.c"
685#include "expr.c"
686#include "symbol.c"
687#include "menu.c"