summaryrefslogtreecommitdiff
path: root/kconfig/confdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'kconfig/confdata.c')
-rw-r--r--kconfig/confdata.c254
1 files changed, 172 insertions, 82 deletions
diff --git a/kconfig/confdata.c b/kconfig/confdata.c
index 0774a4a..a201411 100644
--- a/kconfig/confdata.c
+++ b/kconfig/confdata.c
@@ -83,6 +83,68 @@ char *conf_get_default_confname(void)
return name;
}
+static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
+{
+ char *p2;
+
+ switch (sym->type) {
+ case S_TRISTATE:
+ if (p[0] == 'm') {
+ sym->def[def].tri = mod;
+ sym->flags |= def_flags;
+ break;
+ }
+ case S_BOOLEAN:
+ if (p[0] == 'y') {
+ sym->def[def].tri = yes;
+ sym->flags |= def_flags;
+ break;
+ }
+ if (p[0] == 'n') {
+ sym->def[def].tri = no;
+ sym->flags |= def_flags;
+ break;
+ }
+ conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+ break;
+ case S_OTHER:
+ if (*p != '"') {
+ for (p2 = p; *p2 && !isspace(*p2); p2++)
+ ;
+ sym->type = S_STRING;
+ goto done;
+ }
+ case S_STRING:
+ if (*p++ != '"')
+ break;
+ for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+ if (*p2 == '"') {
+ *p2 = 0;
+ break;
+ }
+ memmove(p2, p2 + 1, strlen(p2));
+ }
+ if (!p2) {
+ conf_warning("invalid string found");
+ return 1;
+ }
+ case S_INT:
+ case S_HEX:
+ done:
+ if (sym_string_valid(sym, p)) {
+ sym->def[def].val = strdup(p);
+ sym->flags |= def_flags;
+ } else {
+ conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+ return 1;
+ }
+ break;
+ default:
+ ;
+ }
+ return 0;
+}
+
int conf_read_simple(const char *name, int def)
{
FILE *in = NULL;
@@ -161,7 +223,7 @@ load:
if (def == S_DEF_USER) {
sym = sym_find(line + 5);
if (!sym) {
- conf_warning("trying to assign nonexistent symbol %s", line + 5);
+ sym_add_change_count(1);
break;
}
} else {
@@ -170,8 +232,7 @@ load:
sym->type = S_BOOLEAN;
}
if (sym->flags & def_flags) {
- conf_warning("trying to reassign symbol %s", sym->name);
- break;
+ conf_warning("override: reassigning to symbol %s", sym->name);
}
switch (sym->type) {
case S_BOOLEAN:
@@ -201,7 +262,7 @@ load:
if (def == S_DEF_USER) {
sym = sym_find(line + 3);
if (!sym) {
- conf_warning("trying to assign nonexistent symbol %s", line + 3);
+ sym_add_change_count(1);
break;
}
} else {
@@ -210,64 +271,10 @@ load:
sym->type = S_OTHER;
}
if (sym->flags & def_flags) {
- conf_warning("trying to reassign symbol %s", sym->name);
- break;
- }
- switch (sym->type) {
- case S_TRISTATE:
- if (p[0] == 'm') {
- sym->def[def].tri = mod;
- sym->flags |= def_flags;
- break;
- }
- case S_BOOLEAN:
- if (p[0] == 'y') {
- sym->def[def].tri = yes;
- sym->flags |= def_flags;
- break;
- }
- if (p[0] == 'n') {
- sym->def[def].tri = no;
- sym->flags |= def_flags;
- break;
- }
- conf_warning("symbol value '%s' invalid for %s", p, sym->name);
- break;
- case S_OTHER:
- if (*p != '"') {
- for (p2 = p; *p2 && !isspace(*p2); p2++)
- ;
- sym->type = S_STRING;
- goto done;
- }
- case S_STRING:
- if (*p++ != '"')
- break;
- for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
- if (*p2 == '"') {
- *p2 = 0;
- break;
- }
- memmove(p2, p2 + 1, strlen(p2));
- }
- if (!p2) {
- conf_warning("invalid string found");
- continue;
- }
- case S_INT:
- case S_HEX:
- done:
- if (sym_string_valid(sym, p)) {
- sym->def[def].val = strdup(p);
- sym->flags |= def_flags;
- } else {
- conf_warning("symbol value '%s' invalid for %s", p, sym->name);
- continue;
- }
- break;
- default:
- ;
+ conf_warning("override: reassigning to symbol %s", sym->name);
}
+ if (conf_set_sym_val(sym, def, def_flags, p))
+ continue;
break;
case '\r':
case '\n':
@@ -288,14 +295,12 @@ load:
}
break;
case yes:
- if (cs->def[def].tri != no) {
- conf_warning("%s creates inconsistent choice state", sym->name);
- cs->flags &= ~def_flags;
- } else
- cs->def[def].val = sym;
+ if (cs->def[def].tri != no)
+ conf_warning("override: %s changes choice state", sym->name);
+ cs->def[def].val = sym;
break;
}
- cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
+ cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
}
}
fclose(in);
@@ -307,7 +312,7 @@ load:
int conf_read(const char *name)
{
- struct symbol *sym;
+ struct symbol *sym, *choice_sym;
struct property *prop;
struct expr *e;
int i, flags;
@@ -341,27 +346,42 @@ int conf_read(const char *name)
conf_unsaved++;
/* maybe print value in verbose mode... */
sym_ok:
+ if (!sym_is_choice(sym))
+ continue;
+ /* The choice symbol only has a set value (and thus is not new)
+ * if all its visible childs have values.
+ */
+ prop = sym_get_choice_prop(sym);
+ flags = sym->flags;
+ expr_list_for_each_sym(prop->expr, e, choice_sym)
+ if (choice_sym->visible != no)
+ flags &= choice_sym->flags;
+ sym->flags &= flags | ~SYMBOL_DEF_USER;
+ }
+
+ for_all_symbols(i, sym) {
if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
- if (sym->visible == no)
+ /* Reset values of generates values, so they'll appear
+ * as new, if they should become visible, but that
+ * doesn't quite work if the Kconfig and the saved
+ * configuration disagree.
+ */
+ if (sym->visible == no && !conf_unsaved)
sym->flags &= ~SYMBOL_DEF_USER;
switch (sym->type) {
case S_STRING:
case S_INT:
case S_HEX:
- if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
- sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+ /* Reset a string value if it's out of range */
+ if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+ break;
+ sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+ conf_unsaved++;
+ break;
default:
break;
}
}
- if (!sym_is_choice(sym))
- continue;
- prop = sym_get_choice_prop(sym);
- flags = sym->flags;
- for (e = prop->expr; e; e = e->left.expr)
- if (e->right.sym->visible != no)
- flags &= e->right.sym->flags;
- sym->flags &= flags | ~SYMBOL_DEF_USER;
}
sym_add_change_count(conf_warnings || conf_unsaved);
@@ -425,7 +445,7 @@ int conf_write(const char *name)
fprintf(out, _("#\n"
"# Automatically generated make config: don't edit\n"
- "# "PROJECT_NAME" version: %s\n"
+ "# " PACKAGE " version: %s\n"
"%s%s"
"#\n"),
sym_get_string_value(sym),
@@ -673,13 +693,13 @@ int conf_write_autoconf(void)
time(&now);
fprintf(out, "#\n"
"# Automatically generated make config: don't edit\n"
- "# "PROJECT_NAME" version: %s\n"
+ "# " PACKAGE " version: %s\n"
"# %s"
"#\n",
sym_get_string_value(sym), ctime(&now));
fprintf(out_h, "/*\n"
" * Automatically generated C config: don't edit\n"
- " * "PROJECT_NAME" version: %s\n"
+ " * " PACKAGE " version: %s\n"
" * %s"
" */\n"
"#define AUTOCONF_INCLUDED\n",
@@ -788,3 +808,73 @@ void conf_set_changed_callback(void (*fn)(void))
{
conf_changed_callback = fn;
}
+
+
+void conf_set_all_new_symbols(enum conf_def_mode mode)
+{
+ struct symbol *sym, *csym;
+ struct property *prop;
+ struct expr *e;
+ int i, cnt, def;
+
+ for_all_symbols(i, sym) {
+ if (sym_has_value(sym))
+ continue;
+ switch (sym_get_type(sym)) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ switch (mode) {
+ case def_yes:
+ sym->def[S_DEF_USER].tri = yes;
+ break;
+ case def_mod:
+ sym->def[S_DEF_USER].tri = mod;
+ break;
+ case def_no:
+ sym->def[S_DEF_USER].tri = no;
+ break;
+ case def_random:
+ sym->def[S_DEF_USER].tri = (tristate)(rand() % 3);
+ break;
+ default:
+ continue;
+ }
+ if (!sym_is_choice(sym) || mode != def_random)
+ sym->flags |= SYMBOL_DEF_USER;
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ if (modules_sym)
+ sym_calc_value(modules_sym);
+
+ if (mode != def_random)
+ return;
+
+ for_all_symbols(i, csym) {
+ if (sym_has_value(csym) || !sym_is_choice(csym))
+ continue;
+
+ sym_calc_value(csym);
+ prop = sym_get_choice_prop(csym);
+ def = -1;
+ while (1) {
+ cnt = 0;
+ expr_list_for_each_sym(prop->expr, e, sym) {
+ if (sym->visible == no)
+ continue;
+ if (def == cnt++) {
+ csym->def[S_DEF_USER].val = sym;
+ break;
+ }
+ }
+ if (def >= 0 || cnt < 2)
+ break;
+ def = (rand() % cnt) + 1;
+ }
+ csym->flags |= SYMBOL_DEF_USER;
+ }
+}