kconfig: remove string expansion for mainmenu after yyparse()
[carl9170fw.git] / config / zconf.y
index 79c4f04f72fa819bfdb7548a736f1c16fcf37ec8..228a14b24faee961505cb3e473fbcac0d4c5c80b 100644 (file)
 
 int cdebug = PRINTD;
 
-extern int zconflex(void);
+int yylex(void);
+static void yyerror(const char *err);
 static void zconfprint(const char *err, ...);
 static void zconf_error(const char *err, ...);
-static void zconferror(const char *err);
 static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken);
 
 struct symbol *symbol_hash[SYMBOL_HASHSIZE];
@@ -85,6 +85,7 @@ static struct menu *current_menu, *current_entry;
 %nonassoc T_NOT
 
 %type <string> prompt
+%type <symbol> nonconst_symbol
 %type <symbol> symbol
 %type <expr> expr
 %type <expr> if_expr
@@ -101,7 +102,7 @@ static struct menu *current_menu, *current_entry;
 } if_entry menu_entry choice_entry
 
 %{
-/* Include zconf_id.c here so it can see the token constants. */
+/* Include kconf_id.c here so it can see the token constants. */
 #include "kconf_id.c"
 %}
 
@@ -110,6 +111,13 @@ input: nl start | start;
 
 start: mainmenu_stmt stmt_list | stmt_list;
 
+/* mainmenu entry */
+
+mainmenu_stmt: T_MAINMENU prompt nl
+{
+       menu_add_prompt(P_MENU, $2, NULL);
+};
+
 stmt_list:
          /* empty */
        | stmt_list common_stmt
@@ -145,26 +153,23 @@ option_error:
 
 /* config/menuconfig entry */
 
-config_entry_start: T_CONFIG T_WORD T_EOL
+config_entry_start: T_CONFIG nonconst_symbol T_EOL
 {
-       struct symbol *sym = sym_lookup($2, 0);
-       sym->flags |= SYMBOL_OPTIONAL;
-       menu_add_entry(sym);
-       printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
+       $2->flags |= SYMBOL_OPTIONAL;
+       menu_add_entry($2);
+       printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name);
 };
 
 config_stmt: config_entry_start config_option_list
 {
-       menu_end_entry();
        printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
 };
 
-menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
+menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
 {
-       struct symbol *sym = sym_lookup($2, 0);
-       sym->flags |= SYMBOL_OPTIONAL;
-       menu_add_entry(sym);
-       printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
+       $2->flags |= SYMBOL_OPTIONAL;
+       menu_add_entry($2);
+       printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name);
 };
 
 menuconfig_stmt: menuconfig_entry_start config_option_list
@@ -173,7 +178,6 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
                current_entry->prompt->type = P_MENU;
        else
                zconfprint("warning: menuconfig statement without prompt");
-       menu_end_entry();
        printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
 };
 
@@ -211,15 +215,15 @@ config_option: T_DEFAULT expr if_expr T_EOL
                $1->stype);
 };
 
-config_option: T_SELECT T_WORD if_expr T_EOL
+config_option: T_SELECT nonconst_symbol if_expr T_EOL
 {
-       menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
+       menu_add_symbol(P_SELECT, $2, $3);
        printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_IMPLY T_WORD if_expr T_EOL
+config_option: T_IMPLY nonconst_symbol if_expr T_EOL
 {
-       menu_add_symbol(P_IMPLY, sym_lookup($2, 0), $3);
+       menu_add_symbol(P_IMPLY, $2, $3);
        printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno());
 };
 
@@ -237,8 +241,10 @@ symbol_option_list:
        | symbol_option_list T_WORD symbol_option_arg
 {
        const struct kconf_id *id = kconf_id_lookup($2, strlen($2));
-       if (id && id->flags & TF_OPTION)
+       if (id && id->flags & TF_OPTION) {
                menu_add_option(id->token, $3);
+               free($3);
+       }
        else
                zconfprint("warning: ignoring unknown option %s", $2);
        free($2);
@@ -257,6 +263,7 @@ choice: T_CHOICE word_opt T_EOL
        sym->flags |= SYMBOL_AUTO;
        menu_add_entry(sym);
        menu_add_expr(P_CHOICE, NULL, NULL);
+       free($2);
        printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
 };
 
@@ -308,10 +315,10 @@ choice_option: T_OPTIONAL T_EOL
        printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
 };
 
-choice_option: T_DEFAULT T_WORD if_expr T_EOL
+choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
 {
        if ($1->stype == S_UNKNOWN) {
-               menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
+               menu_add_symbol(P_DEFAULT, $2, $3);
                printd(DEBUG_PARSE, "%s:%d:default\n",
                        zconf_curname(), zconf_lineno());
        } else
@@ -351,13 +358,6 @@ if_block:
        | if_block choice_stmt
 ;
 
-/* mainmenu entry */
-
-mainmenu_stmt: T_MAINMENU prompt nl
-{
-       menu_add_prompt(P_MENU, $2, NULL);
-};
-
 /* menu entry */
 
 menu: T_MENU prompt T_EOL
@@ -394,6 +394,7 @@ source_stmt: T_SOURCE prompt T_EOL
 {
        printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
        zconf_nextfile($2);
+       free($2);
 };
 
 /* comment entry */
@@ -406,9 +407,7 @@ comment: T_COMMENT prompt T_EOL
 };
 
 comment_stmt: comment depends_list
-{
-       menu_end_entry();
-};
+;
 
 /* help option */
 
@@ -420,6 +419,17 @@ help_start: T_HELP T_EOL
 
 help: help_start T_HELPTEXT
 {
+       if (current_entry->help) {
+               free(current_entry->help);
+               zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used",
+                          current_entry->sym->name ?: "<choice>");
+       }
+
+       /* Is the help text empty or all whitespace? */
+       if ($2[strspn($2, " \f\n\r\t\v")] == '\0')
+               zconfprint("warning: '%s' defined with blank help text",
+                          current_entry->sym->name ?: "<choice>");
+
        current_entry->help = $2;
 };
 
@@ -491,7 +501,10 @@ expr:        symbol                                { $$ = expr_alloc_symbol($1); }
        | expr T_AND expr                       { $$ = expr_alloc_two(E_AND, $1, $3); }
 ;
 
-symbol:          T_WORD        { $$ = sym_lookup($1, 0); free($1); }
+/* For symbol definitions, selects, etc., where quotes are not accepted */
+nonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); };
+
+symbol:          nonconst_symbol
        | T_WORD_QUOTE  { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
 ;
 
@@ -507,27 +520,28 @@ void conf_parse(const char *name)
 
        zconf_initscan(name);
 
-       sym_init();
        _menu_init();
        rootmenu.prompt = menu_add_prompt(P_MENU, "CARL9170 Firmware Configuration", NULL);
 
        if (getenv("ZCONF_DEBUG"))
-               zconfdebug = 1;
-       zconfparse();
-       if (zconfnerrs)
+               yydebug = 1;
+       yyparse();
+       if (yynerrs)
                exit(1);
        if (!modules_sym)
                modules_sym = sym_find( "n" );
 
-       rootmenu.prompt->text = _(rootmenu.prompt->text);
-       rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
+       if (!menu_has_prompt(&rootmenu)) {
+               current_entry = &rootmenu;
+               menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
+       }
 
        menu_finalize(&rootmenu);
        for_all_symbols(i, sym) {
                if (sym_check_deps(sym))
-                       zconfnerrs++;
+                       yynerrs++;
        }
-       if (zconfnerrs)
+       if (yynerrs)
                exit(1);
        sym_set_change_count(1);
 }
@@ -552,7 +566,7 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok
        if (id->token != endtoken) {
                zconf_error("unexpected '%s' within %s block",
                        id->name, zconf_tokenname(starttoken));
-               zconfnerrs++;
+               yynerrs++;
                return false;
        }
        if (current_menu->file != current_file) {
@@ -561,7 +575,7 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok
                fprintf(stderr, "%s:%d: location of the '%s'\n",
                        current_menu->file->name, current_menu->lineno,
                        zconf_tokenname(starttoken));
-               zconfnerrs++;
+               yynerrs++;
                return false;
        }
        return true;
@@ -582,7 +596,7 @@ static void zconf_error(const char *err, ...)
 {
        va_list ap;
 
-       zconfnerrs++;
+       yynerrs++;
        fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
        va_start(ap, err);
        vfprintf(stderr, err, ap);
@@ -590,7 +604,7 @@ static void zconf_error(const char *err, ...)
        fprintf(stderr, "\n");
 }
 
-static void zconferror(const char *err)
+static void yyerror(const char *err)
 {
        fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
 }
@@ -623,7 +637,7 @@ static void print_symbol(FILE *out, struct menu *menu)
                fprintf(out, "\nconfig %s\n", sym->name);
        switch (sym->type) {
        case S_BOOLEAN:
-               fputs("  boolean\n", out);
+               fputs("  bool\n", out);
                break;
        case S_TRISTATE:
                fputs("  tristate\n", out);
@@ -752,3 +766,4 @@ void zconfdump(FILE *out)
 #include "expr.c"
 #include "symbol.c"
 #include "menu.c"
+#include "preprocess.c"