3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 * Released under the terms of the GNU GPL v2.0.
14 #define LKC_DIRECT_LINK
17 #include "zconf.hash.c"
19 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
22 #define DEBUG_PARSE 0x0002
26 extern int zconflex(void);
27 static void zconfprint(const char *err, ...);
28 static void zconferror(const char *err);
29 static bool zconf_endtoken(int token, int starttoken, int endtoken);
31 struct symbol *symbol_hash[257];
33 static struct menu *current_menu, *current_entry;
35 #define YYERROR_VERBOSE
43 struct symbol *symbol;
58 %token <string> T_HELPTEXT
73 %token <string> T_WORD
74 %token <string> T_WORD_QUOTE
86 %left T_EQUAL T_UNEQUAL
104 | T_MAINMENU prompt nl_or_eof
105 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
106 | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
107 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
108 | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
121 /* config/menuconfig entry */
123 config_entry_start: T_CONFIG T_WORD T_EOL
125 struct symbol *sym = sym_lookup($2, 0);
126 sym->flags |= SYMBOL_OPTIONAL;
128 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
131 config_stmt: config_entry_start config_option_list
134 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
137 menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
139 struct symbol *sym = sym_lookup($2, 0);
140 sym->flags |= SYMBOL_OPTIONAL;
142 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
145 menuconfig_stmt: menuconfig_entry_start config_option_list
147 if (current_entry->prompt)
148 current_entry->prompt->type = P_MENU;
150 zconfprint("warning: menuconfig statement without prompt");
152 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
157 | config_option_list config_option
158 | config_option_list depends
159 | config_option_list help
160 | config_option_list T_EOL
163 config_option: T_TRISTATE prompt_stmt_opt T_EOL
165 menu_set_type(S_TRISTATE);
166 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
169 config_option: T_DEF_TRISTATE expr if_expr T_EOL
171 menu_add_expr(P_DEFAULT, $2, $3);
172 menu_set_type(S_TRISTATE);
173 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
176 config_option: T_BOOLEAN prompt_stmt_opt T_EOL
178 menu_set_type(S_BOOLEAN);
179 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
182 config_option: T_DEF_BOOLEAN expr if_expr T_EOL
184 menu_add_expr(P_DEFAULT, $2, $3);
185 menu_set_type(S_BOOLEAN);
186 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
189 config_option: T_INT prompt_stmt_opt T_EOL
191 menu_set_type(S_INT);
192 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
195 config_option: T_HEX prompt_stmt_opt T_EOL
197 menu_set_type(S_HEX);
198 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
201 config_option: T_STRING prompt_stmt_opt T_EOL
203 menu_set_type(S_STRING);
204 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
207 config_option: T_PROMPT prompt if_expr T_EOL
209 menu_add_prompt(P_PROMPT, $2, $3);
210 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
213 config_option: T_DEFAULT expr if_expr T_EOL
215 menu_add_expr(P_DEFAULT, $2, $3);
216 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
219 config_option: T_SELECT T_WORD if_expr T_EOL
221 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
222 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
225 config_option: T_RANGE symbol symbol if_expr T_EOL
227 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
228 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
233 choice: T_CHOICE T_EOL
235 struct symbol *sym = sym_lookup(NULL, 0);
236 sym->flags |= SYMBOL_CHOICE;
238 menu_add_expr(P_CHOICE, NULL, NULL);
239 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
242 choice_entry: choice choice_option_list
250 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
252 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
257 choice_entry choice_block choice_end
258 | choice_entry choice_block
260 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
266 | choice_option_list choice_option
267 | choice_option_list depends
268 | choice_option_list help
269 | choice_option_list T_EOL
272 choice_option: T_PROMPT prompt if_expr T_EOL
274 menu_add_prompt(P_PROMPT, $2, $3);
275 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
278 choice_option: T_TRISTATE prompt_stmt_opt T_EOL
280 menu_set_type(S_TRISTATE);
281 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
284 choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
286 menu_set_type(S_BOOLEAN);
287 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
290 choice_option: T_OPTIONAL T_EOL
292 current_entry->sym->flags |= SYMBOL_OPTIONAL;
293 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
296 choice_option: T_DEFAULT T_WORD if_expr T_EOL
298 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
299 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
304 | choice_block common_block
311 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
312 menu_add_entry(NULL);
320 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
322 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
330 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
336 | if_block common_block
338 | if_block choice_stmt
343 menu: T_MENU prompt T_EOL
345 menu_add_entry(NULL);
346 menu_add_prompt(P_MENU, $2, NULL);
347 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
350 menu_entry: menu depends_list
358 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
360 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
365 menu_entry menu_block menu_end
366 | menu_entry menu_block
368 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
374 | menu_block common_block
375 | menu_block menu_stmt
376 | menu_block choice_stmt
377 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
380 source: T_SOURCE prompt T_EOL
383 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
393 comment: T_COMMENT prompt T_EOL
395 menu_add_entry(NULL);
396 menu_add_prompt(P_COMMENT, $2, NULL);
397 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
400 comment_stmt: comment depends_list
407 help_start: T_HELP T_EOL
409 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
413 help: help_start T_HELPTEXT
415 current_entry->sym->help = $2;
420 depends_list: /* empty */
421 | depends_list depends
425 depends: T_DEPENDS T_ON expr T_EOL
428 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
430 | T_DEPENDS expr T_EOL
433 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
435 | T_REQUIRES expr T_EOL
438 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
441 /* prompt statement */
447 menu_add_prompt(P_PROMPT, $1, $2);
454 end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
455 | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
456 | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
462 if_expr: /* empty */ { $$ = NULL; }
463 | T_IF expr { $$ = $2; }
466 expr: symbol { $$ = expr_alloc_symbol($1); }
467 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
468 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
469 | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
470 | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
471 | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
472 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
475 symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
476 | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
481 void conf_parse(const char *name)
486 zconf_initscan(name);
490 modules_sym = sym_lookup("MODULES", 0);
491 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
497 menu_finalize(&rootmenu);
498 for_all_symbols(i, sym) {
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"
685 #include "confdata.c"