diff options
Diffstat (limited to 'scripts/kconfig/confdata.c')
-rw-r--r-- | scripts/kconfig/confdata.c | 295 |
1 files changed, 194 insertions, 101 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 2bafd9a7c8d..59b667cae5f 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -7,13 +7,13 @@ | |||
7 | #include <ctype.h> | 7 | #include <ctype.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <fcntl.h> | 9 | #include <fcntl.h> |
10 | #include <stdarg.h> | ||
10 | #include <stdio.h> | 11 | #include <stdio.h> |
11 | #include <stdlib.h> | 12 | #include <stdlib.h> |
12 | #include <string.h> | 13 | #include <string.h> |
13 | #include <time.h> | 14 | #include <time.h> |
14 | #include <unistd.h> | 15 | #include <unistd.h> |
15 | 16 | ||
16 | #define LKC_DIRECT_LINK | ||
17 | #include "lkc.h" | 17 | #include "lkc.h" |
18 | 18 | ||
19 | static void conf_warning(const char *fmt, ...) | 19 | static void conf_warning(const char *fmt, ...) |
@@ -128,6 +128,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | |||
128 | sym->flags |= def_flags; | 128 | sym->flags |= def_flags; |
129 | break; | 129 | break; |
130 | } | 130 | } |
131 | /* fall through */ | ||
131 | case S_BOOLEAN: | 132 | case S_BOOLEAN: |
132 | if (p[0] == 'y') { | 133 | if (p[0] == 'y') { |
133 | sym->def[def].tri = yes; | 134 | sym->def[def].tri = yes; |
@@ -140,7 +141,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | |||
140 | break; | 141 | break; |
141 | } | 142 | } |
142 | conf_warning("symbol value '%s' invalid for %s", p, sym->name); | 143 | conf_warning("symbol value '%s' invalid for %s", p, sym->name); |
143 | break; | 144 | return 1; |
144 | case S_OTHER: | 145 | case S_OTHER: |
145 | if (*p != '"') { | 146 | if (*p != '"') { |
146 | for (p2 = p; *p2 && !isspace(*p2); p2++) | 147 | for (p2 = p; *p2 && !isspace(*p2); p2++) |
@@ -148,6 +149,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | |||
148 | sym->type = S_STRING; | 149 | sym->type = S_STRING; |
149 | goto done; | 150 | goto done; |
150 | } | 151 | } |
152 | /* fall through */ | ||
151 | case S_STRING: | 153 | case S_STRING: |
152 | if (*p++ != '"') | 154 | if (*p++ != '"') |
153 | break; | 155 | break; |
@@ -162,6 +164,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) | |||
162 | conf_warning("invalid string found"); | 164 | conf_warning("invalid string found"); |
163 | return 1; | 165 | return 1; |
164 | } | 166 | } |
167 | /* fall through */ | ||
165 | case S_INT: | 168 | case S_INT: |
166 | case S_HEX: | 169 | case S_HEX: |
167 | done: | 170 | done: |
@@ -237,6 +240,7 @@ load: | |||
237 | case S_STRING: | 240 | case S_STRING: |
238 | if (sym->def[def].val) | 241 | if (sym->def[def].val) |
239 | free(sym->def[def].val); | 242 | free(sym->def[def].val); |
243 | /* fall through */ | ||
240 | default: | 244 | default: |
241 | sym->def[def].val = NULL; | 245 | sym->def[def].val = NULL; |
242 | sym->def[def].tri = no; | 246 | sym->def[def].tri = no; |
@@ -363,6 +367,7 @@ int conf_read(const char *name) | |||
363 | break; | 367 | break; |
364 | if (!sym_is_choice(sym)) | 368 | if (!sym_is_choice(sym)) |
365 | goto sym_ok; | 369 | goto sym_ok; |
370 | /* fall through */ | ||
366 | default: | 371 | default: |
367 | if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) | 372 | if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) |
368 | goto sym_ok; | 373 | goto sym_ok; |
@@ -417,64 +422,202 @@ int conf_read(const char *name) | |||
417 | return 0; | 422 | return 0; |
418 | } | 423 | } |
419 | 424 | ||
420 | /* Write a S_STRING */ | 425 | /* |
421 | static void conf_write_string(bool headerfile, const char *name, | 426 | * Kconfig configuration printer |
422 | const char *str, FILE *out) | 427 | * |
428 | * This printer is used when generating the resulting configuration after | ||
429 | * kconfig invocation and `defconfig' files. Unset symbol might be omitted by | ||
430 | * passing a non-NULL argument to the printer. | ||
431 | * | ||
432 | */ | ||
433 | static void | ||
434 | kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) | ||
423 | { | 435 | { |
424 | int l; | 436 | |
425 | if (headerfile) | 437 | switch (sym->type) { |
426 | fprintf(out, "#define %s%s \"", CONFIG_, name); | 438 | case S_BOOLEAN: |
427 | else | 439 | case S_TRISTATE: |
428 | fprintf(out, "%s%s=\"", CONFIG_, name); | 440 | if (*value == 'n') { |
429 | 441 | bool skip_unset = (arg != NULL); | |
430 | while (1) { | 442 | |
431 | l = strcspn(str, "\"\\"); | 443 | if (!skip_unset) |
444 | fprintf(fp, "# %s%s is not set\n", | ||
445 | CONFIG_, sym->name); | ||
446 | return; | ||
447 | } | ||
448 | break; | ||
449 | default: | ||
450 | break; | ||
451 | } | ||
452 | |||
453 | fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value); | ||
454 | } | ||
455 | |||
456 | static void | ||
457 | kconfig_print_comment(FILE *fp, const char *value, void *arg) | ||
458 | { | ||
459 | const char *p = value; | ||
460 | size_t l; | ||
461 | |||
462 | for (;;) { | ||
463 | l = strcspn(p, "\n"); | ||
464 | fprintf(fp, "#"); | ||
432 | if (l) { | 465 | if (l) { |
433 | xfwrite(str, l, 1, out); | 466 | fprintf(fp, " "); |
434 | str += l; | 467 | fwrite(p, l, 1, fp); |
468 | p += l; | ||
435 | } | 469 | } |
436 | if (!*str) | 470 | fprintf(fp, "\n"); |
471 | if (*p++ == '\0') | ||
437 | break; | 472 | break; |
438 | fprintf(out, "\\%c", *str++); | ||
439 | } | 473 | } |
440 | fputs("\"\n", out); | ||
441 | } | 474 | } |
442 | 475 | ||
443 | static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no) | 476 | static struct conf_printer kconfig_printer_cb = |
477 | { | ||
478 | .print_symbol = kconfig_print_symbol, | ||
479 | .print_comment = kconfig_print_comment, | ||
480 | }; | ||
481 | |||
482 | /* | ||
483 | * Header printer | ||
484 | * | ||
485 | * This printer is used when generating the `include/generated/autoconf.h' file. | ||
486 | */ | ||
487 | static void | ||
488 | header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) | ||
444 | { | 489 | { |
445 | const char *str; | ||
446 | 490 | ||
447 | switch (sym->type) { | 491 | switch (sym->type) { |
448 | case S_BOOLEAN: | 492 | case S_BOOLEAN: |
449 | case S_TRISTATE: | 493 | case S_TRISTATE: { |
450 | switch (sym_get_tristate_value(sym)) { | 494 | const char *suffix = ""; |
451 | case no: | 495 | |
452 | if (write_no) | 496 | switch (*value) { |
453 | fprintf(out, "# %s%s is not set\n", | 497 | case 'n': |
454 | CONFIG_, sym->name); | ||
455 | break; | ||
456 | case mod: | ||
457 | fprintf(out, "%s%s=m\n", CONFIG_, sym->name); | ||
458 | break; | ||
459 | case yes: | ||
460 | fprintf(out, "%s%s=y\n", CONFIG_, sym->name); | ||
461 | break; | 498 | break; |
499 | case 'm': | ||
500 | suffix = "_MODULE"; | ||
501 | /* fall through */ | ||
502 | default: | ||
503 | fprintf(fp, "#define %s%s%s 1\n", | ||
504 | CONFIG_, sym->name, suffix); | ||
462 | } | 505 | } |
506 | /* | ||
507 | * Generate the __enabled_CONFIG_* and | ||
508 | * __enabled_CONFIG_*_MODULE macros for use by the | ||
509 | * IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is | ||
510 | * generated even for booleans so that the IS_ENABLED() macro | ||
511 | * works. | ||
512 | */ | ||
513 | fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n", | ||
514 | sym->name, (*value == 'y')); | ||
515 | fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n", | ||
516 | sym->name, (*value == 'm')); | ||
463 | break; | 517 | break; |
464 | case S_STRING: | 518 | } |
465 | conf_write_string(false, sym->name, sym_get_string_value(sym), out); | 519 | case S_HEX: { |
520 | const char *prefix = ""; | ||
521 | |||
522 | if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X')) | ||
523 | prefix = "0x"; | ||
524 | fprintf(fp, "#define %s%s %s%s\n", | ||
525 | CONFIG_, sym->name, prefix, value); | ||
466 | break; | 526 | break; |
467 | case S_HEX: | 527 | } |
528 | case S_STRING: | ||
468 | case S_INT: | 529 | case S_INT: |
469 | str = sym_get_string_value(sym); | 530 | fprintf(fp, "#define %s%s %s\n", |
470 | fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str); | 531 | CONFIG_, sym->name, value); |
532 | break; | ||
533 | default: | ||
471 | break; | 534 | break; |
535 | } | ||
536 | |||
537 | } | ||
538 | |||
539 | static void | ||
540 | header_print_comment(FILE *fp, const char *value, void *arg) | ||
541 | { | ||
542 | const char *p = value; | ||
543 | size_t l; | ||
544 | |||
545 | fprintf(fp, "/*\n"); | ||
546 | for (;;) { | ||
547 | l = strcspn(p, "\n"); | ||
548 | fprintf(fp, " *"); | ||
549 | if (l) { | ||
550 | fprintf(fp, " "); | ||
551 | fwrite(p, l, 1, fp); | ||
552 | p += l; | ||
553 | } | ||
554 | fprintf(fp, "\n"); | ||
555 | if (*p++ == '\0') | ||
556 | break; | ||
557 | } | ||
558 | fprintf(fp, " */\n"); | ||
559 | } | ||
560 | |||
561 | static struct conf_printer header_printer_cb = | ||
562 | { | ||
563 | .print_symbol = header_print_symbol, | ||
564 | .print_comment = header_print_comment, | ||
565 | }; | ||
566 | |||
567 | /* | ||
568 | * Tristate printer | ||
569 | * | ||
570 | * This printer is used when generating the `include/config/tristate.conf' file. | ||
571 | */ | ||
572 | static void | ||
573 | tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) | ||
574 | { | ||
575 | |||
576 | if (sym->type == S_TRISTATE && *value != 'n') | ||
577 | fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value)); | ||
578 | } | ||
579 | |||
580 | static struct conf_printer tristate_printer_cb = | ||
581 | { | ||
582 | .print_symbol = tristate_print_symbol, | ||
583 | .print_comment = kconfig_print_comment, | ||
584 | }; | ||
585 | |||
586 | static void conf_write_symbol(FILE *fp, struct symbol *sym, | ||
587 | struct conf_printer *printer, void *printer_arg) | ||
588 | { | ||
589 | const char *str; | ||
590 | |||
591 | switch (sym->type) { | ||
472 | case S_OTHER: | 592 | case S_OTHER: |
473 | case S_UNKNOWN: | 593 | case S_UNKNOWN: |
474 | break; | 594 | break; |
595 | case S_STRING: | ||
596 | str = sym_get_string_value(sym); | ||
597 | str = sym_escape_string_value(str); | ||
598 | printer->print_symbol(fp, sym, str, printer_arg); | ||
599 | free((void *)str); | ||
600 | break; | ||
601 | default: | ||
602 | str = sym_get_string_value(sym); | ||
603 | printer->print_symbol(fp, sym, str, printer_arg); | ||
475 | } | 604 | } |
476 | } | 605 | } |
477 | 606 | ||
607 | static void | ||
608 | conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg) | ||
609 | { | ||
610 | char buf[256]; | ||
611 | |||
612 | snprintf(buf, sizeof(buf), | ||
613 | "\n" | ||
614 | "Automatically generated file; DO NOT EDIT.\n" | ||
615 | "%s\n", | ||
616 | rootmenu.prompt->text); | ||
617 | |||
618 | printer->print_comment(fp, buf, printer_arg); | ||
619 | } | ||
620 | |||
478 | /* | 621 | /* |
479 | * Write out a minimal config. | 622 | * Write out a minimal config. |
480 | * All values that has default values are skipped as this is redundant. | 623 | * All values that has default values are skipped as this is redundant. |
@@ -531,7 +674,7 @@ int conf_write_defconfig(const char *filename) | |||
531 | goto next_menu; | 674 | goto next_menu; |
532 | } | 675 | } |
533 | } | 676 | } |
534 | conf_write_symbol(sym, out, true); | 677 | conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); |
535 | } | 678 | } |
536 | next_menu: | 679 | next_menu: |
537 | if (menu->list != NULL) { | 680 | if (menu->list != NULL) { |
@@ -596,11 +739,7 @@ int conf_write(const char *name) | |||
596 | if (!out) | 739 | if (!out) |
597 | return 1; | 740 | return 1; |
598 | 741 | ||
599 | fprintf(out, _("#\n" | 742 | conf_write_heading(out, &kconfig_printer_cb, NULL); |
600 | "# Automatically generated make config: don't edit\n" | ||
601 | "# %s\n" | ||
602 | "#\n"), | ||
603 | rootmenu.prompt->text); | ||
604 | 743 | ||
605 | if (!conf_get_changed()) | 744 | if (!conf_get_changed()) |
606 | sym_clear_all_valid(); | 745 | sym_clear_all_valid(); |
@@ -621,8 +760,8 @@ int conf_write(const char *name) | |||
621 | if (!(sym->flags & SYMBOL_WRITE)) | 760 | if (!(sym->flags & SYMBOL_WRITE)) |
622 | goto next; | 761 | goto next; |
623 | sym->flags &= ~SYMBOL_WRITE; | 762 | sym->flags &= ~SYMBOL_WRITE; |
624 | /* Write config symbol to file */ | 763 | |
625 | conf_write_symbol(sym, out, true); | 764 | conf_write_symbol(out, sym, &kconfig_printer_cb, NULL); |
626 | } | 765 | } |
627 | 766 | ||
628 | next: | 767 | next: |
@@ -771,7 +910,6 @@ out: | |||
771 | int conf_write_autoconf(void) | 910 | int conf_write_autoconf(void) |
772 | { | 911 | { |
773 | struct symbol *sym; | 912 | struct symbol *sym; |
774 | const char *str; | ||
775 | const char *name; | 913 | const char *name; |
776 | FILE *out, *tristate, *out_h; | 914 | FILE *out, *tristate, *out_h; |
777 | int i; | 915 | int i; |
@@ -800,68 +938,23 @@ int conf_write_autoconf(void) | |||
800 | return 1; | 938 | return 1; |
801 | } | 939 | } |
802 | 940 | ||
803 | fprintf(out, "#\n" | 941 | conf_write_heading(out, &kconfig_printer_cb, NULL); |
804 | "# Automatically generated make config: don't edit\n" | 942 | |
805 | "# %s\n" | 943 | conf_write_heading(tristate, &tristate_printer_cb, NULL); |
806 | "#\n", | 944 | |
807 | rootmenu.prompt->text); | 945 | conf_write_heading(out_h, &header_printer_cb, NULL); |
808 | fprintf(tristate, "#\n" | ||
809 | "# Automatically generated - do not edit\n" | ||
810 | "\n"); | ||
811 | fprintf(out_h, "/*\n" | ||
812 | " * Automatically generated C config: don't edit\n" | ||
813 | " * %s\n" | ||
814 | " */\n", | ||
815 | rootmenu.prompt->text); | ||
816 | 946 | ||
817 | for_all_symbols(i, sym) { | 947 | for_all_symbols(i, sym) { |
818 | sym_calc_value(sym); | 948 | sym_calc_value(sym); |
819 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) | 949 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) |
820 | continue; | 950 | continue; |
821 | 951 | ||
822 | /* write symbol to config file */ | 952 | /* write symbol to auto.conf, tristate and header files */ |
823 | conf_write_symbol(sym, out, false); | 953 | conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); |
824 | 954 | ||
825 | /* update autoconf and tristate files */ | 955 | conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); |
826 | switch (sym->type) { | 956 | |
827 | case S_BOOLEAN: | 957 | conf_write_symbol(out_h, sym, &header_printer_cb, NULL); |
828 | case S_TRISTATE: | ||
829 | switch (sym_get_tristate_value(sym)) { | ||
830 | case no: | ||
831 | break; | ||
832 | case mod: | ||
833 | fprintf(tristate, "%s%s=M\n", | ||
834 | CONFIG_, sym->name); | ||
835 | fprintf(out_h, "#define %s%s_MODULE 1\n", | ||
836 | CONFIG_, sym->name); | ||
837 | break; | ||
838 | case yes: | ||
839 | if (sym->type == S_TRISTATE) | ||
840 | fprintf(tristate,"%s%s=Y\n", | ||
841 | CONFIG_, sym->name); | ||
842 | fprintf(out_h, "#define %s%s 1\n", | ||
843 | CONFIG_, sym->name); | ||
844 | break; | ||
845 | } | ||
846 | break; | ||
847 | case S_STRING: | ||
848 | conf_write_string(true, sym->name, sym_get_string_value(sym), out_h); | ||
849 | break; | ||
850 | case S_HEX: | ||
851 | str = sym_get_string_value(sym); | ||
852 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { | ||
853 | fprintf(out_h, "#define %s%s 0x%s\n", | ||
854 | CONFIG_, sym->name, str); | ||
855 | break; | ||
856 | } | ||
857 | case S_INT: | ||
858 | str = sym_get_string_value(sym); | ||
859 | fprintf(out_h, "#define %s%s %s\n", | ||
860 | CONFIG_, sym->name, str); | ||
861 | break; | ||
862 | default: | ||
863 | break; | ||
864 | } | ||
865 | } | 958 | } |
866 | fclose(out); | 959 | fclose(out); |
867 | fclose(tristate); | 960 | fclose(tristate); |