diff options
Diffstat (limited to 'scripts/kconfig/confdata.c')
-rw-r--r-- | scripts/kconfig/confdata.c | 322 |
1 files changed, 218 insertions, 104 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c4dec80cfd8e..c39327e60ea4 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -170,8 +170,11 @@ int conf_read_simple(const char *name, int def) | |||
170 | if (in) | 170 | if (in) |
171 | goto load; | 171 | goto load; |
172 | sym_add_change_count(1); | 172 | sym_add_change_count(1); |
173 | if (!sym_defconfig_list) | 173 | if (!sym_defconfig_list) { |
174 | if (modules_sym) | ||
175 | sym_calc_value(modules_sym); | ||
174 | return 1; | 176 | return 1; |
177 | } | ||
175 | 178 | ||
176 | for_all_defaults(sym_defconfig_list, prop) { | 179 | for_all_defaults(sym_defconfig_list, prop) { |
177 | if (expr_calc_value(prop->visible.expr) == no || | 180 | if (expr_calc_value(prop->visible.expr) == no || |
@@ -396,15 +399,148 @@ int conf_read(const char *name) | |||
396 | return 0; | 399 | return 0; |
397 | } | 400 | } |
398 | 401 | ||
402 | /* Write a S_STRING */ | ||
403 | static void conf_write_string(bool headerfile, const char *name, | ||
404 | const char *str, FILE *out) | ||
405 | { | ||
406 | int l; | ||
407 | if (headerfile) | ||
408 | fprintf(out, "#define CONFIG_%s \"", name); | ||
409 | else | ||
410 | fprintf(out, "CONFIG_%s=\"", name); | ||
411 | |||
412 | while (1) { | ||
413 | l = strcspn(str, "\"\\"); | ||
414 | if (l) { | ||
415 | xfwrite(str, l, 1, out); | ||
416 | str += l; | ||
417 | } | ||
418 | if (!*str) | ||
419 | break; | ||
420 | fprintf(out, "\\%c", *str++); | ||
421 | } | ||
422 | fputs("\"\n", out); | ||
423 | } | ||
424 | |||
425 | static void conf_write_symbol(struct symbol *sym, enum symbol_type type, | ||
426 | FILE *out, bool write_no) | ||
427 | { | ||
428 | const char *str; | ||
429 | |||
430 | switch (type) { | ||
431 | case S_BOOLEAN: | ||
432 | case S_TRISTATE: | ||
433 | switch (sym_get_tristate_value(sym)) { | ||
434 | case no: | ||
435 | if (write_no) | ||
436 | fprintf(out, "# CONFIG_%s is not set\n", sym->name); | ||
437 | break; | ||
438 | case mod: | ||
439 | fprintf(out, "CONFIG_%s=m\n", sym->name); | ||
440 | break; | ||
441 | case yes: | ||
442 | fprintf(out, "CONFIG_%s=y\n", sym->name); | ||
443 | break; | ||
444 | } | ||
445 | break; | ||
446 | case S_STRING: | ||
447 | conf_write_string(false, sym->name, sym_get_string_value(sym), out); | ||
448 | break; | ||
449 | case S_HEX: | ||
450 | case S_INT: | ||
451 | str = sym_get_string_value(sym); | ||
452 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
453 | break; | ||
454 | case S_OTHER: | ||
455 | case S_UNKNOWN: | ||
456 | break; | ||
457 | } | ||
458 | } | ||
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 is bool and 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_get_tristate_value(sym) == yes) | ||
511 | goto next_menu; | ||
512 | } | ||
513 | } | ||
514 | conf_write_symbol(sym, sym->type, out, true); | ||
515 | } | ||
516 | next_menu: | ||
517 | if (menu->list != NULL) { | ||
518 | menu = menu->list; | ||
519 | } | ||
520 | else if (menu->next != NULL) { | ||
521 | menu = menu->next; | ||
522 | } else { | ||
523 | while ((menu = menu->parent)) { | ||
524 | if (menu->next != NULL) { | ||
525 | menu = menu->next; | ||
526 | break; | ||
527 | } | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | fclose(out); | ||
532 | return 0; | ||
533 | } | ||
534 | |||
399 | int conf_write(const char *name) | 535 | int conf_write(const char *name) |
400 | { | 536 | { |
401 | FILE *out; | 537 | FILE *out; |
402 | struct symbol *sym; | 538 | struct symbol *sym; |
403 | struct menu *menu; | 539 | struct menu *menu; |
404 | const char *basename; | 540 | const char *basename; |
405 | char dirname[128], tmpname[128], newname[128]; | ||
406 | int type, l; | ||
407 | const char *str; | 541 | const char *str; |
542 | char dirname[128], tmpname[128], newname[128]; | ||
543 | enum symbol_type type; | ||
408 | time_t now; | 544 | time_t now; |
409 | int use_timestamp = 1; | 545 | int use_timestamp = 1; |
410 | char *env; | 546 | char *env; |
@@ -484,50 +620,11 @@ int conf_write(const char *name) | |||
484 | if (modules_sym->curr.tri == no) | 620 | if (modules_sym->curr.tri == no) |
485 | type = S_BOOLEAN; | 621 | type = S_BOOLEAN; |
486 | } | 622 | } |
487 | switch (type) { | 623 | /* Write config symbol to file */ |
488 | case S_BOOLEAN: | 624 | conf_write_symbol(sym, type, out, true); |
489 | case S_TRISTATE: | ||
490 | switch (sym_get_tristate_value(sym)) { | ||
491 | case no: | ||
492 | fprintf(out, "# CONFIG_%s is not set\n", sym->name); | ||
493 | break; | ||
494 | case mod: | ||
495 | fprintf(out, "CONFIG_%s=m\n", sym->name); | ||
496 | break; | ||
497 | case yes: | ||
498 | fprintf(out, "CONFIG_%s=y\n", sym->name); | ||
499 | break; | ||
500 | } | ||
501 | break; | ||
502 | case S_STRING: | ||
503 | str = sym_get_string_value(sym); | ||
504 | fprintf(out, "CONFIG_%s=\"", sym->name); | ||
505 | while (1) { | ||
506 | l = strcspn(str, "\"\\"); | ||
507 | if (l) { | ||
508 | fwrite(str, l, 1, out); | ||
509 | str += l; | ||
510 | } | ||
511 | if (!*str) | ||
512 | break; | ||
513 | fprintf(out, "\\%c", *str++); | ||
514 | } | ||
515 | fputs("\"\n", out); | ||
516 | break; | ||
517 | case S_HEX: | ||
518 | str = sym_get_string_value(sym); | ||
519 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { | ||
520 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
521 | break; | ||
522 | } | ||
523 | case S_INT: | ||
524 | str = sym_get_string_value(sym); | ||
525 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
526 | break; | ||
527 | } | ||
528 | } | 625 | } |
529 | 626 | ||
530 | next: | 627 | next: |
531 | if (menu->list) { | 628 | if (menu->list) { |
532 | menu = menu->list; | 629 | menu = menu->list; |
533 | continue; | 630 | continue; |
@@ -679,7 +776,7 @@ int conf_write_autoconf(void) | |||
679 | const char *name; | 776 | const char *name; |
680 | FILE *out, *tristate, *out_h; | 777 | FILE *out, *tristate, *out_h; |
681 | time_t now; | 778 | time_t now; |
682 | int i, l; | 779 | int i; |
683 | 780 | ||
684 | sym_clear_all_valid(); | 781 | sym_clear_all_valid(); |
685 | 782 | ||
@@ -729,6 +826,11 @@ int conf_write_autoconf(void) | |||
729 | sym_calc_value(sym); | 826 | sym_calc_value(sym); |
730 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) | 827 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) |
731 | continue; | 828 | continue; |
829 | |||
830 | /* write symbol to config file */ | ||
831 | conf_write_symbol(sym, sym->type, out, false); | ||
832 | |||
833 | /* update autoconf and tristate files */ | ||
732 | switch (sym->type) { | 834 | switch (sym->type) { |
733 | case S_BOOLEAN: | 835 | case S_BOOLEAN: |
734 | case S_TRISTATE: | 836 | case S_TRISTATE: |
@@ -736,12 +838,10 @@ int conf_write_autoconf(void) | |||
736 | case no: | 838 | case no: |
737 | break; | 839 | break; |
738 | case mod: | 840 | case mod: |
739 | fprintf(out, "CONFIG_%s=m\n", sym->name); | ||
740 | fprintf(tristate, "CONFIG_%s=M\n", sym->name); | 841 | fprintf(tristate, "CONFIG_%s=M\n", sym->name); |
741 | fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); | 842 | fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); |
742 | break; | 843 | break; |
743 | case yes: | 844 | case yes: |
744 | fprintf(out, "CONFIG_%s=y\n", sym->name); | ||
745 | if (sym->type == S_TRISTATE) | 845 | if (sym->type == S_TRISTATE) |
746 | fprintf(tristate, "CONFIG_%s=Y\n", | 846 | fprintf(tristate, "CONFIG_%s=Y\n", |
747 | sym->name); | 847 | sym->name); |
@@ -750,35 +850,16 @@ int conf_write_autoconf(void) | |||
750 | } | 850 | } |
751 | break; | 851 | break; |
752 | case S_STRING: | 852 | case S_STRING: |
753 | str = sym_get_string_value(sym); | 853 | conf_write_string(true, sym->name, sym_get_string_value(sym), out_h); |
754 | fprintf(out, "CONFIG_%s=\"", sym->name); | ||
755 | fprintf(out_h, "#define CONFIG_%s \"", sym->name); | ||
756 | while (1) { | ||
757 | l = strcspn(str, "\"\\"); | ||
758 | if (l) { | ||
759 | fwrite(str, l, 1, out); | ||
760 | fwrite(str, l, 1, out_h); | ||
761 | str += l; | ||
762 | } | ||
763 | if (!*str) | ||
764 | break; | ||
765 | fprintf(out, "\\%c", *str); | ||
766 | fprintf(out_h, "\\%c", *str); | ||
767 | str++; | ||
768 | } | ||
769 | fputs("\"\n", out); | ||
770 | fputs("\"\n", out_h); | ||
771 | break; | 854 | break; |
772 | case S_HEX: | 855 | case S_HEX: |
773 | str = sym_get_string_value(sym); | 856 | str = sym_get_string_value(sym); |
774 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { | 857 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { |
775 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
776 | fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); | 858 | fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); |
777 | break; | 859 | break; |
778 | } | 860 | } |
779 | case S_INT: | 861 | case S_INT: |
780 | str = sym_get_string_value(sym); | 862 | str = sym_get_string_value(sym); |
781 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
782 | fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); | 863 | fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); |
783 | break; | 864 | break; |
784 | default: | 865 | default: |
@@ -837,13 +918,73 @@ void conf_set_changed_callback(void (*fn)(void)) | |||
837 | conf_changed_callback = fn; | 918 | conf_changed_callback = fn; |
838 | } | 919 | } |
839 | 920 | ||
921 | static void randomize_choice_values(struct symbol *csym) | ||
922 | { | ||
923 | struct property *prop; | ||
924 | struct symbol *sym; | ||
925 | struct expr *e; | ||
926 | int cnt, def; | ||
840 | 927 | ||
841 | void conf_set_all_new_symbols(enum conf_def_mode mode) | 928 | /* |
929 | * If choice is mod then we may have more items slected | ||
930 | * and if no then no-one. | ||
931 | * In both cases stop. | ||
932 | */ | ||
933 | if (csym->curr.tri != yes) | ||
934 | return; | ||
935 | |||
936 | prop = sym_get_choice_prop(csym); | ||
937 | |||
938 | /* count entries in choice block */ | ||
939 | cnt = 0; | ||
940 | expr_list_for_each_sym(prop->expr, e, sym) | ||
941 | cnt++; | ||
942 | |||
943 | /* | ||
944 | * find a random value and set it to yes, | ||
945 | * set the rest to no so we have only one set | ||
946 | */ | ||
947 | def = (rand() % cnt); | ||
948 | |||
949 | cnt = 0; | ||
950 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
951 | if (def == cnt++) { | ||
952 | sym->def[S_DEF_USER].tri = yes; | ||
953 | csym->def[S_DEF_USER].val = sym; | ||
954 | } | ||
955 | else { | ||
956 | sym->def[S_DEF_USER].tri = no; | ||
957 | } | ||
958 | } | ||
959 | csym->flags |= SYMBOL_DEF_USER; | ||
960 | /* clear VALID to get value calculated */ | ||
961 | csym->flags &= ~(SYMBOL_VALID); | ||
962 | } | ||
963 | |||
964 | static void set_all_choice_values(struct symbol *csym) | ||
842 | { | 965 | { |
843 | struct symbol *sym, *csym; | ||
844 | struct property *prop; | 966 | struct property *prop; |
967 | struct symbol *sym; | ||
845 | struct expr *e; | 968 | struct expr *e; |
846 | int i, cnt, def; | 969 | |
970 | prop = sym_get_choice_prop(csym); | ||
971 | |||
972 | /* | ||
973 | * Set all non-assinged choice values to no | ||
974 | */ | ||
975 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
976 | if (!sym_has_value(sym)) | ||
977 | sym->def[S_DEF_USER].tri = no; | ||
978 | } | ||
979 | csym->flags |= SYMBOL_DEF_USER; | ||
980 | /* clear VALID to get value calculated */ | ||
981 | csym->flags &= ~(SYMBOL_VALID); | ||
982 | } | ||
983 | |||
984 | void conf_set_all_new_symbols(enum conf_def_mode mode) | ||
985 | { | ||
986 | struct symbol *sym, *csym; | ||
987 | int i, cnt; | ||
847 | 988 | ||
848 | for_all_symbols(i, sym) { | 989 | for_all_symbols(i, sym) { |
849 | if (sym_has_value(sym)) | 990 | if (sym_has_value(sym)) |
@@ -862,7 +1003,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
862 | sym->def[S_DEF_USER].tri = no; | 1003 | sym->def[S_DEF_USER].tri = no; |
863 | break; | 1004 | break; |
864 | case def_random: | 1005 | case def_random: |
865 | sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); | 1006 | cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2; |
1007 | sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt); | ||
866 | break; | 1008 | break; |
867 | default: | 1009 | default: |
868 | continue; | 1010 | continue; |
@@ -878,8 +1020,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
878 | 1020 | ||
879 | sym_clear_all_valid(); | 1021 | sym_clear_all_valid(); |
880 | 1022 | ||
881 | if (mode != def_random) | ||
882 | return; | ||
883 | /* | 1023 | /* |
884 | * We have different type of choice blocks. | 1024 | * We have different type of choice blocks. |
885 | * If curr.tri equal to mod then we can select several | 1025 | * If curr.tri equal to mod then we can select several |
@@ -894,35 +1034,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
894 | continue; | 1034 | continue; |
895 | 1035 | ||
896 | sym_calc_value(csym); | 1036 | sym_calc_value(csym); |
897 | 1037 | if (mode == def_random) | |
898 | if (csym->curr.tri != yes) | 1038 | randomize_choice_values(csym); |
899 | continue; | 1039 | else |
900 | 1040 | set_all_choice_values(csym); | |
901 | prop = sym_get_choice_prop(csym); | ||
902 | |||
903 | /* count entries in choice block */ | ||
904 | cnt = 0; | ||
905 | expr_list_for_each_sym(prop->expr, e, sym) | ||
906 | cnt++; | ||
907 | |||
908 | /* | ||
909 | * find a random value and set it to yes, | ||
910 | * set the rest to no so we have only one set | ||
911 | */ | ||
912 | def = (rand() % cnt); | ||
913 | |||
914 | cnt = 0; | ||
915 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
916 | if (def == cnt++) { | ||
917 | sym->def[S_DEF_USER].tri = yes; | ||
918 | csym->def[S_DEF_USER].val = sym; | ||
919 | } | ||
920 | else { | ||
921 | sym->def[S_DEF_USER].tri = no; | ||
922 | } | ||
923 | } | ||
924 | csym->flags |= SYMBOL_DEF_USER; | ||
925 | /* clear VALID to get value calculated */ | ||
926 | csym->flags &= ~(SYMBOL_VALID); | ||
927 | } | 1041 | } |
928 | } | 1042 | } |