diff options
Diffstat (limited to 'scripts/kconfig/confdata.c')
| -rw-r--r-- | scripts/kconfig/confdata.c | 324 | 
1 files changed, 220 insertions, 104 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c4dec80cfd8e..515253fe46cf 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,150 @@ 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" and | ||
| 501 | * choice is not "optional". | ||
| 502 | * (If choice is "optional" then all values can be "n") | ||
| 503 | */ | ||
| 504 | if (sym_is_choice_value(sym)) { | ||
| 505 | struct symbol *cs; | ||
| 506 | struct symbol *ds; | ||
| 507 | |||
| 508 | cs = prop_get_symbol(sym_get_choice_prop(sym)); | ||
| 509 | ds = sym_choice_default(cs); | ||
| 510 | if (!sym_is_optional(cs) && sym == ds) { | ||
| 511 | if ((sym->type == S_BOOLEAN) && | ||
| 512 | sym_get_tristate_value(sym) == yes) | ||
| 513 | goto next_menu; | ||
| 514 | } | ||
| 515 | } | ||
| 516 | conf_write_symbol(sym, sym->type, out, true); | ||
| 517 | } | ||
| 518 | next_menu: | ||
| 519 | if (menu->list != NULL) { | ||
| 520 | menu = menu->list; | ||
| 521 | } | ||
| 522 | else if (menu->next != NULL) { | ||
| 523 | menu = menu->next; | ||
| 524 | } else { | ||
| 525 | while ((menu = menu->parent)) { | ||
| 526 | if (menu->next != NULL) { | ||
| 527 | menu = menu->next; | ||
| 528 | break; | ||
| 529 | } | ||
| 530 | } | ||
| 531 | } | ||
| 532 | } | ||
| 533 | fclose(out); | ||
| 534 | return 0; | ||
| 535 | } | ||
| 536 | |||
| 399 | int conf_write(const char *name) | 537 | int conf_write(const char *name) | 
| 400 | { | 538 | { | 
| 401 | FILE *out; | 539 | FILE *out; | 
| 402 | struct symbol *sym; | 540 | struct symbol *sym; | 
| 403 | struct menu *menu; | 541 | struct menu *menu; | 
| 404 | const char *basename; | 542 | const char *basename; | 
| 405 | char dirname[128], tmpname[128], newname[128]; | ||
| 406 | int type, l; | ||
| 407 | const char *str; | 543 | const char *str; | 
| 544 | char dirname[128], tmpname[128], newname[128]; | ||
| 545 | enum symbol_type type; | ||
| 408 | time_t now; | 546 | time_t now; | 
| 409 | int use_timestamp = 1; | 547 | int use_timestamp = 1; | 
| 410 | char *env; | 548 | char *env; | 
| @@ -484,50 +622,11 @@ int conf_write(const char *name) | |||
| 484 | if (modules_sym->curr.tri == no) | 622 | if (modules_sym->curr.tri == no) | 
| 485 | type = S_BOOLEAN; | 623 | type = S_BOOLEAN; | 
| 486 | } | 624 | } | 
| 487 | switch (type) { | 625 | /* Write config symbol to file */ | 
| 488 | case S_BOOLEAN: | 626 | 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 | } | 627 | } | 
| 529 | 628 | ||
| 530 | next: | 629 | next: | 
| 531 | if (menu->list) { | 630 | if (menu->list) { | 
| 532 | menu = menu->list; | 631 | menu = menu->list; | 
| 533 | continue; | 632 | continue; | 
| @@ -679,7 +778,7 @@ int conf_write_autoconf(void) | |||
| 679 | const char *name; | 778 | const char *name; | 
| 680 | FILE *out, *tristate, *out_h; | 779 | FILE *out, *tristate, *out_h; | 
| 681 | time_t now; | 780 | time_t now; | 
| 682 | int i, l; | 781 | int i; | 
| 683 | 782 | ||
| 684 | sym_clear_all_valid(); | 783 | sym_clear_all_valid(); | 
| 685 | 784 | ||
| @@ -729,6 +828,11 @@ int conf_write_autoconf(void) | |||
| 729 | sym_calc_value(sym); | 828 | sym_calc_value(sym); | 
| 730 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) | 829 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) | 
| 731 | continue; | 830 | continue; | 
| 831 | |||
| 832 | /* write symbol to config file */ | ||
| 833 | conf_write_symbol(sym, sym->type, out, false); | ||
| 834 | |||
| 835 | /* update autoconf and tristate files */ | ||
| 732 | switch (sym->type) { | 836 | switch (sym->type) { | 
| 733 | case S_BOOLEAN: | 837 | case S_BOOLEAN: | 
| 734 | case S_TRISTATE: | 838 | case S_TRISTATE: | 
| @@ -736,12 +840,10 @@ int conf_write_autoconf(void) | |||
| 736 | case no: | 840 | case no: | 
| 737 | break; | 841 | break; | 
| 738 | case mod: | 842 | case mod: | 
| 739 | fprintf(out, "CONFIG_%s=m\n", sym->name); | ||
| 740 | fprintf(tristate, "CONFIG_%s=M\n", sym->name); | 843 | fprintf(tristate, "CONFIG_%s=M\n", sym->name); | 
| 741 | fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); | 844 | fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); | 
| 742 | break; | 845 | break; | 
| 743 | case yes: | 846 | case yes: | 
| 744 | fprintf(out, "CONFIG_%s=y\n", sym->name); | ||
| 745 | if (sym->type == S_TRISTATE) | 847 | if (sym->type == S_TRISTATE) | 
| 746 | fprintf(tristate, "CONFIG_%s=Y\n", | 848 | fprintf(tristate, "CONFIG_%s=Y\n", | 
| 747 | sym->name); | 849 | sym->name); | 
| @@ -750,35 +852,16 @@ int conf_write_autoconf(void) | |||
| 750 | } | 852 | } | 
| 751 | break; | 853 | break; | 
| 752 | case S_STRING: | 854 | case S_STRING: | 
| 753 | str = sym_get_string_value(sym); | 855 | 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; | 856 | break; | 
| 772 | case S_HEX: | 857 | case S_HEX: | 
| 773 | str = sym_get_string_value(sym); | 858 | str = sym_get_string_value(sym); | 
| 774 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { | 859 | 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); | 860 | fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); | 
| 777 | break; | 861 | break; | 
| 778 | } | 862 | } | 
| 779 | case S_INT: | 863 | case S_INT: | 
| 780 | str = sym_get_string_value(sym); | 864 | 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); | 865 | fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); | 
| 783 | break; | 866 | break; | 
| 784 | default: | 867 | default: | 
| @@ -837,13 +920,73 @@ void conf_set_changed_callback(void (*fn)(void)) | |||
| 837 | conf_changed_callback = fn; | 920 | conf_changed_callback = fn; | 
| 838 | } | 921 | } | 
| 839 | 922 | ||
| 923 | static void randomize_choice_values(struct symbol *csym) | ||
| 924 | { | ||
| 925 | struct property *prop; | ||
| 926 | struct symbol *sym; | ||
| 927 | struct expr *e; | ||
| 928 | int cnt, def; | ||
| 840 | 929 | ||
| 841 | void conf_set_all_new_symbols(enum conf_def_mode mode) | 930 | /* | 
| 931 | * If choice is mod then we may have more items slected | ||
| 932 | * and if no then no-one. | ||
| 933 | * In both cases stop. | ||
| 934 | */ | ||
| 935 | if (csym->curr.tri != yes) | ||
| 936 | return; | ||
| 937 | |||
| 938 | prop = sym_get_choice_prop(csym); | ||
| 939 | |||
| 940 | /* count entries in choice block */ | ||
| 941 | cnt = 0; | ||
| 942 | expr_list_for_each_sym(prop->expr, e, sym) | ||
| 943 | cnt++; | ||
| 944 | |||
| 945 | /* | ||
| 946 | * find a random value and set it to yes, | ||
| 947 | * set the rest to no so we have only one set | ||
| 948 | */ | ||
| 949 | def = (rand() % cnt); | ||
| 950 | |||
| 951 | cnt = 0; | ||
| 952 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
| 953 | if (def == cnt++) { | ||
| 954 | sym->def[S_DEF_USER].tri = yes; | ||
| 955 | csym->def[S_DEF_USER].val = sym; | ||
| 956 | } | ||
| 957 | else { | ||
| 958 | sym->def[S_DEF_USER].tri = no; | ||
| 959 | } | ||
| 960 | } | ||
| 961 | csym->flags |= SYMBOL_DEF_USER; | ||
| 962 | /* clear VALID to get value calculated */ | ||
| 963 | csym->flags &= ~(SYMBOL_VALID); | ||
| 964 | } | ||
| 965 | |||
| 966 | static void set_all_choice_values(struct symbol *csym) | ||
| 842 | { | 967 | { | 
| 843 | struct symbol *sym, *csym; | ||
| 844 | struct property *prop; | 968 | struct property *prop; | 
| 969 | struct symbol *sym; | ||
| 845 | struct expr *e; | 970 | struct expr *e; | 
| 846 | int i, cnt, def; | 971 | |
| 972 | prop = sym_get_choice_prop(csym); | ||
| 973 | |||
| 974 | /* | ||
| 975 | * Set all non-assinged choice values to no | ||
| 976 | */ | ||
| 977 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
| 978 | if (!sym_has_value(sym)) | ||
| 979 | sym->def[S_DEF_USER].tri = no; | ||
| 980 | } | ||
| 981 | csym->flags |= SYMBOL_DEF_USER; | ||
| 982 | /* clear VALID to get value calculated */ | ||
| 983 | csym->flags &= ~(SYMBOL_VALID); | ||
| 984 | } | ||
| 985 | |||
| 986 | void conf_set_all_new_symbols(enum conf_def_mode mode) | ||
| 987 | { | ||
| 988 | struct symbol *sym, *csym; | ||
| 989 | int i, cnt; | ||
| 847 | 990 | ||
| 848 | for_all_symbols(i, sym) { | 991 | for_all_symbols(i, sym) { | 
| 849 | if (sym_has_value(sym)) | 992 | if (sym_has_value(sym)) | 
| @@ -862,7 +1005,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
| 862 | sym->def[S_DEF_USER].tri = no; | 1005 | sym->def[S_DEF_USER].tri = no; | 
| 863 | break; | 1006 | break; | 
| 864 | case def_random: | 1007 | case def_random: | 
| 865 | sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); | 1008 | cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2; | 
| 1009 | sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt); | ||
| 866 | break; | 1010 | break; | 
| 867 | default: | 1011 | default: | 
| 868 | continue; | 1012 | continue; | 
| @@ -878,8 +1022,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
| 878 | 1022 | ||
| 879 | sym_clear_all_valid(); | 1023 | sym_clear_all_valid(); | 
| 880 | 1024 | ||
| 881 | if (mode != def_random) | ||
| 882 | return; | ||
| 883 | /* | 1025 | /* | 
| 884 | * We have different type of choice blocks. | 1026 | * We have different type of choice blocks. | 
| 885 | * If curr.tri equal to mod then we can select several | 1027 | * If curr.tri equal to mod then we can select several | 
| @@ -894,35 +1036,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
| 894 | continue; | 1036 | continue; | 
| 895 | 1037 | ||
| 896 | sym_calc_value(csym); | 1038 | sym_calc_value(csym); | 
| 897 | 1039 | if (mode == def_random) | |
| 898 | if (csym->curr.tri != yes) | 1040 | randomize_choice_values(csym); | 
| 899 | continue; | 1041 | else | 
| 900 | 1042 | 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 | } | 1043 | } | 
| 928 | } | 1044 | } | 
