History

kconfig: fix conditional prompt behavior for choice

When a prompt is followed by "if <expr>", the symbol is configurable when the if-conditional evaluates to true. A typical usage is as follows: menuconfig BLOCK bool "Enable the block layer" if EXPERT default y When EXPERT=n, the prompt is hidden, but this config entry is still active, and BLOCK is set to its default value 'y'. When EXPERT=y, the prompt is shown, making BLOCK a user-configurable option. This usage is common throughout the kernel tree, but it has never worked within a choice block. [Test Code] config EXPERT bool "Allow expert users to modify more options" choice prompt "Choose" if EXPERT config A bool "A" config B bool "B" endchoice [Result] # CONFIG_EXPERT is not set When the prompt is hidden, the choice block should produce the default without asking for the user's preference. Hence, the output should be: # CONFIG_EXPERT is not set CONFIG_A=y # CONFIG_B is not set Removing unnecessary hacks fixes the issue. This commit also changes the behavior of 'select' by choice members. [Test Code 2] config MODULES def_bool y modules config DEP def_tristate m if DEP choice prompt "choose" config A bool "A" select C endchoice config B def_bool y select D endif config C tristate config D tristate The current output is as follows: CONFIG_MODULES=y CONFIG_DEP=m CONFIG_A=y CONFIG_B=y CONFIG_C=y CONFIG_D=m With this commit, the output will be changed as follows: CONFIG_MODULES=y CONFIG_DEP=m CONFIG_A=y CONFIG_B=y CONFIG_C=m CONFIG_D=m CONFIG_C will be changed to 'm' because 'select C' will inherit the dependency on DEP, which is 'm'. This change is aligned with the behavior of 'select' outside a choice block; 'select D' depends on DEP, therefore D is selected by (B && DEP). Note: With this commit, allmodconfig will set CONFIG_USB_ROLE_SWITCH to 'm' instead of 'y'. I did not see any build regression with this change.

Masahiro Yamada committed 2 years ago

Commit d5338281 parent b9d73212 files · +4 −36Browse files

Showing the changes to scripts (2 of 2 files). Show all

Unified · Split

2 files
  1. scripts/kconfig/menu.c +3 −35
  2. scripts/kconfig/symbol.c +1 −1
scripts/kconfig/menu.c+3−35
@@ -306,7 +306,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 305 unmodified lines
306306 struct menu *menu, *last_menu;
307307 struct symbol *sym;
308308 struct property *prop;
309− struct expr *parentdep, *basedep, *dep, *dep2;
309+ struct expr *basedep, *dep, *dep2;
310310
311311 sym = parent->sym;
312312 if (parent->list) {
@@ -315,24 +315,6 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 2 unmodified lines
315315 * and propagate parent dependencies before moving on.
316316 */
317317
318− bool is_choice = false;
319−
320− if (sym && sym_is_choice(sym))
321− is_choice = true;
322−
323− if (is_choice) {
324− /*
325− * Use the choice itself as the parent dependency of
326− * the contained items. This turns the mode of the
327− * choice into an upper bound on the visibility of the
328− * choice value symbols.
329− */
330− parentdep = expr_alloc_symbol(sym);
331− } else {
332− /* Menu node for 'menu', 'if' */
333− parentdep = parent->dep;
334− }
335−
336318 /* For each child menu node... */
337319 for (menu = parent->list; menu; menu = menu->next) {
338320 /*
@@ -341,7 +323,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 2 unmodified lines
341323 */
342324 basedep = rewrite_m(menu->dep);
343325 basedep = expr_transform(basedep);
344− basedep = expr_alloc_and(expr_copy(parentdep), basedep);
326+ basedep = expr_alloc_and(expr_copy(parent->dep), basedep);
345327 basedep = expr_eliminate_dups(basedep);
346328 menu->dep = basedep;
347329
@@ -405,15 +387,12 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 57 unmodified lines
405387 }
406388 }
407389
408− if (is_choice)
409− expr_free(parentdep);
410−
411390 /*
412391 * Recursively process children in the same fashion before
413392 * moving on
414393 */
415394 for (menu = parent->list; menu; menu = menu->next)
416− _menu_finalize(menu, is_choice);
395+ _menu_finalize(menu, sym && sym_is_choice(sym));
417396 } else if (!inside_choice && sym) {
418397 /*
419398 * Automatic submenu creation. If sym is a symbol and A, B, C,
@@ -541,17 +520,6 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 121 unmodified lines
541520 sym_check_prop(sym);
542521 sym->flags |= SYMBOL_WARNED;
543522 }
544−
545− /*
546− * For choices, add a reverse dependency (corresponding to a select) of
547− * '<visibility> && y'. This prevents the user from setting the choice
548− * mode to 'n' when the choice is visible.
549− */
550− if (sym && sym_is_choice(sym) && parent->prompt) {
551− sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
552− expr_alloc_and(parent->prompt->visible.expr,
553− expr_alloc_symbol(&symbol_yes)));
554− }
555523 }
556524
557525 void menu_finalize(void)
scripts/kconfig/symbol.c+1−1
@@ -868,7 +868,7 @@ const char *sym_get_string_value(struct symbol *sym) · 867 unmodified lines
868868
869869 bool sym_is_changeable(struct symbol *sym)
870870 {
871− return sym->visible > sym->rev_dep.tri;
871+ return !sym_is_choice(sym) && sym->visible > sym->rev_dep.tri;
872872 }
873873
874874 HASHTABLE_DEFINE(sym_hashtable, SYMBOL_HASHSIZE);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t