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.
Showing the changes to scripts (3 of 3 files). Show all
Unified · Split
| @@ -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 | */ | ||
| 747 | bool 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 | |||
| 741 | bool expr_depends_symbol(struct expr *dep, struct symbol *sym) | 774 | bool expr_depends_symbol(struct expr *dep, struct symbol *sym) |
| 742 | { | 775 | { |
| 743 | if (!dep) | 776 | if (!dep) |
| @@ -307,6 +307,7 @@ tristate expr_calc_value(struct expr *e); · 306 unmodified lines | |||
| 307 | struct expr *expr_eliminate_dups(struct expr *e); | 307 | struct expr *expr_eliminate_dups(struct expr *e); |
| 308 | struct expr *expr_transform(struct expr *e); | 308 | struct expr *expr_transform(struct expr *e); |
| 309 | bool expr_contains_symbol(struct expr *dep, struct symbol *sym); | 309 | bool expr_contains_symbol(struct expr *dep, struct symbol *sym); |
| 310 | bool expr_contains_symbol_negated(struct expr *dep, struct symbol *sym); | ||
| 310 | bool expr_depends_symbol(struct expr *dep, struct symbol *sym); | 311 | bool expr_depends_symbol(struct expr *dep, struct symbol *sym); |
| 311 | struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); | 312 | struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); |
| 312 | 313 | ||
| @@ -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 our | 446 | * Also consider it a dependency on sym if our |