aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaud Lacombe <lacombar@gmail.com>2011-05-15 23:42:09 -0400
committerMichal Marek <mmarek@suse.cz>2011-07-01 10:23:27 -0400
commite54e692ba613c2170c66ce36a3791c009680af08 (patch)
tree481c7b253cc97a38f2b267ff2f7cf068a50304d4
parentec6452a5ec68498221a0ced3443cefd65b08be36 (diff)
kconfig: introduce specialized printer
Make conf_write_symbol() grammar agnostic to be able to use it from different code path. These path pass a printer callback which will print a symbol's name and its value in different format. conf_write_symbol()'s job become mostly only to prepare a string for the printer. This avoid to have to pass specialized flag to generic functions Signed-off-by: Arnaud Lacombe <lacombar@gmail.com> [mmarek: rebased on top of de12518 (kconfig: autogenerated config_is_xxx macro)] Signed-off-by: Michal Marek <mmarek@suse.cz>
-rw-r--r--scripts/kconfig/confdata.c342
-rw-r--r--scripts/kconfig/lkc.h5
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rw-r--r--scripts/kconfig/symbol.c46
4 files changed, 266 insertions, 128 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index a49cf4f7dca5..be6952c7fb29 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -422,64 +422,228 @@ int conf_read(const char *name)
422 return 0; 422 return 0;
423} 423}
424 424
425/* Write a S_STRING */ 425/*
426static void conf_write_string(bool headerfile, const char *name, 426 * Kconfig configuration printer
427 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 */
433static void
434kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
435{
436
437 switch (sym->type) {
438 case S_BOOLEAN:
439 case S_TRISTATE:
440 if (*value == 'n') {
441 bool skip_unset = (arg != NULL);
442
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
456static void
457kconfig_print_comment(FILE *fp, const char *value, void *arg)
428{ 458{
429 int l; 459 const char *p = value;
430 if (headerfile) 460 size_t l;
431 fprintf(out, "#define %s%s \"", CONFIG_, name); 461
432 else 462 for (;;) {
433 fprintf(out, "%s%s=\"", CONFIG_, name); 463 l = strcspn(p, "\n");
434 464 fprintf(fp, "#");
435 while (1) {
436 l = strcspn(str, "\"\\");
437 if (l) { 465 if (l) {
438 xfwrite(str, l, 1, out); 466 fprintf(fp, " ");
439 str += l; 467 fwrite(p, l, 1, fp);
468 p += l;
440 } 469 }
441 if (!*str) 470 fprintf(fp, "\n");
471 if (*p++ == '\0')
442 break; 472 break;
443 fprintf(out, "\\%c", *str++);
444 } 473 }
445 fputs("\"\n", out);
446} 474}
447 475
448static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no) 476static struct conf_printer kconfig_printer_cb =
449{ 477{
450 const char *str; 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 */
487static void
488header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
489{
490 const char *suffix = "";
451 491
452 switch (sym->type) { 492 switch (sym->type) {
453 case S_BOOLEAN: 493 case S_BOOLEAN:
454 case S_TRISTATE: 494 case S_TRISTATE:
455 switch (sym_get_tristate_value(sym)) { 495 switch (*value) {
456 case no: 496 case 'n':
457 if (write_no) 497 return;
458 fprintf(out, "# %s%s is not set\n", 498 case 'm':
459 CONFIG_, sym->name); 499 suffix = "_MODULE";
460 break; 500 /* FALLTHROUGH */
461 case mod: 501 default:
462 fprintf(out, "%s%s=m\n", CONFIG_, sym->name); 502 value = "1";
463 break;
464 case yes:
465 fprintf(out, "%s%s=y\n", CONFIG_, sym->name);
466 break;
467 } 503 }
468 break; 504 break;
469 case S_STRING: 505 default:
470 conf_write_string(false, sym->name, sym_get_string_value(sym), out);
471 break; 506 break;
472 case S_HEX: 507 }
473 case S_INT: 508
474 str = sym_get_string_value(sym); 509 fprintf(fp, "#define %s%s%s %s\n",
475 fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str); 510 CONFIG_, sym->name, suffix, value);
511}
512
513static void
514header_print_comment(FILE *fp, const char *value, void *arg)
515{
516 const char *p = value;
517 size_t l;
518
519 fprintf(fp, "/*\n");
520 for (;;) {
521 l = strcspn(p, "\n");
522 fprintf(fp, " *");
523 if (l) {
524 fprintf(fp, " ");
525 fwrite(p, l, 1, fp);
526 p += l;
527 }
528 fprintf(fp, "\n");
529 if (*p++ == '\0')
530 break;
531 }
532 fprintf(fp, " */\n");
533}
534
535static struct conf_printer header_printer_cb =
536{
537 .print_symbol = header_print_symbol,
538 .print_comment = header_print_comment,
539};
540
541/*
542 * Function-style header printer
543 *
544 * This printer is used to generate the config_is_xxx() function-style macros
545 * in `include/generated/autoconf.h'
546 */
547static void
548header_function_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
549{
550 int val = 0;
551 char c;
552 char *tmp, *d;
553
554 switch (sym->type) {
555 case S_BOOLEAN:
556 case S_TRISTATE:
476 break; 557 break;
558 default:
559 return;
560 }
561 if (*value == 'm')
562 val = 2;
563 else if (*value == 'y')
564 val = 1;
565
566 d = strdup(CONFIG_);
567 tmp = d;
568 while ((c = *d)) {
569 *d = tolower(c);
570 d++;
571 }
572
573 fprintf(fp, "#define %sis_", tmp);
574 free(tmp);
575
576 d = strdup(sym->name);
577 tmp = d;
578 while ((c = *d)) {
579 *d = tolower(c);
580 d++;
581 }
582 fprintf(fp, "%s%s() %d\n", tmp, (val > 1) ? "_module" : "",
583 val ? 1 : 0);
584 free(tmp);
585}
586
587static struct conf_printer header_function_printer_cb =
588{
589 .print_symbol = header_function_print_symbol,
590};
591
592
593/*
594 * Tristate printer
595 *
596 * This printer is used when generating the `include/config/tristate.conf' file.
597 */
598static void
599tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
600{
601
602 if (sym->type == S_TRISTATE && *value != 'n')
603 fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value));
604}
605
606static struct conf_printer tristate_printer_cb =
607{
608 .print_symbol = tristate_print_symbol,
609 .print_comment = kconfig_print_comment,
610};
611
612static void conf_write_symbol(FILE *fp, struct symbol *sym,
613 struct conf_printer *printer, void *printer_arg)
614{
615 const char *str;
616
617 switch (sym->type) {
477 case S_OTHER: 618 case S_OTHER:
478 case S_UNKNOWN: 619 case S_UNKNOWN:
479 break; 620 break;
621 case S_STRING:
622 str = sym_get_string_value(sym);
623 str = sym_escape_string_value(str);
624 printer->print_symbol(fp, sym, str, printer_arg);
625 free((void *)str);
626 break;
627 default:
628 str = sym_get_string_value(sym);
629 printer->print_symbol(fp, sym, str, printer_arg);
480 } 630 }
481} 631}
482 632
633static void
634conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg)
635{
636 char buf[256];
637
638 snprintf(buf, sizeof(buf),
639 "\n"
640 "Automatically generated file; DO NOT EDIT.\n"
641 "%s\n",
642 rootmenu.prompt->text);
643
644 printer->print_comment(fp, buf, printer_arg);
645}
646
483/* 647/*
484 * Write out a minimal config. 648 * Write out a minimal config.
485 * All values that has default values are skipped as this is redundant. 649 * All values that has default values are skipped as this is redundant.
@@ -536,7 +700,7 @@ int conf_write_defconfig(const char *filename)
536 goto next_menu; 700 goto next_menu;
537 } 701 }
538 } 702 }
539 conf_write_symbol(sym, out, true); 703 conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
540 } 704 }
541next_menu: 705next_menu:
542 if (menu->list != NULL) { 706 if (menu->list != NULL) {
@@ -601,11 +765,7 @@ int conf_write(const char *name)
601 if (!out) 765 if (!out)
602 return 1; 766 return 1;
603 767
604 fprintf(out, _("#\n" 768 conf_write_heading(out, &kconfig_printer_cb, NULL);
605 "# Automatically generated make config: don't edit\n"
606 "# %s\n"
607 "#\n"),
608 rootmenu.prompt->text);
609 769
610 if (!conf_get_changed()) 770 if (!conf_get_changed())
611 sym_clear_all_valid(); 771 sym_clear_all_valid();
@@ -626,8 +786,8 @@ int conf_write(const char *name)
626 if (!(sym->flags & SYMBOL_WRITE)) 786 if (!(sym->flags & SYMBOL_WRITE))
627 goto next; 787 goto next;
628 sym->flags &= ~SYMBOL_WRITE; 788 sym->flags &= ~SYMBOL_WRITE;
629 /* Write config symbol to file */ 789
630 conf_write_symbol(sym, out, true); 790 conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
631 } 791 }
632 792
633next: 793next:
@@ -773,33 +933,9 @@ out:
773 return res; 933 return res;
774} 934}
775 935
776static void conf_write_function_autoconf(FILE *out, char* conf, char* name,
777 int val)
778{
779 char c;
780 char *tmp, *d;
781
782 d = strdup(conf);
783 tmp = d;
784 while ((c = *conf++))
785 *d++ = tolower(c);
786
787 fprintf(out, "#define %sis_", tmp);
788 free(tmp);
789
790 d = strdup(name);
791 tmp = d;
792 while ((c = *name++))
793 *d++ = tolower(c);
794 fprintf(out, "%s%s() %d\n", tmp, (val > 1) ? "_module" : "",
795 val ? 1 : 0);
796 free(tmp);
797}
798
799int conf_write_autoconf(void) 936int conf_write_autoconf(void)
800{ 937{
801 struct symbol *sym; 938 struct symbol *sym;
802 const char *str;
803 const char *name; 939 const char *name;
804 FILE *out, *tristate, *out_h; 940 FILE *out, *tristate, *out_h;
805 int i; 941 int i;
@@ -828,72 +964,24 @@ int conf_write_autoconf(void)
828 return 1; 964 return 1;
829 } 965 }
830 966
831 fprintf(out, "#\n" 967 conf_write_heading(out, &kconfig_printer_cb, NULL);
832 "# Automatically generated make config: don't edit\n" 968
833 "# %s\n" 969 conf_write_heading(tristate, &tristate_printer_cb, NULL);
834 "#\n", 970
835 rootmenu.prompt->text); 971 conf_write_heading(out_h, &header_printer_cb, NULL);
836 fprintf(tristate, "#\n"
837 "# Automatically generated - do not edit\n"
838 "\n");
839 fprintf(out_h, "/*\n"
840 " * Automatically generated C config: don't edit\n"
841 " * %s\n"
842 " */\n",
843 rootmenu.prompt->text);
844 972
845 for_all_symbols(i, sym) { 973 for_all_symbols(i, sym) {
846 int fct_val = 0;
847 sym_calc_value(sym); 974 sym_calc_value(sym);
848 if (!(sym->flags & SYMBOL_WRITE) || !sym->name) 975 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
849 continue; 976 continue;
850 977
851 /* write symbol to config file */ 978 /* write symbol to auto.conf, tristate and header files */
852 conf_write_symbol(sym, out, false); 979 conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
853 980
854 /* update autoconf and tristate files */ 981 conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
855 switch (sym->type) { 982
856 case S_BOOLEAN: 983 conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
857 case S_TRISTATE: 984 conf_write_symbol(out_h, sym, &header_function_printer_cb, NULL);
858 switch (sym_get_tristate_value(sym)) {
859 case no:
860 break;
861 case mod:
862 fprintf(tristate, "%s%s=M\n",
863 CONFIG_, sym->name);
864 fprintf(out_h, "#define %s%s_MODULE 1\n",
865 CONFIG_, sym->name);
866 fct_val = 2;
867 break;
868 case yes:
869 if (sym->type == S_TRISTATE)
870 fprintf(tristate,"%s%s=Y\n",
871 CONFIG_, sym->name);
872 fprintf(out_h, "#define %s%s 1\n",
873 CONFIG_, sym->name);
874 fct_val = 1;
875 break;
876 }
877 conf_write_function_autoconf(out_h, CONFIG_, sym->name, fct_val);
878 break;
879 case S_STRING:
880 conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
881 break;
882 case S_HEX:
883 str = sym_get_string_value(sym);
884 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
885 fprintf(out_h, "#define %s%s 0x%s\n",
886 CONFIG_, sym->name, str);
887 break;
888 }
889 case S_INT:
890 str = sym_get_string_value(sym);
891 fprintf(out_h, "#define %s%s %s\n",
892 CONFIG_, sym->name, str);
893 break;
894 default:
895 break;
896 }
897 } 985 }
898 fclose(out); 986 fclose(out);
899 fclose(tristate); 987 fclose(tristate);
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 625ec69ebeee..306c5a59efc2 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -87,6 +87,11 @@ void sym_set_change_count(int count);
87void sym_add_change_count(int count); 87void sym_add_change_count(int count);
88void conf_set_all_new_symbols(enum conf_def_mode mode); 88void conf_set_all_new_symbols(enum conf_def_mode mode);
89 89
90struct conf_printer {
91 void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
92 void (*print_comment)(FILE *, const char *, void *);
93};
94
90/* confdata.c and expr.c */ 95/* confdata.c and expr.c */
91static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) 96static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
92{ 97{
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 17342fef38b9..47fe9c340f9a 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -31,6 +31,7 @@ P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
31P(sym_lookup,struct symbol *,(const char *name, int flags)); 31P(sym_lookup,struct symbol *,(const char *name, int flags));
32P(sym_find,struct symbol *,(const char *name)); 32P(sym_find,struct symbol *,(const char *name));
33P(sym_expand_string_value,const char *,(const char *in)); 33P(sym_expand_string_value,const char *,(const char *in));
34P(sym_escape_string_value, const char *,(const char *in));
34P(sym_re_search,struct symbol **,(const char *pattern)); 35P(sym_re_search,struct symbol **,(const char *pattern));
35P(sym_type_name,const char *,(enum symbol_type type)); 36P(sym_type_name,const char *,(enum symbol_type type));
36P(sym_calc_value,void,(struct symbol *sym)); 37P(sym_calc_value,void,(struct symbol *sym));
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index cf8edf4fc429..071f00c3046e 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -750,7 +750,8 @@ const char *sym_get_string_value(struct symbol *sym)
750 case no: 750 case no:
751 return "n"; 751 return "n";
752 case mod: 752 case mod:
753 return "m"; 753 sym_calc_value(modules_sym);
754 return (modules_sym->curr.tri == no) ? "n" : "m";
754 case yes: 755 case yes:
755 return "y"; 756 return "y";
756 } 757 }
@@ -892,6 +893,49 @@ const char *sym_expand_string_value(const char *in)
892 return res; 893 return res;
893} 894}
894 895
896const char *sym_escape_string_value(const char *in)
897{
898 const char *p;
899 size_t reslen;
900 char *res;
901 size_t l;
902
903 reslen = strlen(in) + strlen("\"\"") + 1;
904
905 p = in;
906 for (;;) {
907 l = strcspn(p, "\"\\");
908 p += l;
909
910 if (p[0] == '\0')
911 break;
912
913 reslen++;
914 p++;
915 }
916
917 res = malloc(reslen);
918 res[0] = '\0';
919
920 strcat(res, "\"");
921
922 p = in;
923 for (;;) {
924 l = strcspn(p, "\"\\");
925 strncat(res, p, l);
926 p += l;
927
928 if (p[0] == '\0')
929 break;
930
931 strcat(res, "\\");
932 strncat(res, p++, 1);
933 }
934
935 strcat(res, "\"");
936 return res;
937}
938
895struct symbol **sym_re_search(const char *pattern) 939struct symbol **sym_re_search(const char *pattern)
896{ 940{
897 struct symbol *sym, **sym_arr = NULL; 941 struct symbol *sym, **sym_arr = NULL;