diff options
| author | Arnaud Lacombe <lacombar@gmail.com> | 2011-05-15 23:42:09 -0400 |
|---|---|---|
| committer | Michal Marek <mmarek@suse.cz> | 2011-07-01 10:23:27 -0400 |
| commit | e54e692ba613c2170c66ce36a3791c009680af08 (patch) | |
| tree | 481c7b253cc97a38f2b267ff2f7cf068a50304d4 /scripts | |
| parent | ec6452a5ec68498221a0ced3443cefd65b08be36 (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>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/kconfig/confdata.c | 342 | ||||
| -rw-r--r-- | scripts/kconfig/lkc.h | 5 | ||||
| -rw-r--r-- | scripts/kconfig/lkc_proto.h | 1 | ||||
| -rw-r--r-- | scripts/kconfig/symbol.c | 46 |
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 | /* |
| 426 | static 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 | */ | ||
| 433 | static void | ||
| 434 | kconfig_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 | |||
| 456 | static void | ||
| 457 | kconfig_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 | ||
| 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 | }; | ||
| 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 = ""; | ||
| 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 | |||
| 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 | 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 | |||
| 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 | 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 | ||
| 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 | * 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 | } |
| 541 | next_menu: | 705 | next_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 | ||
| 633 | next: | 793 | next: |
| @@ -773,33 +933,9 @@ out: | |||
| 773 | return res; | 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 | int conf_write_autoconf(void) | 936 | int 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); | |||
| 87 | void sym_add_change_count(int count); | 87 | void sym_add_change_count(int count); |
| 88 | void conf_set_all_new_symbols(enum conf_def_mode mode); | 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 | /* confdata.c and expr.c */ | 95 | /* confdata.c and expr.c */ |
| 91 | static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) | 96 | static 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]); | |||
| 31 | P(sym_lookup,struct symbol *,(const char *name, int flags)); | 31 | P(sym_lookup,struct symbol *,(const char *name, int flags)); |
| 32 | P(sym_find,struct symbol *,(const char *name)); | 32 | P(sym_find,struct symbol *,(const char *name)); |
| 33 | P(sym_expand_string_value,const char *,(const char *in)); | 33 | P(sym_expand_string_value,const char *,(const char *in)); |
| 34 | P(sym_escape_string_value, const char *,(const char *in)); | ||
| 34 | P(sym_re_search,struct symbol **,(const char *pattern)); | 35 | P(sym_re_search,struct symbol **,(const char *pattern)); |
| 35 | P(sym_type_name,const char *,(enum symbol_type type)); | 36 | P(sym_type_name,const char *,(enum symbol_type type)); |
| 36 | P(sym_calc_value,void,(struct symbol *sym)); | 37 | P(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 | ||
| 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, "\""); | ||
| 936 | return res; | ||
| 937 | } | ||
| 938 | |||
| 895 | struct symbol **sym_re_search(const char *pattern) | 939 | struct symbol **sym_re_search(const char *pattern) |
| 896 | { | 940 | { |
| 897 | struct symbol *sym, **sym_arr = NULL; | 941 | struct symbol *sym, **sym_arr = NULL; |
