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