aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig
diff options
context:
space:
mode:
authorYann E. MORIN <yann.morin.1998@free.fr>2013-04-28 16:36:38 -0400
committerYann E. MORIN <yann.morin.1998@free.fr>2013-06-24 14:03:30 -0400
commit3b9a19e08960e5cdad5253998637653e592a3c29 (patch)
tree2293b53b7f29ff79f67fa7245ea027a36bda91fc /scripts/kconfig
parenta1ce636f560336ba007bfabb15b167ff31b592cf (diff)
kconfig: loop as long as we changed some symbols in randconfig
Because of choice-in-a-choice constructs, it can happen that not all symbols are assigned a value during randconfig, leading in rare cases to this situation: ---8<--- choice-in-choice.in choice bool "A/B/C" config A bool "A" config B bool "B" if B choice bool "E/F" config E bool "E" config F bool "F" endchoice endif # B config C bool "C" endchoice ---8<--- $ ./scripts/kconfig/conf --randconfig choice-in-choice.in [--SNIP--] $ ./scripts/kconfig/conf --silentoldconfig choice-in-choice.in </dev/null [--SNIP--] A/B/C 1. A (A) > 2. B (B) 3. C (C) choice[1-3]: 2 E/F > 1. E (E) (NEW) 2. F (F) (NEW) choice[1-2]: aborted! Console input/output is redirected. Run 'make oldconfig' to update configuration. Fix this by looping in randconfig for as long as some symbol gets assigned a value. Note: this was spotted with the USB EHCI Debug Device Gadget (USB_G_DBGP), which uses this choice-in-a-choice construct, and exhibits this problem. The example above is just a stripped-down minimalist test-case. Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Diffstat (limited to 'scripts/kconfig')
-rw-r--r--scripts/kconfig/conf.c3
-rw-r--r--scripts/kconfig/confdata.c18
-rw-r--r--scripts/kconfig/lkc.h2
3 files changed, 17 insertions, 6 deletions
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 38616c14c071..d19944f9c3ac 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -654,7 +654,8 @@ int main(int ac, char **av)
654 conf_set_all_new_symbols(def_default); 654 conf_set_all_new_symbols(def_default);
655 break; 655 break;
656 case randconfig: 656 case randconfig:
657 conf_set_all_new_symbols(def_random); 657 /* Really nothing to do in this loop */
658 while (conf_set_all_new_symbols(def_random)) ;
658 break; 659 break;
659 case defconfig: 660 case defconfig:
660 conf_set_all_new_symbols(def_default); 661 conf_set_all_new_symbols(def_default);
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index d36bc1f1d563..c55c227af463 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -1040,7 +1040,7 @@ void conf_set_changed_callback(void (*fn)(void))
1040 conf_changed_callback = fn; 1040 conf_changed_callback = fn;
1041} 1041}
1042 1042
1043static void randomize_choice_values(struct symbol *csym) 1043static bool randomize_choice_values(struct symbol *csym)
1044{ 1044{
1045 struct property *prop; 1045 struct property *prop;
1046 struct symbol *sym; 1046 struct symbol *sym;
@@ -1053,7 +1053,7 @@ static void randomize_choice_values(struct symbol *csym)
1053 * In both cases stop. 1053 * In both cases stop.
1054 */ 1054 */
1055 if (csym->curr.tri != yes) 1055 if (csym->curr.tri != yes)
1056 return; 1056 return false;
1057 1057
1058 prop = sym_get_choice_prop(csym); 1058 prop = sym_get_choice_prop(csym);
1059 1059
@@ -1084,6 +1084,8 @@ static void randomize_choice_values(struct symbol *csym)
1084 csym->flags |= SYMBOL_DEF_USER; 1084 csym->flags |= SYMBOL_DEF_USER;
1085 /* clear VALID to get value calculated */ 1085 /* clear VALID to get value calculated */
1086 csym->flags &= ~(SYMBOL_VALID); 1086 csym->flags &= ~(SYMBOL_VALID);
1087
1088 return true;
1087} 1089}
1088 1090
1089void set_all_choice_values(struct symbol *csym) 1091void set_all_choice_values(struct symbol *csym)
@@ -1106,7 +1108,7 @@ void set_all_choice_values(struct symbol *csym)
1106 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); 1108 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
1107} 1109}
1108 1110
1109void conf_set_all_new_symbols(enum conf_def_mode mode) 1111bool conf_set_all_new_symbols(enum conf_def_mode mode)
1110{ 1112{
1111 struct symbol *sym, *csym; 1113 struct symbol *sym, *csym;
1112 int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y 1114 int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
@@ -1154,6 +1156,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
1154 exit( 1 ); 1156 exit( 1 );
1155 } 1157 }
1156 } 1158 }
1159 bool has_changed = false;
1157 1160
1158 for_all_symbols(i, sym) { 1161 for_all_symbols(i, sym) {
1159 if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) 1162 if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
@@ -1161,6 +1164,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
1161 switch (sym_get_type(sym)) { 1164 switch (sym_get_type(sym)) {
1162 case S_BOOLEAN: 1165 case S_BOOLEAN:
1163 case S_TRISTATE: 1166 case S_TRISTATE:
1167 has_changed = true;
1164 switch (mode) { 1168 switch (mode) {
1165 case def_yes: 1169 case def_yes:
1166 sym->def[S_DEF_USER].tri = yes; 1170 sym->def[S_DEF_USER].tri = yes;
@@ -1219,6 +1223,12 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
1219 1223
1220 sym_calc_value(csym); 1224 sym_calc_value(csym);
1221 if (mode == def_random) 1225 if (mode == def_random)
1222 randomize_choice_values(csym); 1226 has_changed = randomize_choice_values(csym);
1227 else {
1228 set_all_choice_values(csym);
1229 has_changed = true;
1230 }
1223 } 1231 }
1232
1233 return has_changed;
1224} 1234}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 0c8d4191ca87..09f4edfdc911 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -86,7 +86,7 @@ const char *conf_get_autoconfig_name(void);
86char *conf_get_default_confname(void); 86char *conf_get_default_confname(void);
87void sym_set_change_count(int count); 87void sym_set_change_count(int count);
88void sym_add_change_count(int count); 88void sym_add_change_count(int count);
89void conf_set_all_new_symbols(enum conf_def_mode mode); 89bool conf_set_all_new_symbols(enum conf_def_mode mode);
90void set_all_choice_values(struct symbol *csym); 90void set_all_choice_values(struct symbol *csym);
91 91
92struct conf_printer { 92struct conf_printer {