13d0407baSopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 23d0407baSopenharmony_ci/* 33d0407baSopenharmony_ci * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 43d0407baSopenharmony_ci */ 53d0407baSopenharmony_ci%{ 63d0407baSopenharmony_ci 73d0407baSopenharmony_ci#include <ctype.h> 83d0407baSopenharmony_ci#include <stdarg.h> 93d0407baSopenharmony_ci#include <stdio.h> 103d0407baSopenharmony_ci#include <stdlib.h> 113d0407baSopenharmony_ci#include <string.h> 123d0407baSopenharmony_ci#include <stdbool.h> 133d0407baSopenharmony_ci#include <unistd.h> 143d0407baSopenharmony_ci 153d0407baSopenharmony_ci#include "lkc.h" 163d0407baSopenharmony_ci 173d0407baSopenharmony_ci#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 183d0407baSopenharmony_ci 193d0407baSopenharmony_ci#define PRINTD 0x0001 203d0407baSopenharmony_ci#define DEBUG_PARSE 0x0002 213d0407baSopenharmony_ci 223d0407baSopenharmony_ciint cdebug = PRINTD; 233d0407baSopenharmony_ci/* 243d0407baSopenharmony_cistatic const char *kconfig_white_list[] = { 253d0407baSopenharmony_ci "vendor/Kconfig", 263d0407baSopenharmony_ci "net/newip/Kconfig", 273d0407baSopenharmony_ci "net/newip/hooks/Kconfig", 283d0407baSopenharmony_ci}; 293d0407baSopenharmony_ci*/ 303d0407baSopenharmony_cistatic void yyerror(const char *err); 313d0407baSopenharmony_cistatic void zconfprint(const char *err, ...); 323d0407baSopenharmony_cistatic void zconf_error(const char *err, ...); 333d0407baSopenharmony_cistatic bool zconf_endtoken(const char *tokenname, 343d0407baSopenharmony_ci const char *expected_tokenname); 353d0407baSopenharmony_ci// static bool zconf_in_whitelist(const char *path); 363d0407baSopenharmony_ci 373d0407baSopenharmony_cistruct symbol *symbol_hash[SYMBOL_HASHSIZE]; 383d0407baSopenharmony_ci 393d0407baSopenharmony_cistatic struct menu *current_menu, *current_entry; 403d0407baSopenharmony_ci 413d0407baSopenharmony_ci%} 423d0407baSopenharmony_ci 433d0407baSopenharmony_ci%union 443d0407baSopenharmony_ci{ 453d0407baSopenharmony_ci char *string; 463d0407baSopenharmony_ci struct symbol *symbol; 473d0407baSopenharmony_ci struct expr *expr; 483d0407baSopenharmony_ci struct menu *menu; 493d0407baSopenharmony_ci enum symbol_type type; 503d0407baSopenharmony_ci enum variable_flavor flavor; 513d0407baSopenharmony_ci} 523d0407baSopenharmony_ci 533d0407baSopenharmony_ci%token <string> T_HELPTEXT 543d0407baSopenharmony_ci%token <string> T_WORD 553d0407baSopenharmony_ci%token <string> T_WORD_QUOTE 563d0407baSopenharmony_ci%token T_ALLNOCONFIG_Y 573d0407baSopenharmony_ci%token T_BOOL 583d0407baSopenharmony_ci%token T_CHOICE 593d0407baSopenharmony_ci%token T_CLOSE_PAREN 603d0407baSopenharmony_ci%token T_COLON_EQUAL 613d0407baSopenharmony_ci%token T_COMMENT 623d0407baSopenharmony_ci%token T_CONFIG 633d0407baSopenharmony_ci%token T_DEFAULT 643d0407baSopenharmony_ci%token T_DEFCONFIG_LIST 653d0407baSopenharmony_ci%token T_DEF_BOOL 663d0407baSopenharmony_ci%token T_DEF_TRISTATE 673d0407baSopenharmony_ci%token T_DEPENDS 683d0407baSopenharmony_ci%token T_ENDCHOICE 693d0407baSopenharmony_ci%token T_ENDIF 703d0407baSopenharmony_ci%token T_ENDMENU 713d0407baSopenharmony_ci%token T_HELP 723d0407baSopenharmony_ci%token T_HEX 733d0407baSopenharmony_ci%token T_IF 743d0407baSopenharmony_ci%token T_IMPLY 753d0407baSopenharmony_ci%token T_INT 763d0407baSopenharmony_ci%token T_MAINMENU 773d0407baSopenharmony_ci%token T_MENU 783d0407baSopenharmony_ci%token T_MENUCONFIG 793d0407baSopenharmony_ci%token T_MODULES 803d0407baSopenharmony_ci%token T_ON 813d0407baSopenharmony_ci%token T_OPEN_PAREN 823d0407baSopenharmony_ci%token T_OPTION 833d0407baSopenharmony_ci%token T_OPTIONAL 843d0407baSopenharmony_ci%token T_PLUS_EQUAL 853d0407baSopenharmony_ci%token T_PROMPT 863d0407baSopenharmony_ci%token T_RANGE 873d0407baSopenharmony_ci%token T_SELECT 883d0407baSopenharmony_ci%token T_SOURCE 893d0407baSopenharmony_ci%token T_STRING 903d0407baSopenharmony_ci%token T_TRISTATE 913d0407baSopenharmony_ci%token T_VISIBLE 923d0407baSopenharmony_ci%token T_EOL 933d0407baSopenharmony_ci%token <string> T_ASSIGN_VAL 943d0407baSopenharmony_ci 953d0407baSopenharmony_ci%left T_OR 963d0407baSopenharmony_ci%left T_AND 973d0407baSopenharmony_ci%left T_EQUAL T_UNEQUAL 983d0407baSopenharmony_ci%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL 993d0407baSopenharmony_ci%nonassoc T_NOT 1003d0407baSopenharmony_ci 1013d0407baSopenharmony_ci%type <symbol> nonconst_symbol 1023d0407baSopenharmony_ci%type <symbol> symbol 1033d0407baSopenharmony_ci%type <type> type logic_type default 1043d0407baSopenharmony_ci%type <expr> expr 1053d0407baSopenharmony_ci%type <expr> if_expr 1063d0407baSopenharmony_ci%type <string> end 1073d0407baSopenharmony_ci%type <menu> if_entry menu_entry choice_entry 1083d0407baSopenharmony_ci%type <string> word_opt assign_val 1093d0407baSopenharmony_ci%type <flavor> assign_op 1103d0407baSopenharmony_ci 1113d0407baSopenharmony_ci%destructor { 1123d0407baSopenharmony_ci fprintf(stderr, "%s:%d: missing end statement for this entry\n", 1133d0407baSopenharmony_ci $$->file->name, $$->lineno); 1143d0407baSopenharmony_ci if (current_menu == $$) 1153d0407baSopenharmony_ci menu_end_menu(); 1163d0407baSopenharmony_ci} if_entry menu_entry choice_entry 1173d0407baSopenharmony_ci 1183d0407baSopenharmony_ci%% 1193d0407baSopenharmony_ciinput: mainmenu_stmt stmt_list | stmt_list; 1203d0407baSopenharmony_ci 1213d0407baSopenharmony_ci/* mainmenu entry */ 1223d0407baSopenharmony_ci 1233d0407baSopenharmony_cimainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL 1243d0407baSopenharmony_ci{ 1253d0407baSopenharmony_ci menu_add_prompt(P_MENU, $2, NULL); 1263d0407baSopenharmony_ci}; 1273d0407baSopenharmony_ci 1283d0407baSopenharmony_cistmt_list: 1293d0407baSopenharmony_ci /* empty */ 1303d0407baSopenharmony_ci | stmt_list assignment_stmt 1313d0407baSopenharmony_ci | stmt_list choice_stmt 1323d0407baSopenharmony_ci | stmt_list comment_stmt 1333d0407baSopenharmony_ci | stmt_list config_stmt 1343d0407baSopenharmony_ci | stmt_list if_stmt 1353d0407baSopenharmony_ci | stmt_list menu_stmt 1363d0407baSopenharmony_ci | stmt_list menuconfig_stmt 1373d0407baSopenharmony_ci | stmt_list source_stmt 1383d0407baSopenharmony_ci | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } 1393d0407baSopenharmony_ci | stmt_list error T_EOL { zconf_error("invalid statement"); } 1403d0407baSopenharmony_ci; 1413d0407baSopenharmony_ci 1423d0407baSopenharmony_cistmt_list_in_choice: 1433d0407baSopenharmony_ci /* empty */ 1443d0407baSopenharmony_ci | stmt_list_in_choice comment_stmt 1453d0407baSopenharmony_ci | stmt_list_in_choice config_stmt 1463d0407baSopenharmony_ci | stmt_list_in_choice if_stmt_in_choice 1473d0407baSopenharmony_ci | stmt_list_in_choice error T_EOL { zconf_error("invalid statement"); } 1483d0407baSopenharmony_ci; 1493d0407baSopenharmony_ci 1503d0407baSopenharmony_ci/* config/menuconfig entry */ 1513d0407baSopenharmony_ci 1523d0407baSopenharmony_ciconfig_entry_start: T_CONFIG nonconst_symbol T_EOL 1533d0407baSopenharmony_ci{ 1543d0407baSopenharmony_ci $2->flags |= SYMBOL_OPTIONAL; 1553d0407baSopenharmony_ci menu_add_entry($2); 1563d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name); 1573d0407baSopenharmony_ci}; 1583d0407baSopenharmony_ci 1593d0407baSopenharmony_ciconfig_stmt: config_entry_start config_option_list 1603d0407baSopenharmony_ci{ 1613d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 1623d0407baSopenharmony_ci}; 1633d0407baSopenharmony_ci 1643d0407baSopenharmony_cimenuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL 1653d0407baSopenharmony_ci{ 1663d0407baSopenharmony_ci $2->flags |= SYMBOL_OPTIONAL; 1673d0407baSopenharmony_ci menu_add_entry($2); 1683d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name); 1693d0407baSopenharmony_ci}; 1703d0407baSopenharmony_ci 1713d0407baSopenharmony_cimenuconfig_stmt: menuconfig_entry_start config_option_list 1723d0407baSopenharmony_ci{ 1733d0407baSopenharmony_ci if (current_entry->prompt) 1743d0407baSopenharmony_ci current_entry->prompt->type = P_MENU; 1753d0407baSopenharmony_ci else 1763d0407baSopenharmony_ci zconfprint("warning: menuconfig statement without prompt"); 1773d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 1783d0407baSopenharmony_ci}; 1793d0407baSopenharmony_ci 1803d0407baSopenharmony_ciconfig_option_list: 1813d0407baSopenharmony_ci /* empty */ 1823d0407baSopenharmony_ci | config_option_list config_option 1833d0407baSopenharmony_ci | config_option_list depends 1843d0407baSopenharmony_ci | config_option_list help 1853d0407baSopenharmony_ci; 1863d0407baSopenharmony_ci 1873d0407baSopenharmony_ciconfig_option: type prompt_stmt_opt T_EOL 1883d0407baSopenharmony_ci{ 1893d0407baSopenharmony_ci menu_set_type($1); 1903d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:type(%u)\n", 1913d0407baSopenharmony_ci zconf_curname(), zconf_lineno(), 1923d0407baSopenharmony_ci $1); 1933d0407baSopenharmony_ci}; 1943d0407baSopenharmony_ci 1953d0407baSopenharmony_ciconfig_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL 1963d0407baSopenharmony_ci{ 1973d0407baSopenharmony_ci menu_add_prompt(P_PROMPT, $2, $3); 1983d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 1993d0407baSopenharmony_ci}; 2003d0407baSopenharmony_ci 2013d0407baSopenharmony_ciconfig_option: default expr if_expr T_EOL 2023d0407baSopenharmony_ci{ 2033d0407baSopenharmony_ci menu_add_expr(P_DEFAULT, $2, $3); 2043d0407baSopenharmony_ci if ($1 != S_UNKNOWN) 2053d0407baSopenharmony_ci menu_set_type($1); 2063d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:default(%u)\n", 2073d0407baSopenharmony_ci zconf_curname(), zconf_lineno(), 2083d0407baSopenharmony_ci $1); 2093d0407baSopenharmony_ci}; 2103d0407baSopenharmony_ci 2113d0407baSopenharmony_ciconfig_option: T_SELECT nonconst_symbol if_expr T_EOL 2123d0407baSopenharmony_ci{ 2133d0407baSopenharmony_ci menu_add_symbol(P_SELECT, $2, $3); 2143d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); 2153d0407baSopenharmony_ci}; 2163d0407baSopenharmony_ci 2173d0407baSopenharmony_ciconfig_option: T_IMPLY nonconst_symbol if_expr T_EOL 2183d0407baSopenharmony_ci{ 2193d0407baSopenharmony_ci menu_add_symbol(P_IMPLY, $2, $3); 2203d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); 2213d0407baSopenharmony_ci}; 2223d0407baSopenharmony_ci 2233d0407baSopenharmony_ciconfig_option: T_RANGE symbol symbol if_expr T_EOL 2243d0407baSopenharmony_ci{ 2253d0407baSopenharmony_ci menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); 2263d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); 2273d0407baSopenharmony_ci}; 2283d0407baSopenharmony_ci 2293d0407baSopenharmony_ciconfig_option: T_OPTION T_MODULES T_EOL 2303d0407baSopenharmony_ci{ 2313d0407baSopenharmony_ci menu_add_option_modules(); 2323d0407baSopenharmony_ci}; 2333d0407baSopenharmony_ci 2343d0407baSopenharmony_ciconfig_option: T_OPTION T_DEFCONFIG_LIST T_EOL 2353d0407baSopenharmony_ci{ 2363d0407baSopenharmony_ci menu_add_option_defconfig_list(); 2373d0407baSopenharmony_ci}; 2383d0407baSopenharmony_ci 2393d0407baSopenharmony_ciconfig_option: T_OPTION T_ALLNOCONFIG_Y T_EOL 2403d0407baSopenharmony_ci{ 2413d0407baSopenharmony_ci menu_add_option_allnoconfig_y(); 2423d0407baSopenharmony_ci}; 2433d0407baSopenharmony_ci 2443d0407baSopenharmony_ci/* choice entry */ 2453d0407baSopenharmony_ci 2463d0407baSopenharmony_cichoice: T_CHOICE word_opt T_EOL 2473d0407baSopenharmony_ci{ 2483d0407baSopenharmony_ci struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); 2493d0407baSopenharmony_ci sym->flags |= SYMBOL_NO_WRITE; 2503d0407baSopenharmony_ci menu_add_entry(sym); 2513d0407baSopenharmony_ci menu_add_expr(P_CHOICE, NULL, NULL); 2523d0407baSopenharmony_ci free($2); 2533d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); 2543d0407baSopenharmony_ci}; 2553d0407baSopenharmony_ci 2563d0407baSopenharmony_cichoice_entry: choice choice_option_list 2573d0407baSopenharmony_ci{ 2583d0407baSopenharmony_ci $$ = menu_add_menu(); 2593d0407baSopenharmony_ci}; 2603d0407baSopenharmony_ci 2613d0407baSopenharmony_cichoice_end: end 2623d0407baSopenharmony_ci{ 2633d0407baSopenharmony_ci if (zconf_endtoken($1, "choice")) { 2643d0407baSopenharmony_ci menu_end_menu(); 2653d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); 2663d0407baSopenharmony_ci } 2673d0407baSopenharmony_ci}; 2683d0407baSopenharmony_ci 2693d0407baSopenharmony_cichoice_stmt: choice_entry stmt_list_in_choice choice_end 2703d0407baSopenharmony_ci; 2713d0407baSopenharmony_ci 2723d0407baSopenharmony_cichoice_option_list: 2733d0407baSopenharmony_ci /* empty */ 2743d0407baSopenharmony_ci | choice_option_list choice_option 2753d0407baSopenharmony_ci | choice_option_list depends 2763d0407baSopenharmony_ci | choice_option_list help 2773d0407baSopenharmony_ci; 2783d0407baSopenharmony_ci 2793d0407baSopenharmony_cichoice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL 2803d0407baSopenharmony_ci{ 2813d0407baSopenharmony_ci menu_add_prompt(P_PROMPT, $2, $3); 2823d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 2833d0407baSopenharmony_ci}; 2843d0407baSopenharmony_ci 2853d0407baSopenharmony_cichoice_option: logic_type prompt_stmt_opt T_EOL 2863d0407baSopenharmony_ci{ 2873d0407baSopenharmony_ci menu_set_type($1); 2883d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:type(%u)\n", 2893d0407baSopenharmony_ci zconf_curname(), zconf_lineno(), $1); 2903d0407baSopenharmony_ci}; 2913d0407baSopenharmony_ci 2923d0407baSopenharmony_cichoice_option: T_OPTIONAL T_EOL 2933d0407baSopenharmony_ci{ 2943d0407baSopenharmony_ci current_entry->sym->flags |= SYMBOL_OPTIONAL; 2953d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); 2963d0407baSopenharmony_ci}; 2973d0407baSopenharmony_ci 2983d0407baSopenharmony_cichoice_option: T_DEFAULT nonconst_symbol if_expr T_EOL 2993d0407baSopenharmony_ci{ 3003d0407baSopenharmony_ci menu_add_symbol(P_DEFAULT, $2, $3); 3013d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:default\n", 3023d0407baSopenharmony_ci zconf_curname(), zconf_lineno()); 3033d0407baSopenharmony_ci}; 3043d0407baSopenharmony_ci 3053d0407baSopenharmony_citype: 3063d0407baSopenharmony_ci logic_type 3073d0407baSopenharmony_ci | T_INT { $$ = S_INT; } 3083d0407baSopenharmony_ci | T_HEX { $$ = S_HEX; } 3093d0407baSopenharmony_ci | T_STRING { $$ = S_STRING; } 3103d0407baSopenharmony_ci 3113d0407baSopenharmony_cilogic_type: 3123d0407baSopenharmony_ci T_BOOL { $$ = S_BOOLEAN; } 3133d0407baSopenharmony_ci | T_TRISTATE { $$ = S_TRISTATE; } 3143d0407baSopenharmony_ci 3153d0407baSopenharmony_cidefault: 3163d0407baSopenharmony_ci T_DEFAULT { $$ = S_UNKNOWN; } 3173d0407baSopenharmony_ci | T_DEF_BOOL { $$ = S_BOOLEAN; } 3183d0407baSopenharmony_ci | T_DEF_TRISTATE { $$ = S_TRISTATE; } 3193d0407baSopenharmony_ci 3203d0407baSopenharmony_ci/* if entry */ 3213d0407baSopenharmony_ci 3223d0407baSopenharmony_ciif_entry: T_IF expr T_EOL 3233d0407baSopenharmony_ci{ 3243d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 3253d0407baSopenharmony_ci menu_add_entry(NULL); 3263d0407baSopenharmony_ci menu_add_dep($2); 3273d0407baSopenharmony_ci $$ = menu_add_menu(); 3283d0407baSopenharmony_ci}; 3293d0407baSopenharmony_ci 3303d0407baSopenharmony_ciif_end: end 3313d0407baSopenharmony_ci{ 3323d0407baSopenharmony_ci if (zconf_endtoken($1, "if")) { 3333d0407baSopenharmony_ci menu_end_menu(); 3343d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); 3353d0407baSopenharmony_ci } 3363d0407baSopenharmony_ci}; 3373d0407baSopenharmony_ci 3383d0407baSopenharmony_ciif_stmt: if_entry stmt_list if_end 3393d0407baSopenharmony_ci; 3403d0407baSopenharmony_ci 3413d0407baSopenharmony_ciif_stmt_in_choice: if_entry stmt_list_in_choice if_end 3423d0407baSopenharmony_ci; 3433d0407baSopenharmony_ci 3443d0407baSopenharmony_ci/* menu entry */ 3453d0407baSopenharmony_ci 3463d0407baSopenharmony_cimenu: T_MENU T_WORD_QUOTE T_EOL 3473d0407baSopenharmony_ci{ 3483d0407baSopenharmony_ci menu_add_entry(NULL); 3493d0407baSopenharmony_ci menu_add_prompt(P_MENU, $2, NULL); 3503d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 3513d0407baSopenharmony_ci}; 3523d0407baSopenharmony_ci 3533d0407baSopenharmony_cimenu_entry: menu menu_option_list 3543d0407baSopenharmony_ci{ 3553d0407baSopenharmony_ci $$ = menu_add_menu(); 3563d0407baSopenharmony_ci}; 3573d0407baSopenharmony_ci 3583d0407baSopenharmony_cimenu_end: end 3593d0407baSopenharmony_ci{ 3603d0407baSopenharmony_ci if (zconf_endtoken($1, "menu")) { 3613d0407baSopenharmony_ci menu_end_menu(); 3623d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); 3633d0407baSopenharmony_ci } 3643d0407baSopenharmony_ci}; 3653d0407baSopenharmony_ci 3663d0407baSopenharmony_cimenu_stmt: menu_entry stmt_list menu_end 3673d0407baSopenharmony_ci; 3683d0407baSopenharmony_ci 3693d0407baSopenharmony_cimenu_option_list: 3703d0407baSopenharmony_ci /* empty */ 3713d0407baSopenharmony_ci | menu_option_list visible 3723d0407baSopenharmony_ci | menu_option_list depends 3733d0407baSopenharmony_ci; 3743d0407baSopenharmony_ci 3753d0407baSopenharmony_cisource_stmt: T_SOURCE T_WORD_QUOTE T_EOL 3763d0407baSopenharmony_ci{ 3773d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); 3783d0407baSopenharmony_ci// if (access(($2), F_OK) == 0 || zconf_in_whitelist($2) == false) { 3793d0407baSopenharmony_ci zconf_nextfile($2); 3803d0407baSopenharmony_ci// } 3813d0407baSopenharmony_ci free($2); 3823d0407baSopenharmony_ci}; 3833d0407baSopenharmony_ci 3843d0407baSopenharmony_ci/* comment entry */ 3853d0407baSopenharmony_ci 3863d0407baSopenharmony_cicomment: T_COMMENT T_WORD_QUOTE T_EOL 3873d0407baSopenharmony_ci{ 3883d0407baSopenharmony_ci menu_add_entry(NULL); 3893d0407baSopenharmony_ci menu_add_prompt(P_COMMENT, $2, NULL); 3903d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); 3913d0407baSopenharmony_ci}; 3923d0407baSopenharmony_ci 3933d0407baSopenharmony_cicomment_stmt: comment comment_option_list 3943d0407baSopenharmony_ci; 3953d0407baSopenharmony_ci 3963d0407baSopenharmony_cicomment_option_list: 3973d0407baSopenharmony_ci /* empty */ 3983d0407baSopenharmony_ci | comment_option_list depends 3993d0407baSopenharmony_ci; 4003d0407baSopenharmony_ci 4013d0407baSopenharmony_ci/* help option */ 4023d0407baSopenharmony_ci 4033d0407baSopenharmony_cihelp_start: T_HELP T_EOL 4043d0407baSopenharmony_ci{ 4053d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); 4063d0407baSopenharmony_ci zconf_starthelp(); 4073d0407baSopenharmony_ci}; 4083d0407baSopenharmony_ci 4093d0407baSopenharmony_cihelp: help_start T_HELPTEXT 4103d0407baSopenharmony_ci{ 4113d0407baSopenharmony_ci if (current_entry->help) { 4123d0407baSopenharmony_ci free(current_entry->help); 4133d0407baSopenharmony_ci zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used", 4143d0407baSopenharmony_ci current_entry->sym->name ?: "<choice>"); 4153d0407baSopenharmony_ci } 4163d0407baSopenharmony_ci 4173d0407baSopenharmony_ci /* Is the help text empty or all whitespace? */ 4183d0407baSopenharmony_ci if ($2[strspn($2, " \f\n\r\t\v")] == '\0') 4193d0407baSopenharmony_ci zconfprint("warning: '%s' defined with blank help text", 4203d0407baSopenharmony_ci current_entry->sym->name ?: "<choice>"); 4213d0407baSopenharmony_ci 4223d0407baSopenharmony_ci current_entry->help = $2; 4233d0407baSopenharmony_ci}; 4243d0407baSopenharmony_ci 4253d0407baSopenharmony_ci/* depends option */ 4263d0407baSopenharmony_ci 4273d0407baSopenharmony_cidepends: T_DEPENDS T_ON expr T_EOL 4283d0407baSopenharmony_ci{ 4293d0407baSopenharmony_ci menu_add_dep($3); 4303d0407baSopenharmony_ci printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); 4313d0407baSopenharmony_ci}; 4323d0407baSopenharmony_ci 4333d0407baSopenharmony_ci/* visibility option */ 4343d0407baSopenharmony_civisible: T_VISIBLE if_expr T_EOL 4353d0407baSopenharmony_ci{ 4363d0407baSopenharmony_ci menu_add_visibility($2); 4373d0407baSopenharmony_ci}; 4383d0407baSopenharmony_ci 4393d0407baSopenharmony_ci/* prompt statement */ 4403d0407baSopenharmony_ci 4413d0407baSopenharmony_ciprompt_stmt_opt: 4423d0407baSopenharmony_ci /* empty */ 4433d0407baSopenharmony_ci | T_WORD_QUOTE if_expr 4443d0407baSopenharmony_ci{ 4453d0407baSopenharmony_ci menu_add_prompt(P_PROMPT, $1, $2); 4463d0407baSopenharmony_ci}; 4473d0407baSopenharmony_ci 4483d0407baSopenharmony_ciend: T_ENDMENU T_EOL { $$ = "menu"; } 4493d0407baSopenharmony_ci | T_ENDCHOICE T_EOL { $$ = "choice"; } 4503d0407baSopenharmony_ci | T_ENDIF T_EOL { $$ = "if"; } 4513d0407baSopenharmony_ci; 4523d0407baSopenharmony_ci 4533d0407baSopenharmony_ciif_expr: /* empty */ { $$ = NULL; } 4543d0407baSopenharmony_ci | T_IF expr { $$ = $2; } 4553d0407baSopenharmony_ci; 4563d0407baSopenharmony_ci 4573d0407baSopenharmony_ciexpr: symbol { $$ = expr_alloc_symbol($1); } 4583d0407baSopenharmony_ci | symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); } 4593d0407baSopenharmony_ci | symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); } 4603d0407baSopenharmony_ci | symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); } 4613d0407baSopenharmony_ci | symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); } 4623d0407baSopenharmony_ci | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } 4633d0407baSopenharmony_ci | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } 4643d0407baSopenharmony_ci | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } 4653d0407baSopenharmony_ci | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } 4663d0407baSopenharmony_ci | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } 4673d0407baSopenharmony_ci | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } 4683d0407baSopenharmony_ci; 4693d0407baSopenharmony_ci 4703d0407baSopenharmony_ci/* For symbol definitions, selects, etc., where quotes are not accepted */ 4713d0407baSopenharmony_cinonconst_symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }; 4723d0407baSopenharmony_ci 4733d0407baSopenharmony_cisymbol: nonconst_symbol 4743d0407baSopenharmony_ci | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } 4753d0407baSopenharmony_ci; 4763d0407baSopenharmony_ci 4773d0407baSopenharmony_ciword_opt: /* empty */ { $$ = NULL; } 4783d0407baSopenharmony_ci | T_WORD 4793d0407baSopenharmony_ci 4803d0407baSopenharmony_ci/* assignment statement */ 4813d0407baSopenharmony_ci 4823d0407baSopenharmony_ciassignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } 4833d0407baSopenharmony_ci 4843d0407baSopenharmony_ciassign_op: 4853d0407baSopenharmony_ci T_EQUAL { $$ = VAR_RECURSIVE; } 4863d0407baSopenharmony_ci | T_COLON_EQUAL { $$ = VAR_SIMPLE; } 4873d0407baSopenharmony_ci | T_PLUS_EQUAL { $$ = VAR_APPEND; } 4883d0407baSopenharmony_ci; 4893d0407baSopenharmony_ci 4903d0407baSopenharmony_ciassign_val: 4913d0407baSopenharmony_ci /* empty */ { $$ = xstrdup(""); }; 4923d0407baSopenharmony_ci | T_ASSIGN_VAL 4933d0407baSopenharmony_ci; 4943d0407baSopenharmony_ci 4953d0407baSopenharmony_ci%% 4963d0407baSopenharmony_ci/* 4973d0407baSopenharmony_cistatic bool zconf_in_whitelist(const char *path) 4983d0407baSopenharmony_ci{ 4993d0407baSopenharmony_ci int i; 5003d0407baSopenharmony_ci for (i = 0; i < sizeof(kconfig_white_list) / sizeof(kconfig_white_list[0]); i++) { 5013d0407baSopenharmony_ci if(strcmp(kconfig_white_list[i], path) == 0) 5023d0407baSopenharmony_ci return true; 5033d0407baSopenharmony_ci } 5043d0407baSopenharmony_ci return false; 5053d0407baSopenharmony_ci} 5063d0407baSopenharmony_ci*/ 5073d0407baSopenharmony_civoid conf_parse(const char *name) 5083d0407baSopenharmony_ci{ 5093d0407baSopenharmony_ci struct symbol *sym; 5103d0407baSopenharmony_ci int i; 5113d0407baSopenharmony_ci 5123d0407baSopenharmony_ci zconf_initscan(name); 5133d0407baSopenharmony_ci 5143d0407baSopenharmony_ci _menu_init(); 5153d0407baSopenharmony_ci 5163d0407baSopenharmony_ci if (getenv("ZCONF_DEBUG")) 5173d0407baSopenharmony_ci yydebug = 1; 5183d0407baSopenharmony_ci yyparse(); 5193d0407baSopenharmony_ci 5203d0407baSopenharmony_ci /* Variables are expanded in the parse phase. We can free them here. */ 5213d0407baSopenharmony_ci variable_all_del(); 5223d0407baSopenharmony_ci 5233d0407baSopenharmony_ci if (yynerrs) 5243d0407baSopenharmony_ci exit(1); 5253d0407baSopenharmony_ci if (!modules_sym) 5263d0407baSopenharmony_ci modules_sym = sym_find( "n" ); 5273d0407baSopenharmony_ci 5283d0407baSopenharmony_ci if (!menu_has_prompt(&rootmenu)) { 5293d0407baSopenharmony_ci current_entry = &rootmenu; 5303d0407baSopenharmony_ci menu_add_prompt(P_MENU, "Main menu", NULL); 5313d0407baSopenharmony_ci } 5323d0407baSopenharmony_ci 5333d0407baSopenharmony_ci menu_finalize(&rootmenu); 5343d0407baSopenharmony_ci for_all_symbols(i, sym) { 5353d0407baSopenharmony_ci if (sym_check_deps(sym)) 5363d0407baSopenharmony_ci yynerrs++; 5373d0407baSopenharmony_ci } 5383d0407baSopenharmony_ci if (yynerrs) 5393d0407baSopenharmony_ci exit(1); 5403d0407baSopenharmony_ci sym_set_change_count(1); 5413d0407baSopenharmony_ci} 5423d0407baSopenharmony_ci 5433d0407baSopenharmony_cistatic bool zconf_endtoken(const char *tokenname, 5443d0407baSopenharmony_ci const char *expected_tokenname) 5453d0407baSopenharmony_ci{ 5463d0407baSopenharmony_ci if (strcmp(tokenname, expected_tokenname)) { 5473d0407baSopenharmony_ci zconf_error("unexpected '%s' within %s block", 5483d0407baSopenharmony_ci tokenname, expected_tokenname); 5493d0407baSopenharmony_ci yynerrs++; 5503d0407baSopenharmony_ci return false; 5513d0407baSopenharmony_ci } 5523d0407baSopenharmony_ci if (current_menu->file != current_file) { 5533d0407baSopenharmony_ci zconf_error("'%s' in different file than '%s'", 5543d0407baSopenharmony_ci tokenname, expected_tokenname); 5553d0407baSopenharmony_ci fprintf(stderr, "%s:%d: location of the '%s'\n", 5563d0407baSopenharmony_ci current_menu->file->name, current_menu->lineno, 5573d0407baSopenharmony_ci expected_tokenname); 5583d0407baSopenharmony_ci yynerrs++; 5593d0407baSopenharmony_ci return false; 5603d0407baSopenharmony_ci } 5613d0407baSopenharmony_ci return true; 5623d0407baSopenharmony_ci} 5633d0407baSopenharmony_ci 5643d0407baSopenharmony_cistatic void zconfprint(const char *err, ...) 5653d0407baSopenharmony_ci{ 5663d0407baSopenharmony_ci va_list ap; 5673d0407baSopenharmony_ci 5683d0407baSopenharmony_ci fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); 5693d0407baSopenharmony_ci va_start(ap, err); 5703d0407baSopenharmony_ci vfprintf(stderr, err, ap); 5713d0407baSopenharmony_ci va_end(ap); 5723d0407baSopenharmony_ci fprintf(stderr, "\n"); 5733d0407baSopenharmony_ci} 5743d0407baSopenharmony_ci 5753d0407baSopenharmony_cistatic void zconf_error(const char *err, ...) 5763d0407baSopenharmony_ci{ 5773d0407baSopenharmony_ci va_list ap; 5783d0407baSopenharmony_ci 5793d0407baSopenharmony_ci yynerrs++; 5803d0407baSopenharmony_ci fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); 5813d0407baSopenharmony_ci va_start(ap, err); 5823d0407baSopenharmony_ci vfprintf(stderr, err, ap); 5833d0407baSopenharmony_ci va_end(ap); 5843d0407baSopenharmony_ci fprintf(stderr, "\n"); 5853d0407baSopenharmony_ci} 5863d0407baSopenharmony_ci 5873d0407baSopenharmony_cistatic void yyerror(const char *err) 5883d0407baSopenharmony_ci{ 5893d0407baSopenharmony_ci fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); 5903d0407baSopenharmony_ci} 5913d0407baSopenharmony_ci 5923d0407baSopenharmony_cistatic void print_quoted_string(FILE *out, const char *str) 5933d0407baSopenharmony_ci{ 5943d0407baSopenharmony_ci const char *p; 5953d0407baSopenharmony_ci int len; 5963d0407baSopenharmony_ci 5973d0407baSopenharmony_ci putc('"', out); 5983d0407baSopenharmony_ci while ((p = strchr(str, '"'))) { 5993d0407baSopenharmony_ci len = p - str; 6003d0407baSopenharmony_ci if (len) 6013d0407baSopenharmony_ci fprintf(out, "%.*s", len, str); 6023d0407baSopenharmony_ci fputs("\\\"", out); 6033d0407baSopenharmony_ci str = p + 1; 6043d0407baSopenharmony_ci } 6053d0407baSopenharmony_ci fputs(str, out); 6063d0407baSopenharmony_ci putc('"', out); 6073d0407baSopenharmony_ci} 6083d0407baSopenharmony_ci 6093d0407baSopenharmony_cistatic void print_symbol(FILE *out, struct menu *menu) 6103d0407baSopenharmony_ci{ 6113d0407baSopenharmony_ci struct symbol *sym = menu->sym; 6123d0407baSopenharmony_ci struct property *prop; 6133d0407baSopenharmony_ci 6143d0407baSopenharmony_ci if (sym_is_choice(sym)) 6153d0407baSopenharmony_ci fprintf(out, "\nchoice\n"); 6163d0407baSopenharmony_ci else 6173d0407baSopenharmony_ci fprintf(out, "\nconfig %s\n", sym->name); 6183d0407baSopenharmony_ci switch (sym->type) { 6193d0407baSopenharmony_ci case S_BOOLEAN: 6203d0407baSopenharmony_ci fputs(" bool\n", out); 6213d0407baSopenharmony_ci break; 6223d0407baSopenharmony_ci case S_TRISTATE: 6233d0407baSopenharmony_ci fputs(" tristate\n", out); 6243d0407baSopenharmony_ci break; 6253d0407baSopenharmony_ci case S_STRING: 6263d0407baSopenharmony_ci fputs(" string\n", out); 6273d0407baSopenharmony_ci break; 6283d0407baSopenharmony_ci case S_INT: 6293d0407baSopenharmony_ci fputs(" integer\n", out); 6303d0407baSopenharmony_ci break; 6313d0407baSopenharmony_ci case S_HEX: 6323d0407baSopenharmony_ci fputs(" hex\n", out); 6333d0407baSopenharmony_ci break; 6343d0407baSopenharmony_ci default: 6353d0407baSopenharmony_ci fputs(" ???\n", out); 6363d0407baSopenharmony_ci break; 6373d0407baSopenharmony_ci } 6383d0407baSopenharmony_ci for (prop = sym->prop; prop; prop = prop->next) { 6393d0407baSopenharmony_ci if (prop->menu != menu) 6403d0407baSopenharmony_ci continue; 6413d0407baSopenharmony_ci switch (prop->type) { 6423d0407baSopenharmony_ci case P_PROMPT: 6433d0407baSopenharmony_ci fputs(" prompt ", out); 6443d0407baSopenharmony_ci print_quoted_string(out, prop->text); 6453d0407baSopenharmony_ci if (!expr_is_yes(prop->visible.expr)) { 6463d0407baSopenharmony_ci fputs(" if ", out); 6473d0407baSopenharmony_ci expr_fprint(prop->visible.expr, out); 6483d0407baSopenharmony_ci } 6493d0407baSopenharmony_ci fputc('\n', out); 6503d0407baSopenharmony_ci break; 6513d0407baSopenharmony_ci case P_DEFAULT: 6523d0407baSopenharmony_ci fputs( " default ", out); 6533d0407baSopenharmony_ci expr_fprint(prop->expr, out); 6543d0407baSopenharmony_ci if (!expr_is_yes(prop->visible.expr)) { 6553d0407baSopenharmony_ci fputs(" if ", out); 6563d0407baSopenharmony_ci expr_fprint(prop->visible.expr, out); 6573d0407baSopenharmony_ci } 6583d0407baSopenharmony_ci fputc('\n', out); 6593d0407baSopenharmony_ci break; 6603d0407baSopenharmony_ci case P_CHOICE: 6613d0407baSopenharmony_ci fputs(" #choice value\n", out); 6623d0407baSopenharmony_ci break; 6633d0407baSopenharmony_ci case P_SELECT: 6643d0407baSopenharmony_ci fputs( " select ", out); 6653d0407baSopenharmony_ci expr_fprint(prop->expr, out); 6663d0407baSopenharmony_ci fputc('\n', out); 6673d0407baSopenharmony_ci break; 6683d0407baSopenharmony_ci case P_IMPLY: 6693d0407baSopenharmony_ci fputs( " imply ", out); 6703d0407baSopenharmony_ci expr_fprint(prop->expr, out); 6713d0407baSopenharmony_ci fputc('\n', out); 6723d0407baSopenharmony_ci break; 6733d0407baSopenharmony_ci case P_RANGE: 6743d0407baSopenharmony_ci fputs( " range ", out); 6753d0407baSopenharmony_ci expr_fprint(prop->expr, out); 6763d0407baSopenharmony_ci fputc('\n', out); 6773d0407baSopenharmony_ci break; 6783d0407baSopenharmony_ci case P_MENU: 6793d0407baSopenharmony_ci fputs( " menu ", out); 6803d0407baSopenharmony_ci print_quoted_string(out, prop->text); 6813d0407baSopenharmony_ci fputc('\n', out); 6823d0407baSopenharmony_ci break; 6833d0407baSopenharmony_ci case P_SYMBOL: 6843d0407baSopenharmony_ci fputs( " symbol ", out); 6853d0407baSopenharmony_ci fprintf(out, "%s\n", prop->menu->sym->name); 6863d0407baSopenharmony_ci break; 6873d0407baSopenharmony_ci default: 6883d0407baSopenharmony_ci fprintf(out, " unknown prop %d!\n", prop->type); 6893d0407baSopenharmony_ci break; 6903d0407baSopenharmony_ci } 6913d0407baSopenharmony_ci } 6923d0407baSopenharmony_ci if (menu->help) { 6933d0407baSopenharmony_ci int len = strlen(menu->help); 6943d0407baSopenharmony_ci while (menu->help[--len] == '\n') 6953d0407baSopenharmony_ci menu->help[len] = 0; 6963d0407baSopenharmony_ci fprintf(out, " help\n%s\n", menu->help); 6973d0407baSopenharmony_ci } 6983d0407baSopenharmony_ci} 6993d0407baSopenharmony_ci 7003d0407baSopenharmony_civoid zconfdump(FILE *out) 7013d0407baSopenharmony_ci{ 7023d0407baSopenharmony_ci struct property *prop; 7033d0407baSopenharmony_ci struct symbol *sym; 7043d0407baSopenharmony_ci struct menu *menu; 7053d0407baSopenharmony_ci 7063d0407baSopenharmony_ci menu = rootmenu.list; 7073d0407baSopenharmony_ci while (menu) { 7083d0407baSopenharmony_ci if ((sym = menu->sym)) 7093d0407baSopenharmony_ci print_symbol(out, menu); 7103d0407baSopenharmony_ci else if ((prop = menu->prompt)) { 7113d0407baSopenharmony_ci switch (prop->type) { 7123d0407baSopenharmony_ci case P_COMMENT: 7133d0407baSopenharmony_ci fputs("\ncomment ", out); 7143d0407baSopenharmony_ci print_quoted_string(out, prop->text); 7153d0407baSopenharmony_ci fputs("\n", out); 7163d0407baSopenharmony_ci break; 7173d0407baSopenharmony_ci case P_MENU: 7183d0407baSopenharmony_ci fputs("\nmenu ", out); 7193d0407baSopenharmony_ci print_quoted_string(out, prop->text); 7203d0407baSopenharmony_ci fputs("\n", out); 7213d0407baSopenharmony_ci break; 7223d0407baSopenharmony_ci default: 7233d0407baSopenharmony_ci ; 7243d0407baSopenharmony_ci } 7253d0407baSopenharmony_ci if (!expr_is_yes(prop->visible.expr)) { 7263d0407baSopenharmony_ci fputs(" depends ", out); 7273d0407baSopenharmony_ci expr_fprint(prop->visible.expr, out); 7283d0407baSopenharmony_ci fputc('\n', out); 7293d0407baSopenharmony_ci } 7303d0407baSopenharmony_ci } 7313d0407baSopenharmony_ci 7323d0407baSopenharmony_ci if (menu->list) 7333d0407baSopenharmony_ci menu = menu->list; 7343d0407baSopenharmony_ci else if (menu->next) 7353d0407baSopenharmony_ci menu = menu->next; 7363d0407baSopenharmony_ci else while ((menu = menu->parent)) { 7373d0407baSopenharmony_ci if (menu->prompt && menu->prompt->type == P_MENU) 7383d0407baSopenharmony_ci fputs("\nendmenu\n", out); 7393d0407baSopenharmony_ci if (menu->next) { 7403d0407baSopenharmony_ci menu = menu->next; 7413d0407baSopenharmony_ci break; 7423d0407baSopenharmony_ci } 7433d0407baSopenharmony_ci } 7443d0407baSopenharmony_ci } 7453d0407baSopenharmony_ci} 7463d0407baSopenharmony_ci 7473d0407baSopenharmony_ci#include "menu.c" 748