3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 * Released under the terms of the GNU GPL v2.0.
14 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
17 #define DEBUG_PARSE 0x0002
21 extern int zconflex(void);
22 static void zconfprint(const char *err, ...);
23 static void zconferror(const char *err);
24 static bool zconf_endtoken(int token, int starttoken, int endtoken);
26 struct symbol *symbol_hash[257];
28 #define YYERROR_VERBOSE
36 struct symbol *symbol;
51 %token <string> T_HELPTEXT
66 %token <string> T_WORD
67 %token <string> T_WORD_QUOTE
79 %left T_EQUAL T_UNEQUAL
90 #define LKC_DIRECT_LINK
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; }
118 /* config/menuconfig entry */
120 config_entry_start: T_CONFIG T_WORD T_EOL
122 struct symbol *sym = sym_lookup($2, 0);
123 sym->flags |= SYMBOL_OPTIONAL;
125 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
128 config_stmt: config_entry_start config_option_list
131 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
134 menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
136 struct symbol *sym = sym_lookup($2, 0);
137 sym->flags |= SYMBOL_OPTIONAL;
139 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
142 menuconfig_stmt: menuconfig_entry_start config_option_list
144 if (current_entry->prompt)
145 current_entry->prompt->type = P_MENU;
147 zconfprint("warning: menuconfig statement without prompt");
149 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
154 | config_option_list config_option
155 | config_option_list depends
156 | config_option_list help
157 | config_option_list T_EOL
160 config_option: T_TRISTATE prompt_stmt_opt T_EOL
162 menu_set_type(S_TRISTATE);
163 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
166 config_option: T_DEF_TRISTATE expr if_expr T_EOL
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());
173 config_option: T_BOOLEAN prompt_stmt_opt T_EOL
175 menu_set_type(S_BOOLEAN);
176 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
179 config_option: T_DEF_BOOLEAN expr if_expr T_EOL
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());
186 config_option: T_INT prompt_stmt_opt T_EOL
188 menu_set_type(S_INT);
189 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
192 config_option: T_HEX prompt_stmt_opt T_EOL
194 menu_set_type(S_HEX);
195 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
198 config_option: T_STRING prompt_stmt_opt T_EOL
200 menu_set_type(S_STRING);
201 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
204 config_option: T_PROMPT prompt if_expr T_EOL
206 menu_add_prompt(P_PROMPT, $2, $3);
207 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
210 config_option: T_DEFAULT expr if_expr T_EOL
212 menu_add_expr(P_DEFAULT, $2, $3);
213 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
216 config_option: T_SELECT T_WORD if_expr T_EOL
218 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
219 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
222 config_option: T_RANGE symbol symbol if_expr T_EOL
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());
230 choice: T_CHOICE T_EOL
232 struct symbol *sym = sym_lookup(NULL, 0);
233 sym->flags |= SYMBOL_CHOICE;
235 menu_add_expr(P_CHOICE, NULL, NULL);
236 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
239 choice_entry: choice choice_option_list
247 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
249 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
254 choice_entry choice_block choice_end
255 | choice_entry choice_block
257 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
263 | choice_option_list choice_option
264 | choice_option_list depends
265 | choice_option_list help
266 | choice_option_list T_EOL
269 choice_option: T_PROMPT prompt if_expr T_EOL
271 menu_add_prompt(P_PROMPT, $2, $3);
272 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
275 choice_option: T_TRISTATE prompt_stmt_opt T_EOL
277 menu_set_type(S_TRISTATE);
278 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
281 choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
283 menu_set_type(S_BOOLEAN);
284 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
287 choice_option: T_OPTIONAL T_EOL
289 current_entry->sym->flags |= SYMBOL_OPTIONAL;
290 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
293 choice_option: T_DEFAULT T_WORD if_expr T_EOL
295 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
296 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
301 | choice_block common_block
308 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
309 menu_add_entry(NULL);
317 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
319 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
327 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
333 | if_block common_block
335 | if_block choice_stmt
340 menu: T_MENU prompt T_EOL
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());
347 menu_entry: menu depends_list
355 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
357 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
362 menu_entry menu_block menu_end
363 | menu_entry menu_block
365 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
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; }
377 source: T_SOURCE prompt T_EOL
380 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
390 comment: T_COMMENT prompt T_EOL
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());
397 comment_stmt: comment depends_list
404 help_start: T_HELP T_EOL
406 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
410 help: help_start T_HELPTEXT
412 current_entry->sym->help = $2;
417 depends_list: /* empty */
418 | depends_list depends
422 depends: T_DEPENDS T_ON expr T_EOL
425 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
427 | T_DEPENDS expr T_EOL
430 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
432 | T_REQUIRES expr T_EOL
435 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
438 /* prompt statement */
444 menu_add_prop(P_PROMPT, $1, NULL, $2);
451 end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
452 | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
453 | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
459 if_expr: /* empty */ { $$ = NULL; }
460 | T_IF expr { $$ = $2; }
463 expr: 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); }
472 symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
473 | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
478 void conf_parse(const char *name)
483 zconf_initscan(name);
487 modules_sym = sym_lookup("MODULES", 0);
488 rootmenu.prompt = menu_add_prop(P_MENU, "Buildroot Configuration", NULL, NULL);
494 menu_finalize(&rootmenu);
495 for_all_symbols(i, sym) {
496 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
499 sym->flags |= SYMBOL_CHECK_DONE;
502 sym_change_count = 1;
505 const char *zconf_tokenname(int 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";
518 static bool zconf_endtoken(int token, int starttoken, int endtoken)
520 if (token != endtoken) {
521 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
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));
534 static void zconfprint(const char *err, ...)
538 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
540 vfprintf(stderr, err, ap);
542 fprintf(stderr, "\n");
545 static void zconferror(const char *err)
547 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
550 void print_quoted_string(FILE *out, const char *str)
556 while ((p = strchr(str, '"'))) {
559 fprintf(out, "%.*s", len, str);
567 void print_symbol(FILE *out, struct menu *menu)
569 struct symbol *sym = menu->sym;
570 struct property *prop;
572 if (sym_is_choice(sym))
573 fprintf(out, "choice\n");
575 fprintf(out, "config %s\n", sym->name);
578 fputs(" boolean\n", out);
581 fputs(" tristate\n", out);
584 fputs(" string\n", out);
587 fputs(" integer\n", out);
590 fputs(" hex\n", out);
593 fputs(" ???\n", out);
596 for (prop = sym->prop; prop; prop = prop->next) {
597 if (prop->menu != menu)
599 switch (prop->type) {
601 fputs(" prompt ", out);
602 print_quoted_string(out, prop->text);
603 if (!expr_is_yes(prop->visible.expr)) {
605 expr_fprint(prop->visible.expr, out);
610 fputs( " default ", out);
611 expr_fprint(prop->expr, out);
612 if (!expr_is_yes(prop->visible.expr)) {
614 expr_fprint(prop->visible.expr, out);
619 fputs(" #choice value\n", out);
622 fprintf(out, " unknown prop %d!\n", prop->type);
627 int len = strlen(sym->help);
628 while (sym->help[--len] == '\n')
630 fprintf(out, " help\n%s\n", sym->help);
635 void zconfdump(FILE *out)
637 struct property *prop;
641 menu = rootmenu.list;
643 if ((sym = menu->sym))
644 print_symbol(out, menu);
645 else if ((prop = menu->prompt)) {
646 switch (prop->type) {
648 fputs("\ncomment ", out);
649 print_quoted_string(out, prop->text);
653 fputs("\nmenu ", out);
654 print_quoted_string(out, prop->text);
660 if (!expr_is_yes(prop->visible.expr)) {
661 fputs(" depends ", out);
662 expr_fprint(prop->visible.expr, out);
672 else while ((menu = menu->parent)) {
673 if (menu->prompt && menu->prompt->type == P_MENU)
674 fputs("\nendmenu\n", out);
683 #include "lex.zconf.c"
684 #include "confdata.c"