History

kconfig: remove tristate choice support

I previously submitted a fix for a bug in the choice feature [1], where I mentioned, "Another (much cleaner) approach would be to remove the tristate choice support entirely". There are more issues in the tristate choice feature. For example, you can observe a couple of bugs in the following test code. [Test Code] config MODULES def_bool y modules choice prompt "tristate choice" default A config A tristate "A" config B tristate "B" endchoice Bug 1: the 'default' property is not correctly processed 'make alldefconfig' produces: CONFIG_MODULES=y # CONFIG_A is not set # CONFIG_B is not set However, the correct output should be: CONFIG_MODULES=y CONFIG_A=y # CONFIG_B is not set The unit test file, scripts/kconfig/tests/choice/alldef_expected_config, is wrong as well. Bug 2: choice members never get 'y' with randconfig For the test code above, the following combinations are possible: A B (1) y n (2) n y (3) m m (4) m n (5) n m (6) n n 'make randconfig' never produces (1) or (2). These bugs are fixable, but a more critical problem is the lack of a sensible syntax to specify the default for the tristate choice. The default for the choice must be one of the choice members, which cannot specify any of the patterns (3) through (6) above. In addition, I have never seen it being used in a useful way. The following commits removed unnecessary use of tristate choices: - df8df5e4bc37 ("usb: get rid of 'choice' for legacy gadget drivers") - bfb57ef0544a ("rapidio: remove choice for enumeration") This commit removes the tristate choice support entirely, which allows me to delete a lot of code, making further refactoring easier. Note: This includes the revert of commit fa64e5f6a35e ("kconfig/symbol.c: handle choice_values that depend on 'm' symbols"). It was suspicious because it did not address the root cause but introduced inconsistency in visibility between choice members and other symbols. [1]: https://lore.kernel.org/linux-kbuild/20240427104231.2728905-1-masahiroy@kernel.org/T/#m0a1bb6992581462ceca861b409bb33cb8fd7dbae

Masahiro Yamada committed 2 years ago

Commit fde19251 parent 03638aa28 files · +45 −325Browse files

Unified · Split

28 files
  1. Documentation/kbuild/kconfig-language.rst +3 −10
  2. scripts/kconfig/conf.c +6 −50
  3. scripts/kconfig/confdata.c +3 −14
  4. scripts/kconfig/gconf.c +2 −4
  5. scripts/kconfig/mconf.c +7 −21
  6. scripts/kconfig/menu.c +2 −29
  7. scripts/kconfig/nconf.c +5 −23
  8. scripts/kconfig/parser.y +14 −9
  9. scripts/kconfig/qconf.cc +1 −1
  10. scripts/kconfig/symbol.c +2 −20
  11. scripts/kconfig/tests/choice/Kconfig +0 −17
  12. scripts/kconfig/tests/choice/__init__.py +0 −10
  13. scripts/kconfig/tests/choice/alldef_expected_config +0 −3
  14. scripts/kconfig/tests/choice/allmod_expected_config +0 −3
  15. scripts/kconfig/tests/choice/allno_expected_config +0 −3
  16. scripts/kconfig/tests/choice/allyes_expected_config +0 −3
  17. scripts/kconfig/tests/choice/oldask0_expected_stdout +0 −4
  18. scripts/kconfig/tests/choice/oldask1_config +0 −1
  19. scripts/kconfig/tests/choice/oldask1_expected_stdout +0 −9
  20. scripts/kconfig/tests/choice_value_with_m_dep/Kconfig +0 −21
  21. scripts/kconfig/tests/choice_value_with_m_dep/__init__.py +0 −16
  22. scripts/kconfig/tests/choice_value_with_m_dep/config +0 −2
  23. scripts/kconfig/tests/choice_value_with_m_dep/expected_config +0 −3
  24. scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout +0 −4
  25. scripts/kconfig/tests/inter_choice/Kconfig +0 −25
  26. scripts/kconfig/tests/inter_choice/__init__.py +0 −15
  27. scripts/kconfig/tests/inter_choice/defconfig +0 −1
  28. scripts/kconfig/tests/inter_choice/expected_config +0 −4
Documentation/kbuild/kconfig-language.rst+3−10
@@ -409,16 +409,9 @@ choices:: · 408 unmodified lines
409 "endchoice"409 "endchoice"
410 410
411This defines a choice group and accepts any of the above attributes as411This defines a choice group and accepts any of the above attributes as
412options. A choice can only be of type bool or tristate. If no type is412options.
413specified for a choice, its type will be determined by the type of413
414the first choice element in the group or remain unknown if none of the414A choice only allows a single config entry to be selected.
415choice elements have a type specified, as well.
416
417While a boolean choice only allows a single config entry to be
418selected, a tristate choice also allows any number of config entries
419to be set to 'm'. This can be used if multiple drivers for a single
420hardware exists and only a single driver can be compiled/loaded into
421the kernel, but all drivers can be compiled as modules.
422 415
423comment::416comment::
424 417
scripts/kconfig/conf.c+6−50
@@ -114,21 +114,13 @@ static void set_randconfig_seed(void) · 113 unmodified lines
114 srand(seed);114 srand(seed);
115}115}
116 116
117static bool randomize_choice_values(struct symbol *csym)117static void randomize_choice_values(struct symbol *csym)
118{118{
119 struct property *prop;119 struct property *prop;
120 struct symbol *sym;120 struct symbol *sym;
121 struct expr *e;121 struct expr *e;
122 int cnt, def;122 int cnt, def;
123 123
124 /*
125 * If choice is mod then we may have more items selected
126 * and if no then no-one.
127 * In both cases stop.
128 */
129 if (csym->curr.tri != yes)
130 return false;
131
132 prop = sym_get_choice_prop(csym);124 prop = sym_get_choice_prop(csym);
133 125
134 /* count entries in choice block */126 /* count entries in choice block */
@@ -157,8 +149,6 @@ static bool randomize_choice_values(struct symbol *csym) · 22 unmodified lines
157 csym->flags |= SYMBOL_DEF_USER;149 csym->flags |= SYMBOL_DEF_USER;
158 /* clear VALID to get value calculated */150 /* clear VALID to get value calculated */
159 csym->flags &= ~SYMBOL_VALID;151 csym->flags &= ~SYMBOL_VALID;
160
161 return true;
162}152}
163 153
164enum conf_def_mode {154enum conf_def_mode {
@@ -269,15 +259,6 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode) · 104 unmodified lines
269 259
270 sym_clear_all_valid();260 sym_clear_all_valid();
271 261
272 /*
273 * We have different type of choice blocks.
274 * If curr.tri equals to mod then we can select several
275 * choice symbols in one block.
276 * In this case we do nothing.
277 * If curr.tri equals yes then only one symbol can be
278 * selected in a choice block and we set it to yes,
279 * and the rest to no.
280 */
281 if (mode != def_random) {262 if (mode != def_random) {
282 for_all_symbols(csym) {263 for_all_symbols(csym) {
283 if ((sym_is_choice(csym) && !sym_has_value(csym)) ||264 if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
@@ -292,11 +273,10 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode) · 8 unmodified lines
292 273
293 sym_calc_value(csym);274 sym_calc_value(csym);
294 if (mode == def_random)275 if (mode == def_random)
295 has_changed |= randomize_choice_values(csym);276 randomize_choice_values(csym);
296 else {277 else
297 set_all_choice_values(csym);278 set_all_choice_values(csym);
298 has_changed = true;279 has_changed = true;
299 }
300 }280 }
301 281
302 return has_changed;282 return has_changed;
@@ -454,27 +434,6 @@ static void conf_choice(struct menu *menu) · 151 unmodified lines
454 434
455 sym = menu->sym;435 sym = menu->sym;
456 is_new = !sym_has_value(sym);436 is_new = !sym_has_value(sym);
457 if (sym_is_changeable(sym)) {
458 conf_sym(menu);
459 sym_calc_value(sym);
460 switch (sym_get_tristate_value(sym)) {
461 case no:
462 case mod:
463 return;
464 case yes:
465 break;
466 }
467 } else {
468 switch (sym_get_tristate_value(sym)) {
469 case no:
470 return;
471 case mod:
472 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
473 return;
474 case yes:
475 break;
476 }
477 }
478 437
479 while (1) {438 while (1) {
480 int cnt, def;439 int cnt, def;
@@ -596,9 +555,7 @@ static void conf(struct menu *menu) · 115 unmodified lines
596 555
597 if (sym_is_choice(sym)) {556 if (sym_is_choice(sym)) {
598 conf_choice(menu);557 conf_choice(menu);
599 if (sym->curr.tri != mod)558 return;
600 return;
601 goto conf_childs;
602 }559 }
603 560
604 switch (sym->type) {561 switch (sym->type) {
@@ -631,8 +588,7 @@ static void check_conf(struct menu *menu) · 26 unmodified lines
631 588
632 sym = menu->sym;589 sym = menu->sym;
633 if (sym && !sym_has_value(sym) &&590 if (sym && !sym_has_value(sym) &&
634 (sym_is_changeable(sym) ||591 (sym_is_changeable(sym) || sym_is_choice(sym))) {
635 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
636 592
637 switch (input_mode) {593 switch (input_mode) {
638 case listnewconfig:594 case listnewconfig:
scripts/kconfig/confdata.c+3−14
@@ -462,22 +462,12 @@ load: · 461 unmodified lines
462 462
463 if (sym && sym_is_choice_value(sym)) {463 if (sym && sym_is_choice_value(sym)) {
464 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));464 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
465 switch (sym->def[def].tri) {465 if (sym->def[def].tri == yes) {
466 case no:
467 break;
468 case mod:
469 if (cs->def[def].tri == yes) {
470 conf_warning("%s creates inconsistent choice state", sym->name);
471 cs->flags &= ~def_flags;
472 }
473 break;
474 case yes:
475 if (cs->def[def].tri != no)466 if (cs->def[def].tri != no)
476 conf_warning("override: %s changes choice state", sym->name);467 conf_warning("override: %s changes choice state", sym->name);
477 cs->def[def].val = sym;468 cs->def[def].val = sym;
478 break;469 cs->def[def].tri = yes;
479 }470 }
480 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
481 }471 }
482 }472 }
483 free(line);473 free(line);
@@ -806,8 +796,7 @@ int conf_write_defconfig(const char *filename) · 322 unmodified lines
806 796
807 ds = sym_choice_default(choice->sym);797 ds = sym_choice_default(choice->sym);
808 if (sym == ds) {798 if (sym == ds) {
809 if ((sym->type == S_BOOLEAN) &&799 if (sym_get_tristate_value(sym) == yes)
810 sym_get_tristate_value(sym) == yes)
811 continue;800 continue;
812 }801 }
813 }802 }
scripts/kconfig/gconf.c+2−4
@@ -1067,10 +1067,8 @@ static gchar **fill_row(struct menu *menu) · 1066 unmodified lines
1067 row[COL_VALUE] =1067 row[COL_VALUE] =
1068 g_strdup(menu_get_prompt(def_menu));1068 g_strdup(menu_get_prompt(def_menu));
1069 1069
1070 if (sym_get_type(sym) == S_BOOLEAN) {1070 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1071 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);1071 return row;
1072 return row;
1073 }
1074 }1072 }
1075 if (sym->flags & SYMBOL_CHOICEVAL)1073 if (sym->flags & SYMBOL_CHOICEVAL)
1076 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);1074 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
scripts/kconfig/mconf.c+7−21
@@ -523,28 +523,14 @@ static void build_conf(struct menu *menu) · 522 unmodified lines
523 def_menu = child;523 def_menu = child;
524 }524 }
525 525
526 val = sym_get_tristate_value(sym);526 item_make(" ");
527 if (sym_is_changeable(sym)) {527 item_set_tag(def_menu ? 't' : ':');
528 switch (val) {528 item_set_data(menu);
529 case yes: ch = '*'; break;
530 case mod: ch = 'M'; break;
531 default: ch = ' '; break;
532 }
533 item_make("<%c>", ch);
534 item_set_tag('t');
535 item_set_data(menu);
536 } else {
537 item_make(" ");
538 item_set_tag(def_menu ? 't' : ':');
539 item_set_data(menu);
540 }
541 529
542 item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));530 item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
543 if (val == yes) {531 if (def_menu)
544 if (def_menu)532 item_add_str(" (%s) --->", menu_get_prompt(def_menu));
545 item_add_str(" (%s) --->", menu_get_prompt(def_menu));533 return;
546 return;
547 }
548 } else {534 } else {
549 if (menu == current_menu) {535 if (menu == current_menu) {
550 item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));536 item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
@@ -814,7 +800,7 @@ static void conf(struct menu *menu, struct menu *active_menu) · 263 unmodified lines
814 conf(submenu, NULL);800 conf(submenu, NULL);
815 break;801 break;
816 case 't':802 case 't':
817 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)803 if (sym_is_choice(sym))
818 conf_choice(submenu);804 conf_choice(submenu);
819 else if (submenu->prompt->type == P_MENU)805 else if (submenu->prompt->type == P_MENU)
820 conf(submenu, NULL);806 conf(submenu, NULL);
scripts/kconfig/menu.c+2−29
@@ -321,17 +321,6 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 320 unmodified lines
321 is_choice = true;321 is_choice = true;
322 322
323 if (is_choice) {323 if (is_choice) {
324 if (sym->type == S_UNKNOWN) {
325 /* find the first choice value to find out choice type */
326 current_entry = parent;
327 for (menu = parent->list; menu; menu = menu->next) {
328 if (menu->sym && menu->sym->type != S_UNKNOWN) {
329 menu_set_type(menu->sym->type);
330 break;
331 }
332 }
333 }
334
335 /*324 /*
336 * Use the choice itself as the parent dependency of325 * Use the choice itself as the parent dependency of
337 * the contained items. This turns the mode of the326 * the contained items. This turns the mode of the
@@ -503,22 +492,6 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 165 unmodified lines
503 menu->sym && !sym_is_choice_value(menu->sym)) {492 menu->sym && !sym_is_choice_value(menu->sym)) {
504 current_entry = menu;493 current_entry = menu;
505 menu->sym->flags |= SYMBOL_CHOICEVAL;494 menu->sym->flags |= SYMBOL_CHOICEVAL;
506 /* Non-tristate choice values of tristate choices must
507 * depend on the choice being set to Y. The choice
508 * values' dependencies were propagated to their
509 * properties above, so the change here must be re-
510 * propagated.
511 */
512 if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
513 basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
514 menu->dep = expr_alloc_and(basedep, menu->dep);
515 for (prop = menu->sym->prop; prop; prop = prop->next) {
516 if (prop->menu != menu)
517 continue;
518 prop->visible.expr = expr_alloc_and(expr_copy(basedep),
519 prop->visible.expr);
520 }
521 }
522 menu_add_symbol(P_CHOICE, sym, NULL);495 menu_add_symbol(P_CHOICE, sym, NULL);
523 prop = sym_get_choice_prop(sym);496 prop = sym_get_choice_prop(sym);
524 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)497 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
@@ -578,13 +551,13 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) · 53 unmodified lines
578 551
579 /*552 /*
580 * For choices, add a reverse dependency (corresponding to a select) of553 * For choices, add a reverse dependency (corresponding to a select) of
581 * '<visibility> && m'. This prevents the user from setting the choice554 * '<visibility> && y'. This prevents the user from setting the choice
582 * mode to 'n' when the choice is visible.555 * mode to 'n' when the choice is visible.
583 */556 */
584 if (sym && sym_is_choice(sym) && parent->prompt) {557 if (sym && sym_is_choice(sym) && parent->prompt) {
585 sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,558 sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
586 expr_alloc_and(parent->prompt->visible.expr,559 expr_alloc_and(parent->prompt->visible.expr,
587 expr_alloc_symbol(&symbol_mod)));560 expr_alloc_symbol(&symbol_yes)));
588 }561 }
589}562}
590 563
scripts/kconfig/nconf.c+5−23
@@ -825,30 +825,13 @@ static void build_conf(struct menu *menu) · 824 unmodified lines
825 }825 }
826 826
827 val = sym_get_tristate_value(sym);827 val = sym_get_tristate_value(sym);
828 if (sym_is_changeable(sym)) {828 item_make(menu, def_menu ? 't' : ':', " ");
829 switch (val) {
830 case yes:
831 ch = '*';
832 break;
833 case mod:
834 ch = 'M';
835 break;
836 default:
837 ch = ' ';
838 break;
839 }
840 item_make(menu, 't', "<%c>", ch);
841 } else {
842 item_make(menu, def_menu ? 't' : ':', " ");
843 }
844 829
845 item_add_str("%*c%s", indent + 1,830 item_add_str("%*c%s", indent + 1,
846 ' ', menu_get_prompt(menu));831 ' ', menu_get_prompt(menu));
847 if (val == yes) {832 if (def_menu)
848 if (def_menu)833 item_add_str(" (%s) --->", menu_get_prompt(def_menu));
849 item_add_str(" (%s) --->", menu_get_prompt(def_menu));834 return;
850 return;
851 }
852 } else {835 } else {
853 if (menu == current_menu) {836 if (menu == current_menu) {
854 item_make(menu, ':',837 item_make(menu, ':',
@@ -1191,8 +1174,7 @@ static void selected_conf(struct menu *menu, struct menu *active_menu) · 336 unmodified lines
1191 conf(submenu);1174 conf(submenu);
1192 break;1175 break;
1193 case 't':1176 case 't':
1194 if (sym_is_choice(sym) &&1177 if (sym_is_choice(sym))
1195 sym_get_tristate_value(sym) == yes)
1196 conf_choice(submenu);1178 conf_choice(submenu);
1197 else if (submenu->prompt &&1179 else if (submenu->prompt &&
1198 submenu->prompt->type == P_MENU)1180 submenu->prompt->type == P_MENU)
scripts/kconfig/parser.y+14−9
@@ -90,7 +90,7 @@ static bool inside_choice = false; · 89 unmodified lines
90 90
91%type <symbol> nonconst_symbol91%type <symbol> nonconst_symbol
92%type <symbol> symbol92%type <symbol> symbol
93%type <type> type logic_type default93%type <type> type default
94%type <expr> expr94%type <expr> expr
95%type <expr> if_expr95%type <expr> if_expr
96%type <string> end96%type <string> end
@@ -153,6 +153,12 @@ config_stmt: config_entry_start config_option_list · 56 unmodified lines
153 current_entry->filename, current_entry->lineno);153 current_entry->filename, current_entry->lineno);
154 yynerrs++;154 yynerrs++;
155 }155 }
156
157 if (current_entry->sym->type != S_BOOLEAN) {
158 fprintf(stderr, "%s:%d: error: choice member must be bool\n",
159 current_entry->filename, current_entry->lineno);
160 yynerrs++;
161 }
156 }162 }
157 163
158 printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);164 printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
@@ -235,6 +241,8 @@ choice: T_CHOICE T_EOL · 76 unmodified lines
235 241
236 menu_add_entry(sym);242 menu_add_entry(sym);
237 menu_add_expr(P_CHOICE, NULL, NULL);243 menu_add_expr(P_CHOICE, NULL, NULL);
244 menu_set_type(S_BOOLEAN);
245
238 printd(DEBUG_PARSE, "%s:%d:choice\n", cur_filename, cur_lineno);246 printd(DEBUG_PARSE, "%s:%d:choice\n", cur_filename, cur_lineno);
239};247};
240 248
@@ -277,10 +285,10 @@ choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL · 36 unmodified lines
277 printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);285 printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
278};286};
279 287
280choice_option: logic_type prompt_stmt_opt T_EOL288choice_option: T_BOOL T_WORD_QUOTE if_expr T_EOL
281{289{
282 menu_set_type($1);290 menu_add_prompt(P_PROMPT, $2, $3);
283 printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1);291 printd(DEBUG_PARSE, "%s:%d:bool\n", cur_filename, cur_lineno);
284};292};
285 293
286choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL294choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
@@ -290,15 +298,12 @@ choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL · 3 unmodified lines
290};298};
291 299
292type:300type:
293 logic_type301 T_BOOL { $$ = S_BOOLEAN; }
302 | T_TRISTATE { $$ = S_TRISTATE; }
294 | T_INT { $$ = S_INT; }303 | T_INT { $$ = S_INT; }
295 | T_HEX { $$ = S_HEX; }304 | T_HEX { $$ = S_HEX; }
296 | T_STRING { $$ = S_STRING; }305 | T_STRING { $$ = S_STRING; }
297 306
298logic_type:
299 T_BOOL { $$ = S_BOOLEAN; }
300 | T_TRISTATE { $$ = S_TRISTATE; }
301
302default:307default:
303 T_DEFAULT { $$ = S_UNKNOWN; }308 T_DEFAULT { $$ = S_UNKNOWN; }
304 | T_DEF_BOOL { $$ = S_BOOLEAN; }309 | T_DEF_BOOL { $$ = S_BOOLEAN; }
scripts/kconfig/qconf.cc+1−1
@@ -147,7 +147,7 @@ void ConfigItem::updateMenu(void) · 146 unmodified lines
147 expr = sym_get_tristate_value(sym);147 expr = sym_get_tristate_value(sym);
148 switch (expr) {148 switch (expr) {
149 case yes:149 case yes:
150 if (sym_is_choice_value(sym) && type == S_BOOLEAN)150 if (sym_is_choice_value(sym))
151 setIcon(promptColIdx, choiceYesIcon);151 setIcon(promptColIdx, choiceYesIcon);
152 else152 else
153 setIcon(promptColIdx, symbolYesIcon);153 setIcon(promptColIdx, symbolYesIcon);
scripts/kconfig/symbol.c+2−20
@@ -44,12 +44,8 @@ enum symbol_type sym_get_type(struct symbol *sym) · 43 unmodified lines
44{44{
45 enum symbol_type type = sym->type;45 enum symbol_type type = sym->type;
46 46
47 if (type == S_TRISTATE) {47 if (type == S_TRISTATE && modules_val == no)
48 if (sym_is_choice_value(sym) && sym->visible == yes)48 type = S_BOOLEAN;
49 type = S_BOOLEAN;
50 else if (modules_val == no)
51 type = S_BOOLEAN;
52 }
53 return type;49 return type;
54}50}
55 51
@@ -208,26 +204,12 @@ static void sym_set_all_changed(void) · 152 unmodified lines
208static void sym_calc_visibility(struct symbol *sym)204static void sym_calc_visibility(struct symbol *sym)
209{205{
210 struct property *prop;206 struct property *prop;
211 struct symbol *choice_sym = NULL;
212 tristate tri;207 tristate tri;
213 208
214 /* any prompt visible? */209 /* any prompt visible? */
215 tri = no;210 tri = no;
216
217 if (sym_is_choice_value(sym))
218 choice_sym = prop_get_symbol(sym_get_choice_prop(sym));
219
220 for_all_prompts(sym, prop) {211 for_all_prompts(sym, prop) {
221 prop->visible.tri = expr_calc_value(prop->visible.expr);212 prop->visible.tri = expr_calc_value(prop->visible.expr);
222 /*
223 * Tristate choice_values with visibility 'mod' are
224 * not visible if the corresponding choice's value is
225 * 'yes'.
226 */
227 if (choice_sym && sym->type == S_TRISTATE &&
228 prop->visible.tri == mod && choice_sym->curr.tri == yes)
229 prop->visible.tri = no;
230
231 tri = EXPR_OR(tri, prop->visible.tri);213 tri = EXPR_OR(tri, prop->visible.tri);
232 }214 }
233 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))215 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
scripts/kconfig/tests/choice/Kconfig+0−17
@@ -1,10 +1,5 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2 2
3config MODULES
4 bool "Enable loadable module support"
5 modules
6 default y
7
8choice3choice
9 prompt "boolean choice"4 prompt "boolean choice"
10 default BOOL_CHOICE15 default BOOL_CHOICE1
@@ -16,15 +11,3 @@ config BOOL_CHOICE1 · 5 unmodified lines
16 bool "choice 1"11 bool "choice 1"
17 12
18endchoice13endchoice
19
20choice
21 prompt "tristate choice"
22 default TRI_CHOICE1
23
24config TRI_CHOICE0
25 tristate "choice 0"
26
27config TRI_CHOICE1
28 tristate "choice 1"
29
30endchoice
scripts/kconfig/tests/choice/__init__.py+0−10
@@ -1,11 +1,6 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2"""2"""
3Basic choice tests.3Basic choice tests.
4
5The handling of 'choice' is a bit complicated part in Kconfig.
6
7The behavior of 'y' choice is intuitive. If choice values are tristate,
8the choice can be 'm' where each value can be enabled independently.
9"""4"""
10 5
11 6
@@ -14,11 +9,6 @@ def test_oldask0(conf): · 2 unmodified lines
14 assert conf.stdout_contains('oldask0_expected_stdout')9 assert conf.stdout_contains('oldask0_expected_stdout')
15 10
16 11
17def test_oldask1(conf):
18 assert conf.oldaskconfig('oldask1_config') == 0
19 assert conf.stdout_contains('oldask1_expected_stdout')
20
21
22def test_allyes(conf):12def test_allyes(conf):
23 assert conf.allyesconfig() == 013 assert conf.allyesconfig() == 0
24 assert conf.config_contains('allyes_expected_config')14 assert conf.config_contains('allyes_expected_config')
scripts/kconfig/tests/choice/alldef_expected_config+0−3
@@ -1,5 +1,2 @@
1CONFIG_MODULES=y
2# CONFIG_BOOL_CHOICE0 is not set1# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y2CONFIG_BOOL_CHOICE1=y
4# CONFIG_TRI_CHOICE0 is not set
5# CONFIG_TRI_CHOICE1 is not set
scripts/kconfig/tests/choice/allmod_expected_config+0−3
@@ -1,5 +1,2 @@
1CONFIG_MODULES=y
2# CONFIG_BOOL_CHOICE0 is not set1# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y2CONFIG_BOOL_CHOICE1=y
4CONFIG_TRI_CHOICE0=m
5CONFIG_TRI_CHOICE1=m
scripts/kconfig/tests/choice/allno_expected_config+0−3
@@ -1,5 +1,2 @@
1# CONFIG_MODULES is not set
2# CONFIG_BOOL_CHOICE0 is not set1# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y2CONFIG_BOOL_CHOICE1=y
4# CONFIG_TRI_CHOICE0 is not set
5CONFIG_TRI_CHOICE1=y
scripts/kconfig/tests/choice/allyes_expected_config+0−3
@@ -1,5 +1,2 @@
1CONFIG_MODULES=y
2# CONFIG_BOOL_CHOICE0 is not set1# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y2CONFIG_BOOL_CHOICE1=y
4# CONFIG_TRI_CHOICE0 is not set
5CONFIG_TRI_CHOICE1=y
scripts/kconfig/tests/choice/oldask0_expected_stdout+0−4
@@ -1,8 +1,4 @@
1Enable loadable module support (MODULES) [Y/n/?] (NEW)
2boolean choice1boolean choice
3 1. choice 0 (BOOL_CHOICE0) (NEW)2 1. choice 0 (BOOL_CHOICE0) (NEW)
4> 2. choice 1 (BOOL_CHOICE1) (NEW)3> 2. choice 1 (BOOL_CHOICE1) (NEW)
5choice[1-2?]: 4choice[1-2?]:
6tristate choice [M/y/?] (NEW)
7 choice 0 (TRI_CHOICE0) [N/m/?] (NEW)
8 choice 1 (TRI_CHOICE1) [N/m/?] (NEW)
scripts/kconfig/tests/choice/oldask1_config+0−1
@@ -1 +0,0 @@
1# CONFIG_MODULES is not set
scripts/kconfig/tests/choice/oldask1_expected_stdout+0−9
@@ -1,9 +0,0 @@
1Enable loadable module support (MODULES) [N/y/?]
2boolean choice
3 1. choice 0 (BOOL_CHOICE0) (NEW)
4> 2. choice 1 (BOOL_CHOICE1) (NEW)
5choice[1-2?]:
6tristate choice
7 1. choice 0 (TRI_CHOICE0) (NEW)
8> 2. choice 1 (TRI_CHOICE1) (NEW)
9choice[1-2?]:
scripts/kconfig/tests/choice_value_with_m_dep/Kconfig+0−21
@@ -1,21 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2
3config MODULES
4 def_bool y
5 modules
6
7config DEP
8 tristate
9 default m
10
11choice
12 prompt "Tristate Choice"
13
14config CHOICE0
15 tristate "Choice 0"
16
17config CHOICE1
18 tristate "Choice 1"
19 depends on DEP
20
21endchoice
scripts/kconfig/tests/choice_value_with_m_dep/__init__.py+0−16
@@ -1,16 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Hide tristate choice values with mod dependency in y choice.
4
5If tristate choice values depend on symbols set to 'm', they should be
6hidden when the choice containing them is changed from 'm' to 'y'
7(i.e. exclusive choice).
8
9Related Linux commit: fa64e5f6a35efd5e77d639125d973077ca506074
10"""
11
12
13def test(conf):
14 assert conf.oldaskconfig('config', 'y') == 0
15 assert conf.config_contains('expected_config')
16 assert conf.stdout_contains('expected_stdout')
scripts/kconfig/tests/choice_value_with_m_dep/config+0−2
@@ -1,2 +0,0 @@
1CONFIG_CHOICE0=m
2CONFIG_CHOICE1=m
scripts/kconfig/tests/choice_value_with_m_dep/expected_config+0−3
@@ -1,3 +0,0 @@
1CONFIG_MODULES=y
2CONFIG_DEP=m
3CONFIG_CHOICE0=y
scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout+0−4
@@ -1,4 +0,0 @@
1Tristate Choice [M/y/?] y
2Tristate Choice
3> 1. Choice 0 (CHOICE0)
4choice[1]: 1
scripts/kconfig/tests/inter_choice/Kconfig+0−25
@@ -1,25 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2
3config MODULES
4 def_bool y
5 modules
6
7choice
8 prompt "Choice"
9
10config CHOICE_VAL0
11 tristate "Choice 0"
12
13config CHOIVE_VAL1
14 tristate "Choice 1"
15
16endchoice
17
18choice
19 prompt "Another choice"
20 depends on CHOICE_VAL0
21
22config DUMMY
23 bool "dummy"
24
25endchoice
scripts/kconfig/tests/inter_choice/__init__.py+0−15
@@ -1,15 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Do not affect user-assigned choice value by another choice.
4
5Handling of state flags for choices is complecated. In old days,
6the defconfig result of a choice could be affected by another choice
7if those choices interact by 'depends on', 'select', etc.
8
9Related Linux commit: fbe98bb9ed3dae23e320c6b113e35f129538d14a
10"""
11
12
13def test(conf):
14 assert conf.defconfig('defconfig') == 0
15 assert conf.config_contains('expected_config')
scripts/kconfig/tests/inter_choice/defconfig+0−1
@@ -1 +0,0 @@
1CONFIG_CHOICE_VAL0=y
scripts/kconfig/tests/inter_choice/expected_config+0−4
@@ -1,4 +0,0 @@
1CONFIG_MODULES=y
2CONFIG_CHOICE_VAL0=y
3# CONFIG_CHOIVE_VAL1 is not set
4CONFIG_DUMMY=y