diff options
-rw-r--r-- | scripts/kconfig/Makefile | 6 | ||||
-rw-r--r-- | scripts/kconfig/conf.c | 14 | ||||
-rw-r--r-- | scripts/kconfig/confdata.c | 76 | ||||
-rw-r--r-- | scripts/kconfig/lkc.h | 1 | ||||
-rw-r--r-- | scripts/kconfig/lkc_proto.h | 1 | ||||
-rw-r--r-- | scripts/kconfig/symbol.c | 74 |
6 files changed, 171 insertions, 1 deletions
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 72973591c0f1..c0e459e2b014 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -90,11 +90,14 @@ PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig | |||
90 | allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf | 90 | allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf |
91 | $< --$@ $(Kconfig) | 91 | $< --$@ $(Kconfig) |
92 | 92 | ||
93 | PHONY += listnewconfig oldnoconfig defconfig | 93 | PHONY += listnewconfig oldnoconfig savedefconfig defconfig |
94 | 94 | ||
95 | listnewconfig oldnoconfig: $(obj)/conf | 95 | listnewconfig oldnoconfig: $(obj)/conf |
96 | $< --$@ $(Kconfig) | 96 | $< --$@ $(Kconfig) |
97 | 97 | ||
98 | savedefconfig: $(obj)/conf | ||
99 | $< --$@=defconfig $(Kconfig) | ||
100 | |||
98 | defconfig: $(obj)/conf | 101 | defconfig: $(obj)/conf |
99 | ifeq ($(KBUILD_DEFCONFIG),) | 102 | ifeq ($(KBUILD_DEFCONFIG),) |
100 | $< --defconfig $(Kconfig) | 103 | $< --defconfig $(Kconfig) |
@@ -118,6 +121,7 @@ help: | |||
118 | @echo ' localyesconfig - Update current config converting local mods to core' | 121 | @echo ' localyesconfig - Update current config converting local mods to core' |
119 | @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' | 122 | @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' |
120 | @echo ' defconfig - New config with default from ARCH supplied defconfig' | 123 | @echo ' defconfig - New config with default from ARCH supplied defconfig' |
124 | @echo ' savedefconfig - Save current config as ./defconfig (minimal config)' | ||
121 | @echo ' allnoconfig - New config where all options are answered with no' | 125 | @echo ' allnoconfig - New config where all options are answered with no' |
122 | @echo ' allyesconfig - New config where all options are accepted with yes' | 126 | @echo ' allyesconfig - New config where all options are accepted with yes' |
123 | @echo ' allmodconfig - New config selecting modules when possible' | 127 | @echo ' allmodconfig - New config selecting modules when possible' |
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index c8bd33cb3bf7..010600ef58c0 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -30,6 +30,7 @@ enum input_mode { | |||
30 | alldefconfig, | 30 | alldefconfig, |
31 | randconfig, | 31 | randconfig, |
32 | defconfig, | 32 | defconfig, |
33 | savedefconfig, | ||
33 | listnewconfig, | 34 | listnewconfig, |
34 | oldnoconfig, | 35 | oldnoconfig, |
35 | } input_mode = oldaskconfig; | 36 | } input_mode = oldaskconfig; |
@@ -444,6 +445,7 @@ static struct option long_opts[] = { | |||
444 | {"oldconfig", no_argument, NULL, oldconfig}, | 445 | {"oldconfig", no_argument, NULL, oldconfig}, |
445 | {"silentoldconfig", no_argument, NULL, silentoldconfig}, | 446 | {"silentoldconfig", no_argument, NULL, silentoldconfig}, |
446 | {"defconfig", optional_argument, NULL, defconfig}, | 447 | {"defconfig", optional_argument, NULL, defconfig}, |
448 | {"savedefconfig", required_argument, NULL, savedefconfig}, | ||
447 | {"allnoconfig", no_argument, NULL, allnoconfig}, | 449 | {"allnoconfig", no_argument, NULL, allnoconfig}, |
448 | {"allyesconfig", no_argument, NULL, allyesconfig}, | 450 | {"allyesconfig", no_argument, NULL, allyesconfig}, |
449 | {"allmodconfig", no_argument, NULL, allmodconfig}, | 451 | {"allmodconfig", no_argument, NULL, allmodconfig}, |
@@ -471,6 +473,7 @@ int main(int ac, char **av) | |||
471 | sync_kconfig = 1; | 473 | sync_kconfig = 1; |
472 | break; | 474 | break; |
473 | case defconfig: | 475 | case defconfig: |
476 | case savedefconfig: | ||
474 | defconfig_file = optarg; | 477 | defconfig_file = optarg; |
475 | break; | 478 | break; |
476 | case randconfig: | 479 | case randconfig: |
@@ -526,6 +529,9 @@ int main(int ac, char **av) | |||
526 | exit(1); | 529 | exit(1); |
527 | } | 530 | } |
528 | break; | 531 | break; |
532 | case savedefconfig: | ||
533 | conf_read(NULL); | ||
534 | break; | ||
529 | case silentoldconfig: | 535 | case silentoldconfig: |
530 | case oldaskconfig: | 536 | case oldaskconfig: |
531 | case oldconfig: | 537 | case oldconfig: |
@@ -591,6 +597,8 @@ int main(int ac, char **av) | |||
591 | case defconfig: | 597 | case defconfig: |
592 | conf_set_all_new_symbols(def_default); | 598 | conf_set_all_new_symbols(def_default); |
593 | break; | 599 | break; |
600 | case savedefconfig: | ||
601 | break; | ||
594 | case oldconfig: | 602 | case oldconfig: |
595 | case oldaskconfig: | 603 | case oldaskconfig: |
596 | rootEntry = &rootmenu; | 604 | rootEntry = &rootmenu; |
@@ -622,6 +630,12 @@ int main(int ac, char **av) | |||
622 | fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); | 630 | fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); |
623 | return 1; | 631 | return 1; |
624 | } | 632 | } |
633 | } else if (input_mode == savedefconfig) { | ||
634 | if (conf_write_defconfig(defconfig_file)) { | ||
635 | fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), | ||
636 | defconfig_file); | ||
637 | return 1; | ||
638 | } | ||
625 | } else if (input_mode != listnewconfig) { | 639 | } else if (input_mode != listnewconfig) { |
626 | if (conf_write(NULL)) { | 640 | if (conf_write(NULL)) { |
627 | fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); | 641 | fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 583f6405f01d..f81f263b64f2 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -457,6 +457,82 @@ static void conf_write_symbol(struct symbol *sym, enum symbol_type type, | |||
457 | } | 457 | } |
458 | } | 458 | } |
459 | 459 | ||
460 | /* | ||
461 | * Write out a minimal config. | ||
462 | * All values that has default values are skipped as this is redundant. | ||
463 | */ | ||
464 | int conf_write_defconfig(const char *filename) | ||
465 | { | ||
466 | struct symbol *sym; | ||
467 | struct menu *menu; | ||
468 | FILE *out; | ||
469 | |||
470 | out = fopen(filename, "w"); | ||
471 | if (!out) | ||
472 | return 1; | ||
473 | |||
474 | sym_clear_all_valid(); | ||
475 | |||
476 | /* Traverse all menus to find all relevant symbols */ | ||
477 | menu = rootmenu.list; | ||
478 | |||
479 | while (menu != NULL) | ||
480 | { | ||
481 | sym = menu->sym; | ||
482 | if (sym == NULL) { | ||
483 | if (!menu_is_visible(menu)) | ||
484 | goto next_menu; | ||
485 | } else if (!sym_is_choice(sym)) { | ||
486 | sym_calc_value(sym); | ||
487 | if (!(sym->flags & SYMBOL_WRITE)) | ||
488 | goto next_menu; | ||
489 | sym->flags &= ~SYMBOL_WRITE; | ||
490 | /* If we cannot change the symbol - skip */ | ||
491 | if (!sym_is_changable(sym)) | ||
492 | goto next_menu; | ||
493 | /* If symbol equals to default value - skip */ | ||
494 | if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) | ||
495 | goto next_menu; | ||
496 | |||
497 | /* | ||
498 | * If symbol is a choice value and equals to the | ||
499 | * default for a choice - skip. | ||
500 | * But only if value equal to "y". | ||
501 | */ | ||
502 | if (sym_is_choice_value(sym)) { | ||
503 | struct symbol *cs; | ||
504 | struct symbol *ds; | ||
505 | |||
506 | cs = prop_get_symbol(sym_get_choice_prop(sym)); | ||
507 | ds = sym_choice_default(cs); | ||
508 | if (sym == ds) { | ||
509 | if ((sym->type == S_BOOLEAN || | ||
510 | sym->type == S_TRISTATE) && | ||
511 | sym_get_tristate_value(sym) == yes) | ||
512 | goto next_menu; | ||
513 | } | ||
514 | } | ||
515 | conf_write_symbol(sym, sym->type, out, true); | ||
516 | } | ||
517 | next_menu: | ||
518 | if (menu->list != NULL) { | ||
519 | menu = menu->list; | ||
520 | } | ||
521 | else if (menu->next != NULL) { | ||
522 | menu = menu->next; | ||
523 | } else { | ||
524 | while ((menu = menu->parent)) { | ||
525 | if (menu->next != NULL) { | ||
526 | menu = menu->next; | ||
527 | break; | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | fclose(out); | ||
533 | return 0; | ||
534 | } | ||
535 | |||
460 | int conf_write(const char *name) | 536 | int conf_write(const char *name) |
461 | { | 537 | { |
462 | FILE *out; | 538 | FILE *out; |
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 755b8190eb64..76db065ed72c 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h | |||
@@ -127,6 +127,7 @@ void sym_clear_all_valid(void); | |||
127 | void sym_set_all_changed(void); | 127 | void sym_set_all_changed(void); |
128 | void sym_set_changed(struct symbol *sym); | 128 | void sym_set_changed(struct symbol *sym); |
129 | struct symbol *sym_choice_default(struct symbol *sym); | 129 | struct symbol *sym_choice_default(struct symbol *sym); |
130 | const char *sym_get_string_default(struct symbol *sym); | ||
130 | struct symbol *sym_check_deps(struct symbol *sym); | 131 | struct symbol *sym_check_deps(struct symbol *sym); |
131 | struct property *prop_alloc(enum prop_type type, struct symbol *sym); | 132 | struct property *prop_alloc(enum prop_type type, struct symbol *sym); |
132 | struct symbol *prop_get_symbol(struct property *prop); | 133 | struct symbol *prop_get_symbol(struct property *prop); |
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 7cadcad8233b..9a948c9ce44e 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h | |||
@@ -3,6 +3,7 @@ | |||
3 | P(conf_parse,void,(const char *name)); | 3 | P(conf_parse,void,(const char *name)); |
4 | P(conf_read,int,(const char *name)); | 4 | P(conf_read,int,(const char *name)); |
5 | P(conf_read_simple,int,(const char *name, int)); | 5 | P(conf_read_simple,int,(const char *name, int)); |
6 | P(conf_write_defconfig,int,(const char *name)); | ||
6 | P(conf_write,int,(const char *name)); | 7 | P(conf_write,int,(const char *name)); |
7 | P(conf_write_autoconf,int,(void)); | 8 | P(conf_write_autoconf,int,(void)); |
8 | P(conf_get_changed,bool,(void)); | 9 | P(conf_get_changed,bool,(void)); |
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 0a013ab3ae27..e95718fea355 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -661,6 +661,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval) | |||
661 | return true; | 661 | return true; |
662 | } | 662 | } |
663 | 663 | ||
664 | /* | ||
665 | * Find the default value associated to a symbol. | ||
666 | * For tristate symbol handle the modules=n case | ||
667 | * in which case "m" becomes "y". | ||
668 | * If the symbol does not have any default then fallback | ||
669 | * to the fixed default values. | ||
670 | */ | ||
671 | const char *sym_get_string_default(struct symbol *sym) | ||
672 | { | ||
673 | struct property *prop; | ||
674 | struct symbol *ds; | ||
675 | const char *str; | ||
676 | tristate val; | ||
677 | |||
678 | sym_calc_visibility(sym); | ||
679 | sym_calc_value(modules_sym); | ||
680 | val = symbol_no.curr.tri; | ||
681 | str = symbol_empty.curr.val; | ||
682 | |||
683 | /* If symbol has a default value look it up */ | ||
684 | prop = sym_get_default_prop(sym); | ||
685 | if (prop != NULL) { | ||
686 | switch (sym->type) { | ||
687 | case S_BOOLEAN: | ||
688 | case S_TRISTATE: | ||
689 | /* The visibility imay limit the value from yes => mod */ | ||
690 | val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); | ||
691 | break; | ||
692 | default: | ||
693 | /* | ||
694 | * The following fails to handle the situation | ||
695 | * where a default value is further limited by | ||
696 | * the valid range. | ||
697 | */ | ||
698 | ds = prop_get_symbol(prop); | ||
699 | if (ds != NULL) { | ||
700 | sym_calc_value(ds); | ||
701 | str = (const char *)ds->curr.val; | ||
702 | } | ||
703 | } | ||
704 | } | ||
705 | |||
706 | /* Handle select statements */ | ||
707 | val = EXPR_OR(val, sym->rev_dep.tri); | ||
708 | |||
709 | /* transpose mod to yes if modules are not enabled */ | ||
710 | if (val == mod) | ||
711 | if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no) | ||
712 | val = yes; | ||
713 | |||
714 | /* transpose mod to yes if type is bool */ | ||
715 | if (sym->type == S_BOOLEAN && val == mod) | ||
716 | val = yes; | ||
717 | |||
718 | switch (sym->type) { | ||
719 | case S_BOOLEAN: | ||
720 | case S_TRISTATE: | ||
721 | switch (val) { | ||
722 | case no: return "n"; | ||
723 | case mod: return "m"; | ||
724 | case yes: return "y"; | ||
725 | } | ||
726 | case S_INT: | ||
727 | case S_HEX: | ||
728 | return str; | ||
729 | case S_STRING: | ||
730 | return str; | ||
731 | case S_OTHER: | ||
732 | case S_UNKNOWN: | ||
733 | break; | ||
734 | } | ||
735 | return ""; | ||
736 | } | ||
737 | |||
664 | const char *sym_get_string_value(struct symbol *sym) | 738 | const char *sym_get_string_value(struct symbol *sym) |
665 | { | 739 | { |
666 | tristate val; | 740 | tristate val; |