summaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig/conf.c')
-rw-r--r--scripts/kconfig/conf.c230
1 files changed, 88 insertions, 142 deletions
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 8ad2c52d9b1f..3d7d454c54da 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -114,51 +114,54 @@ static void set_randconfig_seed(void)
srand(seed);
}
-static bool randomize_choice_values(struct symbol *csym)
+/**
+ * randomize_choice_values - randomize choice block
+ *
+ * @choice: menu entry for the choice
+ */
+static void randomize_choice_values(struct menu *choice)
{
- struct property *prop;
- struct symbol *sym;
- struct expr *e;
- int cnt, def;
+ struct menu *menu;
+ int x;
+ int cnt = 0;
/*
- * If choice is mod then we may have more items selected
- * and if no then no-one.
- * In both cases stop.
+ * First, count the number of symbols to randomize. If sym_has_value()
+ * is true, it was specified by KCONFIG_ALLCONFIG. It needs to be
+ * respected.
*/
- if (csym->curr.tri != yes)
- return false;
+ menu_for_each_sub_entry(menu, choice) {
+ struct symbol *sym = menu->sym;
- prop = sym_get_choice_prop(csym);
+ if (sym && !sym_has_value(sym))
+ cnt++;
+ }
- /* count entries in choice block */
- cnt = 0;
- expr_list_for_each_sym(prop->expr, e, sym)
- cnt++;
+ while (cnt > 0) {
+ x = rand() % cnt;
- /*
- * find a random value and set it to yes,
- * set the rest to no so we have only one set
- */
- def = rand() % cnt;
-
- cnt = 0;
- expr_list_for_each_sym(prop->expr, e, sym) {
- if (def == cnt++) {
- sym->def[S_DEF_USER].tri = yes;
- csym->def[S_DEF_USER].val = sym;
- } else {
- sym->def[S_DEF_USER].tri = no;
+ menu_for_each_sub_entry(menu, choice) {
+ struct symbol *sym = menu->sym;
+
+ if (sym && !sym_has_value(sym))
+ x--;
+
+ if (x < 0) {
+ sym->def[S_DEF_USER].tri = yes;
+ sym->flags |= SYMBOL_DEF_USER;
+ /*
+ * Move the selected item to the _tail_ because
+ * this needs to have a lower priority than the
+ * user input from KCONFIG_ALLCONFIG.
+ */
+ list_move_tail(&sym->choice_link,
+ &choice->choice_members);
+
+ break;
+ }
}
- sym->flags |= SYMBOL_DEF_USER;
- /* clear VALID to get value calculated */
- sym->flags &= ~SYMBOL_VALID;
+ cnt--;
}
- csym->flags |= SYMBOL_DEF_USER;
- /* clear VALID to get value calculated */
- csym->flags &= ~SYMBOL_VALID;
-
- return true;
}
enum conf_def_mode {
@@ -169,9 +172,9 @@ enum conf_def_mode {
def_random
};
-static bool conf_set_all_new_symbols(enum conf_def_mode mode)
+static void conf_set_all_new_symbols(enum conf_def_mode mode)
{
- struct symbol *sym, *csym;
+ struct menu *menu;
int cnt;
/*
* can't go as the default in switch-case below, otherwise gcc whines
@@ -180,7 +183,6 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
int pby = 50; /* probability of bool = y */
int pty = 33; /* probability of tristate = y */
int ptm = 33; /* probability of tristate = m */
- bool has_changed = false;
if (mode == def_random) {
int n, p[3];
@@ -227,79 +229,51 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
}
}
- for_all_symbols(sym) {
- if (sym_has_value(sym) || sym->flags & SYMBOL_VALID)
- continue;
- switch (sym_get_type(sym)) {
- case S_BOOLEAN:
- case S_TRISTATE:
- has_changed = true;
- switch (mode) {
- case def_yes:
- sym->def[S_DEF_USER].tri = yes;
- break;
- case def_mod:
- sym->def[S_DEF_USER].tri = mod;
- break;
- case def_no:
- sym->def[S_DEF_USER].tri = no;
- break;
- case def_random:
- sym->def[S_DEF_USER].tri = no;
- cnt = rand() % 100;
- if (sym->type == S_TRISTATE) {
- if (cnt < pty)
- sym->def[S_DEF_USER].tri = yes;
- else if (cnt < pty + ptm)
- sym->def[S_DEF_USER].tri = mod;
- } else if (cnt < pby)
- sym->def[S_DEF_USER].tri = yes;
- break;
- default:
- continue;
- }
- if (!(sym_is_choice(sym) && mode == def_random))
- sym->flags |= SYMBOL_DEF_USER;
- break;
- default:
- break;
- }
-
- }
+ menu_for_each_entry(menu) {
+ struct symbol *sym = menu->sym;
+ tristate val;
- sym_clear_all_valid();
+ if (!sym || !menu->prompt || sym_has_value(sym) ||
+ (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) ||
+ sym_is_choice_value(sym))
+ continue;
- /*
- * We have different type of choice blocks.
- * If curr.tri equals to mod then we can select several
- * choice symbols in one block.
- * In this case we do nothing.
- * If curr.tri equals yes then only one symbol can be
- * selected in a choice block and we set it to yes,
- * and the rest to no.
- */
- if (mode != def_random) {
- for_all_symbols(csym) {
- if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
- sym_is_choice_value(csym))
- csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
+ if (sym_is_choice(sym)) {
+ if (mode == def_random)
+ randomize_choice_values(menu);
+ continue;
}
- }
- for_all_symbols(csym) {
- if (sym_has_value(csym) || !sym_is_choice(csym))
+ switch (mode) {
+ case def_yes:
+ val = yes;
+ break;
+ case def_mod:
+ val = mod;
+ break;
+ case def_no:
+ val = no;
+ break;
+ case def_random:
+ val = no;
+ cnt = rand() % 100;
+ if (sym->type == S_TRISTATE) {
+ if (cnt < pty)
+ val = yes;
+ else if (cnt < pty + ptm)
+ val = mod;
+ } else if (cnt < pby) {
+ val = yes;
+ }
+ break;
+ default:
continue;
-
- sym_calc_value(csym);
- if (mode == def_random)
- has_changed |= randomize_choice_values(csym);
- else {
- set_all_choice_values(csym);
- has_changed = true;
}
+ sym->def[S_DEF_USER].tri = val;
+ sym->flags |= SYMBOL_DEF_USER;
}
- return has_changed;
+ sym_clear_all_valid();
}
static void conf_rewrite_tristates(tristate old_val, tristate new_val)
@@ -448,39 +422,15 @@ help:
static void conf_choice(struct menu *menu)
{
- struct symbol *sym, *def_sym;
+ struct symbol *def_sym;
struct menu *child;
- bool is_new;
-
- sym = menu->sym;
- is_new = !sym_has_value(sym);
- if (sym_is_changeable(sym)) {
- conf_sym(menu);
- sym_calc_value(sym);
- switch (sym_get_tristate_value(sym)) {
- case no:
- case mod:
- return;
- case yes:
- break;
- }
- } else {
- switch (sym_get_tristate_value(sym)) {
- case no:
- return;
- case mod:
- printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
- return;
- case yes:
- break;
- }
- }
+ bool is_new = false;
while (1) {
int cnt, def;
printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
- def_sym = sym_get_choice_value(sym);
+ def_sym = sym_calc_choice(menu);
cnt = def = 0;
line[0] = 0;
for (child = menu->list; child; child = child->next) {
@@ -498,8 +448,10 @@ static void conf_choice(struct menu *menu)
printf("%*c", indent, ' ');
printf(" %d. %s (%s)", cnt, menu_get_prompt(child),
child->sym->name);
- if (!sym_has_value(child->sym))
+ if (!sym_has_value(child->sym)) {
+ is_new = true;
printf(" (NEW)");
+ }
printf("\n");
}
printf("%*schoice", indent - 1, "");
@@ -549,7 +501,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;
}
}
@@ -596,9 +548,7 @@ static void conf(struct menu *menu)
if (sym_is_choice(sym)) {
conf_choice(menu);
- if (sym->curr.tri != mod)
- return;
- goto conf_childs;
+ return;
}
switch (sym->type) {
@@ -630,10 +580,7 @@ static void check_conf(struct menu *menu)
return;
sym = menu->sym;
- if (sym && !sym_has_value(sym) &&
- (sym_is_changeable(sym) ||
- (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) {
-
+ if (sym && !sym_has_value(sym) && sym_is_changeable(sym)) {
switch (input_mode) {
case listnewconfig:
if (sym->name)
@@ -849,8 +796,7 @@ int main(int ac, char **av)
conf_set_all_new_symbols(def_default);
break;
case randconfig:
- /* Really nothing to do in this loop */
- while (conf_set_all_new_symbols(def_random)) ;
+ conf_set_all_new_symbols(def_random);
break;
case defconfig:
conf_set_all_new_symbols(def_default);