Commit 669bfad9 authored by Roman Zippel's avatar Roman Zippel Committed by Sam Ravnborg

kconfig: allow loading multiple configurations

Extend conf_read_simple() so it can load multiple configurations.
Signed-off-by: default avatarRoman Zippel <zippel@linux-m68k.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent 0c1822e6
...@@ -573,7 +573,7 @@ int main(int ac, char **av) ...@@ -573,7 +573,7 @@ int main(int ac, char **av)
case set_random: case set_random:
name = getenv("KCONFIG_ALLCONFIG"); name = getenv("KCONFIG_ALLCONFIG");
if (name && !stat(name, &tmpstat)) { if (name && !stat(name, &tmpstat)) {
conf_read_simple(name); conf_read_simple(name, S_DEF_USER);
break; break;
} }
switch (input_mode) { switch (input_mode) {
...@@ -584,9 +584,9 @@ int main(int ac, char **av) ...@@ -584,9 +584,9 @@ int main(int ac, char **av)
default: break; default: break;
} }
if (!stat(name, &tmpstat)) if (!stat(name, &tmpstat))
conf_read_simple(name); conf_read_simple(name, S_DEF_USER);
else if (!stat("all.config", &tmpstat)) else if (!stat("all.config", &tmpstat))
conf_read_simple("all.config"); conf_read_simple("all.config", S_DEF_USER);
break; break;
default: default:
break; break;
......
...@@ -86,13 +86,13 @@ char *conf_get_default_confname(void) ...@@ -86,13 +86,13 @@ char *conf_get_default_confname(void)
return name; return name;
} }
int conf_read_simple(const char *name) int conf_read_simple(const char *name, int def)
{ {
FILE *in = NULL; FILE *in = NULL;
char line[1024]; char line[1024];
char *p, *p2; char *p, *p2;
struct symbol *sym; struct symbol *sym;
int i; int i, def_flags;
if (name) { if (name) {
in = zconf_fopen(name); in = zconf_fopen(name);
...@@ -125,20 +125,21 @@ int conf_read_simple(const char *name) ...@@ -125,20 +125,21 @@ int conf_read_simple(const char *name)
conf_warnings = 0; conf_warnings = 0;
conf_unsaved = 0; conf_unsaved = 0;
def_flags = SYMBOL_DEF << def;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; sym->flags |= SYMBOL_CHANGED;
sym->flags &= ~(def_flags|SYMBOL_VALID);
if (sym_is_choice(sym)) if (sym_is_choice(sym))
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
sym->flags &= ~SYMBOL_VALID;
switch (sym->type) { switch (sym->type) {
case S_INT: case S_INT:
case S_HEX: case S_HEX:
case S_STRING: case S_STRING:
if (sym->def[S_DEF_USER].val) if (sym->def[def].val)
free(sym->def[S_DEF_USER].val); free(sym->def[def].val);
default: default:
sym->def[S_DEF_USER].val = NULL; sym->def[def].val = NULL;
sym->def[S_DEF_USER].tri = no; sym->def[def].tri = no;
} }
} }
...@@ -155,19 +156,26 @@ int conf_read_simple(const char *name) ...@@ -155,19 +156,26 @@ int conf_read_simple(const char *name)
*p++ = 0; *p++ = 0;
if (strncmp(p, "is not set", 10)) if (strncmp(p, "is not set", 10))
continue; continue;
sym = sym_find(line + 9); if (def == S_DEF_USER) {
if (!sym) { sym = sym_find(line + 9);
conf_warning("trying to assign nonexistent symbol %s", line + 9); if (!sym) {
break; conf_warning("trying to assign nonexistent symbol %s", line + 9);
} else if (!(sym->flags & SYMBOL_NEW)) { break;
}
} else {
sym = sym_lookup(line + 9, 0);
if (sym->type == S_UNKNOWN)
sym->type = S_BOOLEAN;
}
if (sym->flags & def_flags) {
conf_warning("trying to reassign symbol %s", sym->name); conf_warning("trying to reassign symbol %s", sym->name);
break; break;
} }
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
case S_TRISTATE: case S_TRISTATE:
sym->def[S_DEF_USER].tri = no; sym->def[def].tri = no;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
default: default:
; ;
...@@ -185,34 +193,48 @@ int conf_read_simple(const char *name) ...@@ -185,34 +193,48 @@ int conf_read_simple(const char *name)
p2 = strchr(p, '\n'); p2 = strchr(p, '\n');
if (p2) if (p2)
*p2 = 0; *p2 = 0;
sym = sym_find(line + 7); if (def == S_DEF_USER) {
if (!sym) { sym = sym_find(line + 7);
conf_warning("trying to assign nonexistent symbol %s", line + 7); if (!sym) {
break; conf_warning("trying to assign nonexistent symbol %s", line + 7);
} else if (!(sym->flags & SYMBOL_NEW)) { break;
}
} else {
sym = sym_lookup(line + 7, 0);
if (sym->type == S_UNKNOWN)
sym->type = S_OTHER;
}
if (sym->flags & def_flags) {
conf_warning("trying to reassign symbol %s", sym->name); conf_warning("trying to reassign symbol %s", sym->name);
break; break;
} }
switch (sym->type) { switch (sym->type) {
case S_TRISTATE: case S_TRISTATE:
if (p[0] == 'm') { if (p[0] == 'm') {
sym->def[S_DEF_USER].tri = mod; sym->def[def].tri = mod;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
case S_BOOLEAN: case S_BOOLEAN:
if (p[0] == 'y') { if (p[0] == 'y') {
sym->def[S_DEF_USER].tri = yes; sym->def[def].tri = yes;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
if (p[0] == 'n') { if (p[0] == 'n') {
sym->def[S_DEF_USER].tri = no; sym->def[def].tri = no;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
conf_warning("symbol value '%s' invalid for %s", p, sym->name); conf_warning("symbol value '%s' invalid for %s", p, sym->name);
break; break;
case S_OTHER:
if (*p != '"') {
for (p2 = p; *p2 && !isspace(*p2); p2++)
;
sym->type = S_STRING;
goto done;
}
case S_STRING: case S_STRING:
if (*p++ != '"') if (*p++ != '"')
break; break;
...@@ -229,9 +251,10 @@ int conf_read_simple(const char *name) ...@@ -229,9 +251,10 @@ int conf_read_simple(const char *name)
} }
case S_INT: case S_INT:
case S_HEX: case S_HEX:
done:
if (sym_string_valid(sym, p)) { if (sym_string_valid(sym, p)) {
sym->def[S_DEF_USER].val = strdup(p); sym->def[def].val = strdup(p);
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
} else { } else {
conf_warning("symbol value '%s' invalid for %s", p, sym->name); conf_warning("symbol value '%s' invalid for %s", p, sym->name);
continue; continue;
...@@ -249,24 +272,24 @@ int conf_read_simple(const char *name) ...@@ -249,24 +272,24 @@ int conf_read_simple(const char *name)
} }
if (sym && sym_is_choice_value(sym)) { if (sym && sym_is_choice_value(sym)) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
switch (sym->def[S_DEF_USER].tri) { switch (sym->def[def].tri) {
case no: case no:
break; break;
case mod: case mod:
if (cs->def[S_DEF_USER].tri == yes) { if (cs->def[def].tri == yes) {
conf_warning("%s creates inconsistent choice state", sym->name); conf_warning("%s creates inconsistent choice state", sym->name);
cs->flags |= SYMBOL_NEW; cs->flags &= ~def_flags;
} }
break; break;
case yes: case yes:
if (cs->def[S_DEF_USER].tri != no) { if (cs->def[def].tri != no) {
conf_warning("%s creates inconsistent choice state", sym->name); conf_warning("%s creates inconsistent choice state", sym->name);
cs->flags |= SYMBOL_NEW; cs->flags &= ~def_flags;
} else } else
cs->def[S_DEF_USER].val = sym; cs->def[def].val = sym;
break; break;
} }
cs->def[S_DEF_USER].tri = E_OR(cs->def[S_DEF_USER].tri, sym->def[S_DEF_USER].tri); cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
} }
} }
fclose(in); fclose(in);
...@@ -281,11 +304,11 @@ int conf_read(const char *name) ...@@ -281,11 +304,11 @@ int conf_read(const char *name)
struct symbol *sym; struct symbol *sym;
struct property *prop; struct property *prop;
struct expr *e; struct expr *e;
int i; int i, flags;
sym_change_count = 0; sym_change_count = 0;
if (conf_read_simple(name)) if (conf_read_simple(name, S_DEF_USER))
return 1; return 1;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
...@@ -314,15 +337,13 @@ int conf_read(const char *name) ...@@ -314,15 +337,13 @@ int conf_read(const char *name)
sym_ok: sym_ok:
if (sym_has_value(sym) && !sym_is_choice_value(sym)) { if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
if (sym->visible == no) if (sym->visible == no)
sym->flags |= SYMBOL_NEW; sym->flags &= ~SYMBOL_DEF_USER;
switch (sym->type) { switch (sym->type) {
case S_STRING: case S_STRING:
case S_INT: case S_INT:
case S_HEX: case S_HEX:
if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val)) { if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
sym->flags |= SYMBOL_NEW; sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
sym->flags &= ~SYMBOL_VALID;
}
default: default:
break; break;
} }
...@@ -330,9 +351,11 @@ int conf_read(const char *name) ...@@ -330,9 +351,11 @@ int conf_read(const char *name)
if (!sym_is_choice(sym)) if (!sym_is_choice(sym))
continue; continue;
prop = sym_get_choice_prop(sym); prop = sym_get_choice_prop(sym);
flags = sym->flags;
for (e = prop->expr; e; e = e->left.expr) for (e = prop->expr; e; e = e->left.expr)
if (e->right.sym->visible != no) if (e->right.sym->visible != no)
sym->flags |= e->right.sym->flags & SYMBOL_NEW; flags &= e->right.sym->flags;
sym->flags |= flags & SYMBOL_DEF_USER;
} }
sym_change_count += conf_warnings || conf_unsaved; sym_change_count += conf_warnings || conf_unsaved;
......
...@@ -92,10 +92,14 @@ struct symbol { ...@@ -92,10 +92,14 @@ struct symbol {
#define SYMBOL_OPTIONAL 0x0100 #define SYMBOL_OPTIONAL 0x0100
#define SYMBOL_WRITE 0x0200 #define SYMBOL_WRITE 0x0200
#define SYMBOL_CHANGED 0x0400 #define SYMBOL_CHANGED 0x0400
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000 #define SYMBOL_AUTO 0x1000
#define SYMBOL_CHECKED 0x2000 #define SYMBOL_CHECKED 0x2000
#define SYMBOL_WARNED 0x8000 #define SYMBOL_WARNED 0x8000
#define SYMBOL_DEF 0x10000
#define SYMBOL_DEF_USER 0x10000
#define SYMBOL_DEF2 0x20000
#define SYMBOL_DEF3 0x40000
#define SYMBOL_DEF4 0x80000
#define SYMBOL_MAXLENGTH 256 #define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257 #define SYMBOL_HASHSIZE 257
......
...@@ -132,8 +132,6 @@ const char *dbg_print_flags(int val) ...@@ -132,8 +132,6 @@ const char *dbg_print_flags(int val)
strcat(buf, "write/"); strcat(buf, "write/");
if (val & SYMBOL_CHANGED) if (val & SYMBOL_CHANGED)
strcat(buf, "changed/"); strcat(buf, "changed/");
if (val & SYMBOL_NEW)
strcat(buf, "new/");
if (val & SYMBOL_AUTO) if (val & SYMBOL_AUTO)
strcat(buf, "auto/"); strcat(buf, "auto/");
...@@ -1186,9 +1184,7 @@ static gchar **fill_row(struct menu *menu) ...@@ -1186,9 +1184,7 @@ static gchar **fill_row(struct menu *menu)
row[COL_OPTION] = row[COL_OPTION] =
g_strdup_printf("%s %s", menu_get_prompt(menu), g_strdup_printf("%s %s", menu_get_prompt(menu),
sym ? (sym-> sym && sym_has_value(sym) ? "(NEW)" : "");
flags & SYMBOL_NEW ? "(NEW)" : "") :
"");
if (show_all && !menu_is_visible(menu)) if (show_all && !menu_is_visible(menu))
row[COL_COLOR] = g_strdup("DarkGray"); row[COL_COLOR] = g_strdup("DarkGray");
......
...@@ -137,7 +137,7 @@ static inline bool sym_is_optional(struct symbol *sym) ...@@ -137,7 +137,7 @@ static inline bool sym_is_optional(struct symbol *sym)
static inline bool sym_has_value(struct symbol *sym) static inline bool sym_has_value(struct symbol *sym)
{ {
return sym->flags & SYMBOL_NEW ? false : true; return sym->flags & SYMBOL_DEF_USER ? true : false;
} }
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* confdata.c */ /* confdata.c */
P(conf_parse,void,(const char *name)); P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name)); P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name)); P(conf_read_simple,int,(const char *name, int));
P(conf_write,int,(const char *name)); P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void)); P(conf_write_autoconf,int,(void));
......
...@@ -426,8 +426,8 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) ...@@ -426,8 +426,8 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
if (oldval != val && !sym_tristate_within_range(sym, val)) if (oldval != val && !sym_tristate_within_range(sym, val))
return false; return false;
if (sym->flags & SYMBOL_NEW) { if (!(sym->flags & SYMBOL_DEF_USER)) {
sym->flags &= ~SYMBOL_NEW; sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym); sym_set_changed(sym);
} }
/* /*
...@@ -440,11 +440,11 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) ...@@ -440,11 +440,11 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
struct expr *e; struct expr *e;
cs->def[S_DEF_USER].val = sym; cs->def[S_DEF_USER].val = sym;
cs->flags &= ~SYMBOL_NEW; cs->flags |= SYMBOL_DEF_USER;
prop = sym_get_choice_prop(cs); prop = sym_get_choice_prop(cs);
for (e = prop->expr; e; e = e->left.expr) { for (e = prop->expr; e; e = e->left.expr) {
if (e->right.sym->visible != no) if (e->right.sym->visible != no)
e->right.sym->flags &= ~SYMBOL_NEW; e->right.sym->flags |= SYMBOL_DEF_USER;
} }
} }
...@@ -591,8 +591,8 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) ...@@ -591,8 +591,8 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
if (!sym_string_within_range(sym, newval)) if (!sym_string_within_range(sym, newval))
return false; return false;
if (sym->flags & SYMBOL_NEW) { if (!(sym->flags & SYMBOL_DEF_USER)) {
sym->flags &= ~SYMBOL_NEW; sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym); sym_set_changed(sym);
} }
...@@ -679,7 +679,6 @@ struct symbol *sym_lookup(const char *name, int isconst) ...@@ -679,7 +679,6 @@ struct symbol *sym_lookup(const char *name, int isconst)
memset(symbol, 0, sizeof(*symbol)); memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name; symbol->name = new_name;
symbol->type = S_UNKNOWN; symbol->type = S_UNKNOWN;
symbol->flags = SYMBOL_NEW;
if (isconst) if (isconst)
symbol->flags |= SYMBOL_CONST; symbol->flags |= SYMBOL_CONST;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment