diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index fa8c2dd..7936c57 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -3,7 +3,7 @@ # These targets are used from top-level makefile PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \ - localmodconfig localyesconfig + localmodconfig localyesconfig reportoldconfig updateoldconfig ifdef KBUILD_KCONFIG Kconfig := $(KBUILD_KCONFIG) @@ -25,9 +25,15 @@ config: $(obj)/conf oldconfig: $(obj)/conf $< -o $(Kconfig) +reportoldconfig: $(obj)/conf + $< -R $(Kconfig) + silentoldconfig: $(obj)/conf $< -s $(Kconfig) +updateoldconfig: $(obj)/conf + $< -U $(Kconfig) + localmodconfig: $(obj)/streamline_config.pl $(obj)/conf $(Q)perl $< $(Kconfig) > .tmp.config $(Q)if [ -f .config ]; then \ diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 3e1057f..e526d00 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -434,12 +435,13 @@ int main(int ac, char **av) int opt; const char *name; struct stat tmpstat; + bool report = false, update = false; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { + while ((opt = getopt(ac, av, "osdD:nmyrRUh")) != -1) { switch (opt) { case 'o': input_mode = ask_silent; @@ -481,6 +482,14 @@ int main(int ac, char **av) input_mode = set_random; break; } + case 'R': + input_mode = set_default; + report = update = true; + break; + case 'U': + input_mode = set_default; + update = true; + break; case 'h': printf(_("See README for usage info\n")); exit(0); @@ -512,13 +522,17 @@ int main(int ac, char **av) switch (input_mode) { case set_default: - if (!defconfig_file) - defconfig_file = conf_get_default_confname(); - if (conf_read(defconfig_file)) { - printf(_("***\n" - "*** Can't find default configuration \"%s\"!\n" - "***\n"), defconfig_file); - exit(1); + if (update) + conf_read(NULL); + else { + if (!defconfig_file) + defconfig_file = conf_get_default_confname(); + if (conf_read(defconfig_file)) { + printf("***\n" + "*** Can't find default configuration \"%s\"!\n" + "***\n", defconfig_file); + exit(1); + } } break; case ask_silent: @@ -594,6 +608,9 @@ int main(int ac, char **av) break; } + if (report) + conf_write_changes(); + if (sync_kconfig) { /* silentoldconfig is used during the build so we shall update autoconf. * All other commands are only used to generate a config. diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 830d9ea..faf0b50 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -786,6 +786,85 @@ int conf_write_autoconf(void) return 0; } +void conf_write_changes(void) +{ + struct symbol *sym; + struct menu *menu; + int l; + const char *str; + + fprintf(stdout, "\n#\n" + "# Changes:\n" + "#\n"); + menu = rootmenu.list; + while (menu) { + sym = menu->sym; + if (sym && + !(sym->flags & SYMBOL_CHOICE) && + sym->flags & SYMBOL_WRITE && + sym->flags & SYMBOL_NEW && + sym->visible != no && + sym_is_changable(sym)) { + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + fprintf(stdout, "# CONFIG_%s is not set\n", sym->name); + break; + case mod: + fprintf(stdout, "CONFIG_%s=m\n", sym->name); + break; + case yes: + fprintf(stdout, "CONFIG_%s=y\n", sym->name); + break; + } + break; + case S_STRING: + str = sym_get_string_value(sym); + fprintf(stdout, "CONFIG_%s=\"", sym->name); + while (1) { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, stdout); + str += l; + } + if (!*str) + break; + fprintf(stdout, "\\%c", *str++); + } + fputs("\"\n", stdout); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(stdout, "CONFIG_%s=%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(stdout, "CONFIG_%s=%s\n", sym->name, str); + break; + default: + break; + } + } + + if (menu->list) { + menu = menu->list; + continue; + } + if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->next) { + menu = menu->next; + break; + } + } + } +} + static int sym_change_count; static void (*conf_changed_callback)(void); @@ -824,6 +903,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) for_all_symbols(i, sym) { if (sym_has_value(sym)) continue; + sym->flags |= SYMBOL_NEW; switch (sym_get_type(sym)) { case S_BOOLEAN: case S_TRISTATE: diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 6408fef..fd025e1 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -106,6 +106,7 @@ struct symbol { #define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ +#define SYMBOL_NEW 0x100000 #define SYMBOL_MAXLENGTH 256 #define SYMBOL_HASHSIZE 257 diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 8e69461..974acf0 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -5,6 +5,7 @@ P(conf_read,int,(const char *name)); P(conf_read_simple,int,(const char *name, int)); P(conf_write,int,(const char *name)); P(conf_write_autoconf,int,(void)); +P(conf_write_changes,void,(void)); P(conf_get_changed,bool,(void)); P(conf_set_changed_callback, void,(void (*fn)(void)));