History

kconfig: fix submenu rendering of negative dependencies

The Kconfig frontend should render options that depend on a previous option in the submenu of that previous option. But currently, this breaks for negative dependencies. For example, option FOO may be rendered in the submenu of option BAR, despite FOO actually depending on !BAR. Let's fix this ironic rendering by modifying Kconfig to explicitly check negative dependencies. I've only tested locally on x86, but as far as I can tell, this only changes how 2 options are rendered in the menu: 1. NTFS3_FS, no longer in the NTFS_FS submenu, and 2. MTD_BLOCK_RO, no longer in the MTD_BLOCK submenu.

Julian Braha committed 3 months ago

Commit 35e4b601 parent 14b8b4b3 files · +44 −0Browse files

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

Unified · Split

3 files
  1. scripts/kconfig/expr.c +33 −0
  2. scripts/kconfig/expr.h +1 −0
  3. scripts/kconfig/menu.c +10 −0
scripts/kconfig/expr.c+33−0
@@ -738,6 +738,39 @@ bool expr_contains_symbol(struct expr *dep, struct symbol *sym) · 737 unmodified lines
738 return false;738 return false;
739}739}
740 740
741/*
742 * Check if the expression references 'sym' in a way that is satisfiable
743 * with 'sym' disabled, e.g.'sym!=y'.
744 *
745 * Expects that expr_transform() was already called on 'expr'.
746 */
747bool expr_contains_symbol_negated(struct expr *dep, struct symbol *sym)
748{
749 if (!dep)
750 return false;
751
752 switch (dep->type) {
753 case E_AND:
754 case E_OR:
755 return expr_contains_symbol_negated(dep->left.expr, sym) ||
756 expr_contains_symbol_negated(dep->right.expr, sym);
757 case E_NOT:
758 return dep->left.expr->type == E_SYMBOL &&
759 dep->left.expr->left.sym == sym;
760 case E_EQUAL:
761 /* sym=n */
762 return dep->left.sym == sym && dep->right.sym == &symbol_no;
763 case E_UNEQUAL:
764 /* sym!=y, sym!=m */
765 return dep->left.sym == sym &&
766 (dep->right.sym == &symbol_yes ||
767 dep->right.sym == &symbol_mod);
768 default:
769 break;
770 }
771 return false;
772}
773
741bool expr_depends_symbol(struct expr *dep, struct symbol *sym)774bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
742{775{
743 if (!dep)776 if (!dep)
scripts/kconfig/expr.h+1−0
@@ -307,6 +307,7 @@ tristate expr_calc_value(struct expr *e); · 306 unmodified lines
307struct expr *expr_eliminate_dups(struct expr *e);307struct expr *expr_eliminate_dups(struct expr *e);
308struct expr *expr_transform(struct expr *e);308struct expr *expr_transform(struct expr *e);
309bool expr_contains_symbol(struct expr *dep, struct symbol *sym);309bool expr_contains_symbol(struct expr *dep, struct symbol *sym);
310bool expr_contains_symbol_negated(struct expr *dep, struct symbol *sym);
310bool expr_depends_symbol(struct expr *dep, struct symbol *sym);311bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
311struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);312struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
312 313
scripts/kconfig/menu.c+10−0
@@ -428,9 +428,19 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 427 unmodified lines
428 if (!expr_contains_symbol(dep, sym))428 if (!expr_contains_symbol(dep, sym))
429 /* No dependency, quit */429 /* No dependency, quit */
430 break;430 break;
431 /*
432 * Note that it's actually possible to depend on both
433 * 'SYM!=y' and 'SYM=y', so we need to first check if
434 * it's a positive dependency before checking if it's
435 * a negative dependency. See example:
436 * 'SFC && MTD && !(SFC=y && MTD=m)'
437 */
431 if (expr_depends_symbol(dep, sym))438 if (expr_depends_symbol(dep, sym))
432 /* Absolute dependency, put in submenu */439 /* Absolute dependency, put in submenu */
433 goto next;440 goto next;
441 if (expr_contains_symbol_negated(dep, sym))
442 /* Negative dependency, quit */
443 break;
434 444
435 /*445 /*
436 * Also consider it a dependency on sym if our446 * Also consider it a dependency on sym if our