Commit e54e692ba613c2170c66ce36a3791c009680af08

Authored by Arnaud Lacombe
Committed by Michal Marek
1 parent ec6452a5ec

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>

Showing 4 changed files with 266 additions and 128 deletions Side-by-side Diff

scripts/kconfig/confdata.c
... ... @@ -422,64 +422,228 @@
422 422 return 0;
423 423 }
424 424  
425   -/* Write a S_STRING */
426   -static void conf_write_string(bool headerfile, const char *name,
427   - const char *str, FILE *out)
  425 +/*
  426 + * Kconfig configuration printer
  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)
428 435 {
429   - int l;
430   - if (headerfile)
431   - fprintf(out, "#define %s%s \"", CONFIG_, name);
432   - else
433   - fprintf(out, "%s%s=\"", CONFIG_, name);
434 436  
435   - while (1) {
436   - l = strcspn(str, "\"\\");
  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 +
  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, "#");
437 465 if (l) {
438   - xfwrite(str, l, 1, out);
439   - str += l;
  466 + fprintf(fp, " ");
  467 + fwrite(p, l, 1, fp);
  468 + p += l;
440 469 }
441   - if (!*str)
  470 + fprintf(fp, "\n");
  471 + if (*p++ == '\0')
442 472 break;
443   - fprintf(out, "\\%c", *str++);
444 473 }
445   - fputs("\"\n", out);
446 474 }
447 475  
448   -static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
  476 +static 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 +};
451 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)
  489 +{
  490 + const char *suffix = "";
  491 +
452 492 switch (sym->type) {
453 493 case S_BOOLEAN:
454 494 case S_TRISTATE:
455   - switch (sym_get_tristate_value(sym)) {
456   - case no:
457   - if (write_no)
458   - fprintf(out, "# %s%s is not set\n",
459   - CONFIG_, sym->name);
460   - break;
461   - case mod:
462   - fprintf(out, "%s%s=m\n", CONFIG_, sym->name);
463   - break;
464   - case yes:
465   - fprintf(out, "%s%s=y\n", CONFIG_, sym->name);
466   - break;
  495 + switch (*value) {
  496 + case 'n':
  497 + return;
  498 + case 'm':
  499 + suffix = "_MODULE";
  500 + /* FALLTHROUGH */
  501 + default:
  502 + value = "1";
467 503 }
468 504 break;
469   - case S_STRING:
470   - conf_write_string(false, sym->name, sym_get_string_value(sym), out);
  505 + default:
471 506 break;
472   - case S_HEX:
473   - case S_INT:
474   - str = sym_get_string_value(sym);
475   - fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str);
  507 + }
  508 +
  509 + fprintf(fp, "#define %s%s%s %s\n",
  510 + CONFIG_, sym->name, suffix, value);
  511 +}
  512 +
  513 +static void
  514 +header_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 +
  535 +static 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 + */
  547 +static void
  548 +header_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 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 +
  587 +static 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 + */
  598 +static void
  599 +tristate_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 +
  606 +static struct conf_printer tristate_printer_cb =
  607 +{
  608 + .print_symbol = tristate_print_symbol,
  609 + .print_comment = kconfig_print_comment,
  610 +};
  611 +
  612 +static 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 618 case S_OTHER:
478 619 case S_UNKNOWN:
479 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  
  633 +static void
  634 +conf_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 648 * Write out a minimal config.
485 649 * All values that has default values are skipped as this is redundant.
... ... @@ -536,7 +700,7 @@
536 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 }
541 705 next_menu:
542 706 if (menu->list != NULL) {
... ... @@ -601,11 +765,7 @@
601 765 if (!out)
602 766 return 1;
603 767  
604   - fprintf(out, _("#\n"
605   - "# Automatically generated make config: don't edit\n"
606   - "# %s\n"
607   - "#\n"),
608   - rootmenu.prompt->text);
  768 + conf_write_heading(out, &kconfig_printer_cb, NULL);
609 769  
610 770 if (!conf_get_changed())
611 771 sym_clear_all_valid();
... ... @@ -626,8 +786,8 @@
626 786 if (!(sym->flags & SYMBOL_WRITE))
627 787 goto next;
628 788 sym->flags &= ~SYMBOL_WRITE;
629   - /* Write config symbol to file */
630   - conf_write_symbol(sym, out, true);
  789 +
  790 + conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
631 791 }
632 792  
633 793 next:
634 794  
... ... @@ -773,33 +933,9 @@
773 933 return res;
774 934 }
775 935  
776   -static 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   -
799 936 int conf_write_autoconf(void)
800 937 {
801 938 struct symbol *sym;
802   - const char *str;
803 939 const char *name;
804 940 FILE *out, *tristate, *out_h;
805 941 int i;
806 942  
807 943  
808 944  
809 945  
... ... @@ -828,72 +964,24 @@
828 964 return 1;
829 965 }
830 966  
831   - fprintf(out, "#\n"
832   - "# Automatically generated make config: don't edit\n"
833   - "# %s\n"
834   - "#\n",
835   - rootmenu.prompt->text);
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);
  967 + conf_write_heading(out, &kconfig_printer_cb, NULL);
844 968  
  969 + conf_write_heading(tristate, &tristate_printer_cb, NULL);
  970 +
  971 + conf_write_heading(out_h, &header_printer_cb, NULL);
  972 +
845 973 for_all_symbols(i, sym) {
846   - int fct_val = 0;
847 974 sym_calc_value(sym);
848 975 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
849 976 continue;
850 977  
851   - /* write symbol to config file */
852   - conf_write_symbol(sym, out, false);
  978 + /* write symbol to auto.conf, tristate and header files */
  979 + conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
853 980  
854   - /* update autoconf and tristate files */
855   - switch (sym->type) {
856   - case S_BOOLEAN:
857   - case S_TRISTATE:
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   - }
  981 + conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
  982 +
  983 + conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
  984 + conf_write_symbol(out_h, sym, &header_function_printer_cb, NULL);
897 985 }
898 986 fclose(out);
899 987 fclose(tristate);
scripts/kconfig/lkc.h
... ... @@ -87,6 +87,11 @@
87 87 void sym_add_change_count(int count);
88 88 void conf_set_all_new_symbols(enum conf_def_mode mode);
89 89  
  90 +struct conf_printer {
  91 + void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
  92 + void (*print_comment)(FILE *, const char *, void *);
  93 +};
  94 +
90 95 /* confdata.c and expr.c */
91 96 static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
92 97 {
scripts/kconfig/lkc_proto.h
... ... @@ -31,6 +31,7 @@
31 31 P(sym_lookup,struct symbol *,(const char *name, int flags));
32 32 P(sym_find,struct symbol *,(const char *name));
33 33 P(sym_expand_string_value,const char *,(const char *in));
  34 +P(sym_escape_string_value, const char *,(const char *in));
34 35 P(sym_re_search,struct symbol **,(const char *pattern));
35 36 P(sym_type_name,const char *,(enum symbol_type type));
36 37 P(sym_calc_value,void,(struct symbol *sym));
scripts/kconfig/symbol.c
... ... @@ -750,7 +750,8 @@
750 750 case no:
751 751 return "n";
752 752 case mod:
753   - return "m";
  753 + sym_calc_value(modules_sym);
  754 + return (modules_sym->curr.tri == no) ? "n" : "m";
754 755 case yes:
755 756 return "y";
756 757 }
... ... @@ -889,6 +890,49 @@
889 890 }
890 891 strcat(res, in);
891 892  
  893 + return res;
  894 +}
  895 +
  896 +const 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, "\"");
892 936 return res;
893 937 }
894 938