aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig
diff options
context:
space:
mode:
authorArnaud Lacombe <lacombar@gmail.com>2012-01-23 17:29:05 -0500
committerMichal Marek <mmarek@suse.cz>2012-01-26 05:01:56 -0500
commit5d09598d488f081e3be23f885ed65cbbe2d073b5 (patch)
tree077850c02c72b29a8b5b1f5fa95a1cf2adae5275 /scripts/kconfig
parentdcd6c92267155e70a94b3927bce681ce74b80d1f (diff)
kconfig: fix new choices being skipped upon config update
Running `oldconfig' after any of the following configuration change: either trivial addition, such as: config A bool "A" choice prompt "Choice ?" depends on A config CHOICE_B bool "Choice B" config CHOICE_C bool "Choice C" endchoice or more tricky change: OLD KCONFIG | NEW KCONFIG | | config A | bool "A" | choice | choice prompt "Choice ?" | prompt "Choice ?" | config CHOICE_C | config CHOICE_C bool "Choice C" | bool "Choice C" | config CHOICE_D | config CHOICE_D bool "Choice D" | bool "Choice D" endchoice | | config CHOICE_E | bool "Choice E" | depends on A | endchoice will not cause the choice to be considered as NEW, and thus not be asked. The cause of this behavior is that choice's novelty are computed statically right after the saved configuration has been read. At this point, the new dependency's value is still unknown and asserted to be `no'. Moreover, no update to this decision is made afterward. Correct this by dynamically evaluating a choice's novelty, and removing the static evaluation. Reported-and-tested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Arnaud Lacombe <lacombar@gmail.com> Signed-off-by: Michal Marek <mmarek@suse.cz>
Diffstat (limited to 'scripts/kconfig')
-rw-r--r--scripts/kconfig/confdata.c26
-rw-r--r--scripts/kconfig/symbol.c9
2 files changed, 14 insertions, 21 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 7c7a5a6cc3f5..0586085136d1 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -344,10 +344,8 @@ setsym:
344 344
345int conf_read(const char *name) 345int conf_read(const char *name)
346{ 346{
347 struct symbol *sym, *choice_sym; 347 struct symbol *sym;
348 struct property *prop; 348 int i;
349 struct expr *e;
350 int i, flags;
351 349
352 sym_set_change_count(0); 350 sym_set_change_count(0);
353 351
@@ -357,7 +355,7 @@ int conf_read(const char *name)
357 for_all_symbols(i, sym) { 355 for_all_symbols(i, sym) {
358 sym_calc_value(sym); 356 sym_calc_value(sym);
359 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) 357 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
360 goto sym_ok; 358 continue;
361 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 359 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
362 /* check that calculated value agrees with saved value */ 360 /* check that calculated value agrees with saved value */
363 switch (sym->type) { 361 switch (sym->type) {
@@ -366,30 +364,18 @@ int conf_read(const char *name)
366 if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) 364 if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
367 break; 365 break;
368 if (!sym_is_choice(sym)) 366 if (!sym_is_choice(sym))
369 goto sym_ok; 367 continue;
370 /* fall through */ 368 /* fall through */
371 default: 369 default:
372 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 370 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
373 goto sym_ok; 371 continue;
374 break; 372 break;
375 } 373 }
376 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 374 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
377 /* no previous value and not saved */ 375 /* no previous value and not saved */
378 goto sym_ok; 376 continue;
379 conf_unsaved++; 377 conf_unsaved++;
380 /* maybe print value in verbose mode... */ 378 /* maybe print value in verbose mode... */
381 sym_ok:
382 if (!sym_is_choice(sym))
383 continue;
384 /* The choice symbol only has a set value (and thus is not new)
385 * if all its visible childs have values.
386 */
387 prop = sym_get_choice_prop(sym);
388 flags = sym->flags;
389 expr_list_for_each_sym(prop->expr, e, choice_sym)
390 if (choice_sym->visible != no)
391 flags &= choice_sym->flags;
392 sym->flags &= flags | ~SYMBOL_DEF_USER;
393 } 379 }
394 380
395 for_all_symbols(i, sym) { 381 for_all_symbols(i, sym) {
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 071f00c3046e..22a3c400fc41 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -262,11 +262,18 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
262 struct symbol *def_sym; 262 struct symbol *def_sym;
263 struct property *prop; 263 struct property *prop;
264 struct expr *e; 264 struct expr *e;
265 int flags;
265 266
266 /* first calculate all choice values' visibilities */ 267 /* first calculate all choice values' visibilities */
268 flags = sym->flags;
267 prop = sym_get_choice_prop(sym); 269 prop = sym_get_choice_prop(sym);
268 expr_list_for_each_sym(prop->expr, e, def_sym) 270 expr_list_for_each_sym(prop->expr, e, def_sym) {
269 sym_calc_visibility(def_sym); 271 sym_calc_visibility(def_sym);
272 if (def_sym->visible != no)
273 flags &= def_sym->flags;
274 }
275
276 sym->flags &= flags | ~SYMBOL_DEF_USER;
270 277
271 /* is the user choice visible? */ 278 /* is the user choice visible? */
272 def_sym = sym->def[S_DEF_USER].val; 279 def_sym = sym->def[S_DEF_USER].val;