X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=scripts%2Fkconfig%2Fsymbol.c;h=9f180ab7698d3314c3e164983fd154521672bef1;hb=59e89e3ddf8523be39a8e0a66bacbbdd6a72d069;hp=6c8fbbb66ebcaddefff183696d1c5d89bc2d6c09;hpb=5bb241b325d7d91bc4ec0b394f31dffb17fe7978;p=~andy%2Flinux diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 6c8fbbb66eb..9f180ab7698 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym) } if (sym_is_choice_value(sym)) return; + /* defaulting to "yes" if no explicit "depends on" are given */ + tri = yes; + if (sym->dir_dep.expr) + tri = expr_calc_value(sym->dir_dep.expr); + if (tri == mod) + tri = yes; + if (sym->dir_dep.tri != tri) { + sym->dir_dep.tri = tri; + sym_set_changed(sym); + } tri = no; if (sym->rev_dep.expr) tri = expr_calc_value(sym->rev_dep.expr); @@ -222,13 +232,15 @@ static struct symbol *sym_calc_choice(struct symbol *sym) struct property *prop; struct expr *e; + /* first calculate all choice values' visibilities */ + prop = sym_get_choice_prop(sym); + expr_list_for_each_sym(prop->expr, e, def_sym) + sym_calc_visibility(def_sym); + /* is the user choice visible? */ def_sym = sym->def[S_DEF_USER].val; - if (def_sym) { - sym_calc_visibility(def_sym); - if (def_sym->visible != no) - return def_sym; - } + if (def_sym && def_sym->visible != no) + return def_sym; /* any of the defaults visible? */ for_all_defaults(sym, prop) { @@ -236,18 +248,15 @@ static struct symbol *sym_calc_choice(struct symbol *sym) if (prop->visible.tri == no) continue; def_sym = prop_get_symbol(prop); - sym_calc_visibility(def_sym); if (def_sym->visible != no) return def_sym; } /* just get the first visible value */ prop = sym_get_choice_prop(sym); - expr_list_for_each_sym(prop->expr, e, def_sym) { - sym_calc_visibility(def_sym); + expr_list_for_each_sym(prop->expr, e, def_sym) if (def_sym->visible != no) return def_sym; - } /* no choice? reset tristate value */ sym->curr.tri = no; @@ -321,6 +330,14 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: + if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { + fprintf(stderr, "warning: ("); + expr_fprint(sym->rev_dep.expr, stderr); + fprintf(stderr, ") selects %s which has unmet direct dependencies (", + sym->name); + expr_fprint(sym->dir_dep.expr, stderr); + fprintf(stderr, ")\n"); + } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) @@ -365,12 +382,13 @@ void sym_calc_value(struct symbol *sym) if (sym_is_choice(sym)) { struct symbol *choice_sym; - int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); prop = sym_get_choice_prop(sym); expr_list_for_each_sym(prop->expr, e, choice_sym) { - choice_sym->flags |= flags; - if (flags & SYMBOL_CHANGED) + if ((sym->flags & SYMBOL_WRITE) && + choice_sym->visible != no) + choice_sym->flags |= SYMBOL_WRITE; + if (sym->flags & SYMBOL_CHANGED) sym_set_changed(choice_sym); } } @@ -651,12 +669,20 @@ bool sym_is_changable(struct symbol *sym) return sym->visible > sym->rev_dep.tri; } +static unsigned strhash(const char *s) +{ + /* fnv32 hash */ + unsigned hash = 2166136261U; + for (; *s; s++) + hash = (hash ^ *s) * 0x01000193; + return hash; +} + struct symbol *sym_lookup(const char *name, int flags) { struct symbol *symbol; - const char *ptr; char *new_name; - int hash = 0; + int hash; if (name) { if (name[0] && !name[1]) { @@ -666,12 +692,11 @@ struct symbol *sym_lookup(const char *name, int flags) case 'n': return &symbol_no; } } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; + hash = strhash(name) % SYMBOL_HASHSIZE; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && + if (symbol->name && + !strcmp(symbol->name, name) && (flags ? symbol->flags & flags : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) return symbol; @@ -679,7 +704,7 @@ struct symbol *sym_lookup(const char *name, int flags) new_name = strdup(name); } else { new_name = NULL; - hash = 256; + hash = 0; } symbol = malloc(sizeof(*symbol)); @@ -697,7 +722,6 @@ struct symbol *sym_lookup(const char *name, int flags) struct symbol *sym_find(const char *name) { struct symbol *symbol = NULL; - const char *ptr; int hash = 0; if (!name) @@ -710,12 +734,11 @@ struct symbol *sym_find(const char *name) case 'n': return &symbol_no; } } - for (ptr = name; *ptr; ptr++) - hash += *ptr; - hash &= 0xff; + hash = strhash(name) % SYMBOL_HASHSIZE; for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { - if (!strcmp(symbol->name, name) && + if (symbol->name && + !strcmp(symbol->name, name) && !(symbol->flags & SYMBOL_CONST)) break; } @@ -750,6 +773,7 @@ struct symbol **sym_re_search(const char *pattern) return NULL; } } + sym_calc_value(sym); sym_arr[cnt++] = sym; } if (sym_arr) @@ -937,6 +961,8 @@ const char *prop_get_type_name(enum prop_type type) return "select"; case P_RANGE: return "range"; + case P_SYMBOL: + return "symbol"; case P_UNKNOWN: break; }