summaryrefslogtreecommitdiff
path: root/scripts/kconfig/symbol.c
Side-by-side diff
Diffstat (limited to 'scripts/kconfig/symbol.c') (more/less context) (show whitespace changes)
-rw-r--r--scripts/kconfig/symbol.c35
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
@@ -140,25 +140,25 @@ struct property *sym_get_default_prop(struct symbol *sym)
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;
@@ -195,25 +195,26 @@ void sym_calc_value(struct symbol *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;
}
@@ -267,52 +268,66 @@ out:
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;
@@ -331,25 +346,25 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
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)
@@ -451,25 +466,25 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
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
@@ -516,64 +531,60 @@ bool sym_is_changable(struct symbol *sym)
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;