From bd988e7cb84a7f27e8ec100c5f68498b7d4fa69c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 12 Jun 2024 02:55:12 +0900 Subject: kconfig: introduce choice_set_value() helper Currently, sym_set_tristate_value() is used to set 'y' to a choice member, which is confusing because it not only sets 'y' to the given symbol but also tweaks flags of other symbols as a side effect. Add a dedicated function for setting the value of the given choice. Signed-off-by: Masahiro Yamada --- scripts/kconfig/conf.c | 2 +- scripts/kconfig/lkc_proto.h | 1 + scripts/kconfig/mconf.c | 2 +- scripts/kconfig/nconf.c | 2 +- scripts/kconfig/symbol.c | 62 +++++++++++++++++++++++++++++++-------------- 5 files changed, 47 insertions(+), 22 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index cf8193fc00fc..5dbdd9459f21 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -507,7 +507,7 @@ static void conf_choice(struct menu *menu) print_help(child); continue; } - sym_set_tristate_value(child->sym, yes); + choice_set_value(menu, child->sym); return; } } diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index c663fd8b35d2..1221709efac1 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -28,6 +28,7 @@ bool sym_dep_errors(void); enum symbol_type sym_get_type(struct symbol *sym); bool sym_tristate_within_range(struct symbol *sym,tristate tri); bool sym_set_tristate_value(struct symbol *sym,tristate tri); +void choice_set_value(struct menu *choice, struct symbol *sym); tristate sym_toggle_tristate_value(struct symbol *sym); bool sym_string_valid(struct symbol *sym, const char *newval); bool sym_string_within_range(struct symbol *sym, const char *str); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index e6227af51658..03709eb734ae 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -636,7 +636,7 @@ static void conf_choice(struct menu *menu) if (!child->sym) break; - sym_set_tristate_value(child->sym, yes); + choice_set_value(menu, child->sym); } return; case 1: diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index addc89ee61d4..eb5fc3ccaf9d 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -1331,7 +1331,7 @@ static void conf_choice(struct menu *menu) case ' ': case 10: case KEY_RIGHT: - sym_set_tristate_value(child->sym, yes); + choice_set_value(menu, child->sym); return; case 'h': case '?': diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index eaff7ac496bd..8df0a75f40b9 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -516,8 +516,6 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) return false; if (sym->visible <= sym->rev_dep.tri) return false; - if (sym_is_choice_value(sym) && sym->visible == yes) - return val == yes; return val >= sym->rev_dep.tri && val <= sym->visible; } @@ -532,23 +530,6 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) sym->flags |= SYMBOL_DEF_USER; sym_set_changed(sym); } - /* - * setting a choice value also resets the new flag of the choice - * symbol and all other choice values. - */ - if (sym_is_choice_value(sym) && val == yes) { - struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - struct property *prop; - struct expr *e; - - cs->def[S_DEF_USER].val = sym; - cs->flags |= SYMBOL_DEF_USER; - prop = sym_get_choice_prop(cs); - for (e = prop->expr; e; e = e->left.expr) { - if (e->right.sym->visible != no) - e->right.sym->flags |= SYMBOL_DEF_USER; - } - } sym->def[S_DEF_USER].tri = val; if (oldval != val) @@ -557,10 +538,53 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) return true; } +/** + * choice_set_value - set the user input to a choice + * + * @choice: menu entry for the choice + * @sym: selected symbol + */ +void choice_set_value(struct menu *choice, struct symbol *sym) +{ + struct menu *menu; + bool changed = false; + + menu_for_each_sub_entry(menu, choice) { + tristate val; + + if (!menu->sym) + continue; + + if (menu->sym->visible == no) + continue; + + val = menu->sym == sym ? yes : no; + + if (menu->sym->curr.tri != val) + changed = true; + + menu->sym->def[S_DEF_USER].tri = val; + menu->sym->flags |= SYMBOL_DEF_USER; + } + + choice->sym->def[S_DEF_USER].val = sym; + choice->sym->flags |= SYMBOL_DEF_USER; + + if (changed) + sym_clear_all_valid(); +} + tristate sym_toggle_tristate_value(struct symbol *sym) { + struct menu *choice; tristate oldval, newval; + choice = sym_get_choice_menu(sym); + if (choice) { + choice_set_value(choice, sym); + return yes; + } + oldval = newval = sym_get_tristate_value(sym); do { switch (newval) { -- cgit v1.2.3