X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=scripts%2Fkconfig%2Fconfdata.c;h=c1702d82b3b30a18459ba20ff8baa8f4f50d7aa2;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=f777c91437879d7a2aee94d0911495709dcef85b;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f777c9143..c1702d82b 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -21,8 +20,19 @@ static void conf_warning(const char *fmt, ...) static const char *conf_filename; static int conf_lineno, conf_warnings, conf_unsaved; +const char conf_def_filename[] = ".config"; + const char conf_defname[] = "arch/$ARCH/defconfig"; +const char *conf_confnames[] = { + ".config", + "/lib/modules/$UNAME_RELEASE/.config", + "/etc/kernel-config", + "/boot/config-$UNAME_RELEASE", + conf_defname, + NULL, +}; + static void conf_warning(const char *fmt, ...) { va_list ap; @@ -34,13 +44,6 @@ static void conf_warning(const char *fmt, ...) conf_warnings++; } -const char *conf_get_configname(void) -{ - char *name = getenv("KCONFIG_CONFIG"); - - return name ? name : ".config"; -} - static char *conf_expand_value(const char *in) { struct symbol *sym; @@ -83,65 +86,51 @@ char *conf_get_default_confname(void) return name; } -int conf_read_simple(const char *name, int def) +int conf_read_simple(const char *name) { FILE *in = NULL; char line[1024]; char *p, *p2; struct symbol *sym; - int i, def_flags; + int i; if (name) { in = zconf_fopen(name); } else { - struct property *prop; - - name = conf_get_configname(); - in = zconf_fopen(name); - if (in) - goto load; - sym_change_count++; - if (!sym_defconfig_list) - return 1; - - for_all_defaults(sym_defconfig_list, prop) { - if (expr_calc_value(prop->visible.expr) == no || - prop->expr->type != E_SYMBOL) - continue; - name = conf_expand_value(prop->expr->left.sym->name); + const char **names = conf_confnames; + while ((name = *names++)) { + name = conf_expand_value(name); in = zconf_fopen(name); if (in) { printf(_("#\n" - "# using defaults found in %s\n" - "#\n"), name); - goto load; + "# using defaults found in %s\n" + "#\n"), name); + break; } } } if (!in) return 1; -load: conf_filename = name; conf_lineno = 0; conf_warnings = 0; conf_unsaved = 0; - def_flags = SYMBOL_DEF << def; for_all_symbols(i, sym) { - sym->flags |= SYMBOL_CHANGED; - sym->flags &= ~(def_flags|SYMBOL_VALID); + sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; if (sym_is_choice(sym)) - sym->flags |= def_flags; + sym->flags &= ~SYMBOL_NEW; + sym->flags &= ~SYMBOL_VALID; switch (sym->type) { case S_INT: case S_HEX: case S_STRING: - if (sym->def[def].val) - free(sym->def[def].val); + if (sym->user.val) + free(sym->user.val); default: - sym->def[def].val = NULL; - sym->def[def].tri = no; + sym->user.val = NULL; + sym->user.tri = no; } } @@ -158,25 +147,18 @@ load: *p++ = 0; if (strncmp(p, "is not set", 10)) continue; - if (def == S_DEF_USER) { - sym = sym_find(line + 9); - if (!sym) { - conf_warning("trying to assign nonexistent symbol %s", line + 9); - break; - } - } else { - sym = sym_lookup(line + 9, 0); - if (sym->type == S_UNKNOWN) - sym->type = S_BOOLEAN; - } - if (sym->flags & def_flags) { + sym = sym_find(line + 9); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line + 9); + break; + } else if (!(sym->flags & SYMBOL_NEW)) { conf_warning("trying to reassign symbol %s", sym->name); } switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - sym->def[def].tri = no; - sym->flags |= def_flags; + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; break; default: ; @@ -194,47 +176,33 @@ load: p2 = strchr(p, '\n'); if (p2) *p2 = 0; - if (def == S_DEF_USER) { - sym = sym_find(line + 7); - if (!sym) { - conf_warning("trying to assign nonexistent symbol %s", line + 7); - break; - } - } else { - sym = sym_lookup(line + 7, 0); - if (sym->type == S_UNKNOWN) - sym->type = S_OTHER; - } - if (sym->flags & def_flags) { + sym = sym_find(line + 7); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line + 7); + break; + } else if (!(sym->flags & SYMBOL_NEW)) { conf_warning("trying to reassign symbol %s", sym->name); } switch (sym->type) { case S_TRISTATE: if (p[0] == 'm') { - sym->def[def].tri = mod; - sym->flags |= def_flags; + sym->user.tri = mod; + sym->flags &= ~SYMBOL_NEW; break; } case S_BOOLEAN: if (p[0] == 'y') { - sym->def[def].tri = yes; - sym->flags |= def_flags; + sym->user.tri = yes; + sym->flags &= ~SYMBOL_NEW; break; } if (p[0] == 'n') { - sym->def[def].tri = no; - sym->flags |= def_flags; + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; 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; @@ -251,10 +219,9 @@ load: } case S_INT: case S_HEX: - done: if (sym_string_valid(sym, p)) { - sym->def[def].val = strdup(p); - sym->flags |= def_flags; + sym->user.val = strdup(p); + sym->flags &= ~SYMBOL_NEW; } else { conf_warning("symbol value '%s' invalid for %s", p, sym->name); continue; @@ -272,24 +239,24 @@ load: } if (sym && sym_is_choice_value(sym)) { struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); - switch (sym->def[def].tri) { + switch (sym->user.tri) { case no: break; case mod: - if (cs->def[def].tri == yes) { + if (cs->user.tri == yes) { conf_warning("%s creates inconsistent choice state", sym->name); - cs->flags &= ~def_flags; + cs->flags |= SYMBOL_NEW; } break; case yes: - if (cs->def[def].tri != no) { + if (cs->user.tri != no) { conf_warning("%s creates inconsistent choice state", sym->name); - cs->flags &= ~def_flags; + cs->flags |= SYMBOL_NEW; } else - cs->def[def].val = sym; - break; + cs->user.val = sym; + //break; } - cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri); + cs->user.tri = E_OR(cs->user.tri, sym->user.tri); } } fclose(in); @@ -304,11 +271,9 @@ int conf_read(const char *name) struct symbol *sym; struct property *prop; struct expr *e; - int i, flags; - - sym_change_count = 0; + int i; - if (conf_read_simple(name, S_DEF_USER)) + if (conf_read_simple(name)) return 1; for_all_symbols(i, sym) { @@ -320,12 +285,12 @@ int conf_read(const char *name) switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) + if (sym->user.tri != sym_get_tristate_value(sym)) break; if (!sym_is_choice(sym)) goto sym_ok; default: - if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) + if (!strcmp(sym->curr.val, sym->user.val)) goto sym_ok; break; } @@ -337,13 +302,15 @@ int conf_read(const char *name) sym_ok: if (sym_has_value(sym) && !sym_is_choice_value(sym)) { if (sym->visible == no) - sym->flags &= ~SYMBOL_DEF_USER; + sym->flags |= SYMBOL_NEW; 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); + if (!sym_string_within_range(sym, sym->user.val)) { + sym->flags |= SYMBOL_NEW; + sym->flags &= ~SYMBOL_VALID; + } default: break; } @@ -351,21 +318,19 @@ int conf_read(const char *name) 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->flags |= e->right.sym->flags & SYMBOL_NEW; } - sym_change_count += conf_warnings || conf_unsaved; + sym_change_count = conf_warnings || conf_unsaved; return 0; } int conf_write(const char *name) { - FILE *out; + FILE *out, *out_h; struct symbol *sym; struct menu *menu; const char *basename; @@ -384,7 +349,7 @@ int conf_write(const char *name) if (!stat(name, &st) && S_ISDIR(st.st_mode)) { strcpy(dirname, name); strcat(dirname, "/"); - basename = conf_get_configname(); + basename = conf_def_filename; } else if ((slash = strrchr(name, '/'))) { int size = slash - name + 1; memcpy(dirname, name, size); @@ -392,24 +357,23 @@ int conf_write(const char *name) if (slash[1]) basename = slash + 1; else - basename = conf_get_configname(); + basename = conf_def_filename; } else basename = name; } else - basename = conf_get_configname(); + basename = conf_def_filename; - sprintf(newname, "%s%s", dirname, basename); - env = getenv("KCONFIG_OVERWRITECONFIG"); - if (!env || !*env) { - sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); - out = fopen(tmpname, "w"); - } else { - *tmpname = 0; - out = fopen(newname, "w"); - } + sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); + out = fopen(newname, "w"); if (!out) return 1; - + out_h = NULL; + if (!name) { + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) + return 1; + file_write_dep(NULL); + } sym = sym_lookup("KERNELVERSION", 0); sym_calc_value(sym); time(&now); @@ -425,6 +389,16 @@ int conf_write(const char *name) sym_get_string_value(sym), use_timestamp ? "# " : "", use_timestamp ? ctime(&now) : ""); + if (out_h) + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " * Linux kernel version: %s\n" + "%s%s" + " */\n" + "#define AUTOCONF_INCLUDED\n", + sym_get_string_value(sym), + use_timestamp ? " * " : "", + use_timestamp ? ctime(&now) : ""); if (!sym_change_count) sym_clear_all_valid(); @@ -440,6 +414,11 @@ int conf_write(const char *name) "#\n" "# %s\n" "#\n", str); + if (out_h) + fprintf(out_h, "\n" + "/*\n" + " * %s\n" + " */\n", str); } else if (!(sym->flags & SYMBOL_CHOICE)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) @@ -457,39 +436,59 @@ int conf_write(const char *name) switch (sym_get_tristate_value(sym)) { case no: fprintf(out, "# CONFIG_%s is not set\n", sym->name); + if (out_h) + fprintf(out_h, "#undef CONFIG_%s\n", sym->name); break; case mod: fprintf(out, "CONFIG_%s=m\n", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); break; case yes: fprintf(out, "CONFIG_%s=y\n", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); break; } break; case S_STRING: + // fix me str = sym_get_string_value(sym); fprintf(out, "CONFIG_%s=\"", sym->name); - while (1) { + if (out_h) + fprintf(out_h, "#define CONFIG_%s \"", sym->name); + do { l = strcspn(str, "\"\\"); if (l) { fwrite(str, l, 1, out); - str += l; + if (out_h) + fwrite(str, l, 1, out_h); } - if (!*str) - break; - fprintf(out, "\\%c", *str++); - } + str += l; + while (*str == '\\' || *str == '"') { + fprintf(out, "\\%c", *str); + if (out_h) + fprintf(out_h, "\\%c", *str); + str++; + } + } while (*str); fputs("\"\n", out); + if (out_h) + fputs("\"\n", out_h); break; case S_HEX: str = sym_get_string_value(sym); if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); break; } case S_INT: str = sym_get_string_value(sym); fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); break; } } @@ -509,253 +508,21 @@ int conf_write(const char *name) } } fclose(out); - - if (*tmpname) { - strcat(dirname, name ? name : conf_get_configname()); - strcat(dirname, ".old"); - rename(newname, dirname); - if (rename(tmpname, newname)) - return 1; + if (out_h) { + fclose(out_h); + rename(".tmpconfig.h", "include/linux/autoconf.h"); } - - printf(_("#\n" - "# configuration written to %s\n" - "#\n"), newname); - - sym_change_count = 0; - - return 0; -} - -int conf_split_config(void) -{ - char *name, path[128]; - char *s, *d, c; - struct symbol *sym; - struct stat sb; - int res, i, fd; - - name = getenv("KCONFIG_AUTOCONFIG"); - if (!name) - name = "include/config/auto.conf"; - conf_read_simple(name, S_DEF_AUTO); - - if (chdir("include/config")) - return 1; - - res = 0; - for_all_symbols(i, sym) { - sym_calc_value(sym); - if ((sym->flags & SYMBOL_AUTO) || !sym->name) - continue; - if (sym->flags & SYMBOL_WRITE) { - if (sym->flags & SYMBOL_DEF_AUTO) { - /* - * symbol has old and new value, - * so compare them... - */ - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - if (sym_get_tristate_value(sym) == - sym->def[S_DEF_AUTO].tri) - continue; - break; - case S_STRING: - case S_HEX: - case S_INT: - if (!strcmp(sym_get_string_value(sym), - sym->def[S_DEF_AUTO].val)) - continue; - break; - default: - break; - } - } else { - /* - * If there is no old value, only 'no' (unset) - * is allowed as new value. - */ - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - if (sym_get_tristate_value(sym) == no) - continue; - break; - default: - break; - } - } - } else if (!(sym->flags & SYMBOL_DEF_AUTO)) - /* There is neither an old nor a new value. */ - continue; - /* else - * There is an old value, but no new value ('no' (unset) - * isn't saved in auto.conf, so the old value is always - * different from 'no'). - */ - - /* Replace all '_' and append ".h" */ - s = sym->name; - d = path; - while ((c = *s++)) { - c = tolower(c); - *d++ = (c == '_') ? '/' : c; - } - strcpy(d, ".h"); - - /* Assume directory path already exists. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - if (errno != ENOENT) { - res = 1; - break; - } - /* - * Create directory components, - * unless they exist already. - */ - d = path; - while ((d = strchr(d, '/'))) { - *d = 0; - if (stat(path, &sb) && mkdir(path, 0755)) { - res = 1; - goto out; - } - *d++ = '/'; - } - /* Try it again. */ - fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - res = 1; - break; - } - } - close(fd); + if (!name || basename != conf_def_filename) { + if (!name) + name = conf_def_filename; + sprintf(tmpname, "%s.old", name); + rename(name, tmpname); } -out: - if (chdir("../..")) - return 1; - - return res; -} - -int conf_write_autoconf(void) -{ - struct symbol *sym; - const char *str; - char *name; - FILE *out, *out_h; - time_t now; - int i, l; - - sym_clear_all_valid(); - - file_write_dep("include/config/auto.conf.cmd"); - - if (conf_split_config()) - return 1; - - out = fopen(".tmpconfig", "w"); - if (!out) - return 1; - - out_h = fopen(".tmpconfig.h", "w"); - if (!out_h) { - fclose(out); + sprintf(tmpname, "%s%s", dirname, basename); + if (rename(newname, tmpname)) return 1; - } - - sym = sym_lookup("KERNELVERSION", 0); - sym_calc_value(sym); - time(&now); - fprintf(out, "#\n" - "# Automatically generated make config: don't edit\n" - "# Linux kernel version: %s\n" - "# %s" - "#\n", - sym_get_string_value(sym), ctime(&now)); - fprintf(out_h, "/*\n" - " * Automatically generated C config: don't edit\n" - " * Linux kernel version: %s\n" - " * %s" - " */\n" - "#define AUTOCONF_INCLUDED\n", - sym_get_string_value(sym), ctime(&now)); - for_all_symbols(i, sym) { - sym_calc_value(sym); - if (!(sym->flags & SYMBOL_WRITE) || !sym->name) - continue; - switch (sym->type) { - case S_BOOLEAN: - case S_TRISTATE: - switch (sym_get_tristate_value(sym)) { - case no: - break; - case mod: - fprintf(out, "CONFIG_%s=m\n", sym->name); - fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); - break; - case yes: - fprintf(out, "CONFIG_%s=y\n", sym->name); - fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); - break; - } - break; - case S_STRING: - str = sym_get_string_value(sym); - fprintf(out, "CONFIG_%s=\"", sym->name); - fprintf(out_h, "#define CONFIG_%s \"", sym->name); - while (1) { - l = strcspn(str, "\"\\"); - if (l) { - fwrite(str, l, 1, out); - fwrite(str, l, 1, out_h); - str += l; - } - if (!*str) - break; - fprintf(out, "\\%c", *str); - fprintf(out_h, "\\%c", *str); - str++; - } - fputs("\"\n", out); - fputs("\"\n", out_h); - break; - case S_HEX: - str = sym_get_string_value(sym); - if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { - fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); - break; - } - case S_INT: - str = sym_get_string_value(sym); - fprintf(out, "CONFIG_%s=%s\n", sym->name, str); - fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); - break; - default: - break; - } - } - fclose(out); - fclose(out_h); - - name = getenv("KCONFIG_AUTOHEADER"); - if (!name) - name = "include/linux/autoconf.h"; - if (rename(".tmpconfig.h", name)) - return 1; - name = getenv("KCONFIG_AUTOCONFIG"); - if (!name) - name = "include/config/auto.conf"; - /* - * This must be the last step, kbuild has a dependency on auto.conf - * and this marks the successful completion of the previous steps. - */ - if (rename(".tmpconfig", name)) - return 1; + sym_change_count = 0; return 0; }