x86: simplify "make ARCH=x86" and fix kconfig all.config
[linux-flexiantxendom0-natty.git] / scripts / kconfig / confdata.c
index 66b15ef..e0f402f 100644 (file)
@@ -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;
@@ -100,7 +162,7 @@ int conf_read_simple(const char *name, int def)
                in = zconf_fopen(name);
                if (in)
                        goto load;
-               sym_change_count++;
+               sym_add_change_count(1);
                if (!sym_defconfig_list)
                        return 1;
 
@@ -213,61 +275,8 @@ load:
                                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:
-                               ;
-                       }
+                       if (conf_set_sym_val(sym, def, def_flags, p))
+                               continue;
                        break;
                case '\r':
                case '\n':
@@ -312,7 +321,7 @@ int conf_read(const char *name)
        struct expr *e;
        int i, flags;
 
-       sym_change_count = 0;
+       sym_set_change_count(0);
 
        if (conf_read_simple(name, S_DEF_USER))
                return 1;
@@ -341,30 +350,45 @@ 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;
+               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;
+       }
+
+       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_change_count += conf_warnings || conf_unsaved;
+       sym_add_change_count(conf_warnings || conf_unsaved);
 
        return 0;
 }
@@ -432,7 +456,7 @@ int conf_write(const char *name)
                     use_timestamp ? "# " : "",
                     use_timestamp ? ctime(&now) : "");
 
-       if (!sym_change_count)
+       if (!conf_get_changed())
                sym_clear_all_valid();
 
        menu = rootmenu.list;
@@ -528,7 +552,7 @@ int conf_write(const char *name)
                 "# configuration written to %s\n"
                 "#\n"), newname);
 
-       sym_change_count = 0;
+       sym_set_change_count(0);
 
        return 0;
 }
@@ -765,3 +789,30 @@ int conf_write_autoconf(void)
 
        return 0;
 }
+
+static int sym_change_count;
+static void (*conf_changed_callback)(void);
+
+void sym_set_change_count(int count)
+{
+       int _sym_change_count = sym_change_count;
+       sym_change_count = count;
+       if (conf_changed_callback &&
+           (bool)_sym_change_count != (bool)count)
+               conf_changed_callback();
+}
+
+void sym_add_change_count(int count)
+{
+       sym_set_change_count(count + sym_change_count);
+}
+
+bool conf_get_changed(void)
+{
+       return sym_change_count;
+}
+
+void conf_set_changed_callback(void (*fn)(void))
+{
+       conf_changed_callback = fn;
+}