-rw-r--r-- | scripts/kconfig/symbol.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 59c88d2..845d8a3 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -136,33 +136,33 @@ struct property *sym_get_default_prop(struct symbol *sym) } return NULL; } void sym_calc_visibility(struct symbol *sym) { struct property *prop; tristate visible, oldvisible; /* any prompt visible? */ oldvisible = sym->visible; visible = no; for_all_prompts(sym, prop) visible = E_OR(visible, E_CALC(prop->visible)); if (oldvisible != visible) { sym->visible = visible; - sym->flags |= SYMBOL_CHANGED; + sym_set_changed(sym); } } void sym_calc_value(struct symbol *sym) { struct symbol_value newval, oldval; struct property *prop, *def_prop; struct symbol *def_sym; struct expr *e; if (sym->flags & SYMBOL_VALID) return; oldval = sym->curr; switch (sym->type) { @@ -191,33 +191,34 @@ void sym_calc_value(struct symbol *sym) sym->flags &= ~SYMBOL_WRITE; sym_calc_visibility(sym); /* set default if recursively called */ sym->curr = newval; if (sym->visible != no) { sym->flags |= SYMBOL_WRITE; if (!sym_has_value(sym)) { if (!sym_is_choice(sym)) { prop = sym_get_default_prop(sym); if (prop) { sym_calc_value(prop->def); newval = prop->def->curr; } - } + } else + S_TRI(newval) = S_TRI(sym->def); } else newval = sym->def; S_TRI(newval) = E_AND(S_TRI(newval), sym->visible); /* if the symbol is visible and not optionial, * possibly ignore old user choice. */ if (!sym_is_optional(sym) && S_TRI(newval) == no) S_TRI(newval) = sym->visible; if (sym_is_choice_value(sym) && sym->visible == yes) { prop = sym_get_choice_prop(sym); S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; } } else { prop = sym_get_default_prop(sym); if (prop) { sym->flags |= SYMBOL_WRITE; @@ -263,60 +264,74 @@ out: if (!def_sym) { prop = sym_get_choice_prop(sym); for (e = prop->dep; e; e = e->left.expr) { sym_calc_visibility(e->right.sym); if (e->right.sym->visible != no) { def_sym = e->right.sym; break; } } } S_VAL(newval) = def_sym; } if (memcmp(&oldval, &newval, sizeof(newval))) - sym->flags |= SYMBOL_CHANGED; + sym_set_changed(sym); sym->curr = newval; if (sym_is_choice(sym)) { int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); prop = sym_get_choice_prop(sym); - for (e = prop->dep; e; e = e->left.expr) + for (e = prop->dep; e; e = e->left.expr) { e->right.sym->flags |= flags; + if (flags & SYMBOL_CHANGED) + sym_set_changed(e->right.sym); + } } } void sym_clear_all_valid(void) { struct symbol *sym; int i; for_all_symbols(i, sym) sym->flags &= ~SYMBOL_VALID; sym_change_count++; } +void sym_set_changed(struct symbol *sym) +{ + struct property *prop; + + sym->flags |= SYMBOL_CHANGED; + for (prop = sym->prop; prop; prop = prop->next) { + if (prop->menu) + prop->menu->flags |= MENU_CHANGED; + } +} + void sym_set_all_changed(void) { struct symbol *sym; int i; for_all_symbols(i, sym) - sym->flags |= SYMBOL_CHANGED; + sym_set_changed(sym); } bool sym_tristate_within_range(struct symbol *sym, tristate val) { int type = sym_get_type(sym); if (sym->visible == no) return false; if (type != S_BOOLEAN && type != S_TRISTATE) return false; switch (val) { case no: if (sym_is_choice_value(sym) && sym->visible == yes) return false; @@ -327,33 +342,33 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val) return type == S_TRISTATE; case yes: return type == S_BOOLEAN || sym->visible == yes; } return false; } bool sym_set_tristate_value(struct symbol *sym, tristate val) { tristate oldval = sym_get_tristate_value(sym); if (oldval != val && !sym_tristate_within_range(sym, val)) return false; if (sym->flags & SYMBOL_NEW) { sym->flags &= ~SYMBOL_NEW; - sym->flags |= SYMBOL_CHANGED; + sym_set_changed(sym); } if (sym_is_choice_value(sym) && val == yes) { struct property *prop = sym_get_choice_prop(sym); S_VAL(prop->def->def) = sym; prop->def->flags &= ~SYMBOL_NEW; } S_TRI(sym->def) = val; if (oldval != val) { sym_clear_all_valid(); if (sym == modules_sym) sym_set_all_changed(); } return true; @@ -447,33 +462,33 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) case 'M': return sym_set_tristate_value(sym, mod); case 'n': case 'N': return sym_set_tristate_value(sym, no); } return false; default: ; } if (!sym_string_valid(sym, newval)) return false; if (sym->flags & SYMBOL_NEW) { sym->flags &= ~SYMBOL_NEW; - sym->flags |= SYMBOL_CHANGED; + sym_set_changed(sym); } oldval = S_VAL(sym->def); size = strlen(newval) + 1; if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { size += 2; S_VAL(sym->def) = val = malloc(size); *val++ = '0'; *val++ = 'x'; } else if (!oldval || strcmp(oldval, newval)) S_VAL(sym->def) = val = malloc(size); else return true; strcpy(val, newval); free((void *)oldval); @@ -512,72 +527,68 @@ bool sym_is_changable(struct symbol *sym) /* at least 'n' and 'y'/'m' is selectable */ if (sym_is_optional(sym)) return true; /* no 'n', so 'y' and 'm' must be selectable */ if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes) return true; return false; } struct symbol *sym_lookup(const char *name, int isconst) { struct symbol *symbol; const char *ptr; char *new_name; int hash = 0; - //printf("lookup: %s -> ", name); if (name) { if (name[0] && !name[1]) { switch (name[0]) { case 'y': return &symbol_yes; case 'm': return &symbol_mod; case 'n': return &symbol_no; } } for (ptr = name; *ptr; ptr++) hash += *ptr; hash &= 0xff; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { if (!strcmp(symbol->name, name)) { if ((isconst && symbol->flags & SYMBOL_CONST) || - (!isconst && !(symbol->flags & SYMBOL_CONST))) { - //printf("h:%p\n", symbol); + (!isconst && !(symbol->flags & SYMBOL_CONST))) return symbol; - } } } new_name = strdup(name); } else { new_name = NULL; hash = 256; } symbol = malloc(sizeof(*symbol)); memset(symbol, 0, sizeof(*symbol)); symbol->name = new_name; symbol->type = S_UNKNOWN; symbol->flags = SYMBOL_NEW; if (isconst) symbol->flags |= SYMBOL_CONST; symbol->next = symbol_hash[hash]; symbol_hash[hash] = symbol; - //printf("n:%p\n", symbol); return symbol; } struct symbol *sym_find(const char *name) { struct symbol *symbol = NULL; const char *ptr; int hash = 0; if (!name) return NULL; if (name[0] && !name[1]) { switch (name[0]) { case 'y': return &symbol_yes; case 'm': return &symbol_mod; |