From 09d5873e4d1f70202314b5fe40160f9b14b9d2d0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 24 Apr 2020 14:49:29 +0900 Subject: [PATCH] kconfig: allow only 'config', 'comment', and 'if' inside 'choice' The code block surrounded by 'if' ... 'endif' is reduced into if_stmt, which is accepted in the 'choice' context. Therefore, you can write any statements within a choice block by wrapping 'if y' ... 'end'. For example, you can create a menu inside a choice, like follows: ---------------->8---------------- choice prompt "choice" config A bool "A" config B bool "B" if y menu "strange menu" config C bool "C" endmenu endif endchoice ---------------->8---------------- I want to change such a weird structure into a syntax error. In fact, the USB gadget Kconfig had used nested 'choice' for no good reason until commit df8df5e4bc37 ("usb: get rid of 'choice' for legacy gadget drivers") killed it. I think the 'source' inside 'choice' is on the fence. It is at least gramatically sensible as long as the included file contains only bool/tristate configs. However, it makes the code unreadable, and people tend to forget the fact that the file is included from the choice block. Commit 10e5e6c24963 ("usb: gadget: move choice ... endchoice to legacy/Kconfig") got rid of the only usecase. Going forward, you can only use 'config', 'comment', and 'if' inside 'choice'. This also recursively applies to 'if' blocks inside 'choice'. Signed-off-by: Masahiro Yamada --- scripts/kconfig/parser.y | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 708b6c4..190f111 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -119,20 +119,24 @@ mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL stmt_list: /* empty */ - | stmt_list common_stmt + | stmt_list assignment_stmt | stmt_list choice_stmt + | stmt_list comment_stmt + | stmt_list config_stmt + | stmt_list if_stmt | stmt_list menu_stmt + | stmt_list menuconfig_stmt + | stmt_list source_stmt | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } | stmt_list error T_EOL { zconf_error("invalid statement"); } ; -common_stmt: - if_stmt - | comment_stmt - | config_stmt - | menuconfig_stmt - | source_stmt - | assignment_stmt +stmt_list_in_choice: + /* empty */ + | stmt_list_in_choice comment_stmt + | stmt_list_in_choice config_stmt + | stmt_list_in_choice if_stmt_in_choice + | stmt_list_in_choice error T_EOL { zconf_error("invalid statement"); } ; /* config/menuconfig entry */ @@ -254,7 +258,7 @@ choice_end: end } }; -choice_stmt: choice_entry choice_block choice_end +choice_stmt: choice_entry stmt_list_in_choice choice_end ; choice_option_list: @@ -305,11 +309,6 @@ default: | T_DEF_BOOL { $$ = S_BOOLEAN; } | T_DEF_TRISTATE { $$ = S_TRISTATE; } -choice_block: - /* empty */ - | choice_block common_stmt -; - /* if entry */ if_entry: T_IF expr T_EOL @@ -331,6 +330,9 @@ if_end: end if_stmt: if_entry stmt_list if_end ; +if_stmt_in_choice: if_entry stmt_list_in_choice if_end +; + /* menu entry */ menu: T_MENU T_WORD_QUOTE T_EOL -- 2.7.4