diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-11-15 09:58:01 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-11-15 09:58:01 +0200 |
commit | 6e4ef4c272a23ffde227689bc4e65a0523f18b4d (patch) | |
tree | 9c47e8915e0a11ff5df86ee7849cbc54eeff3882 | |
parent | 82a4e4b019194d60080c1b9f34de841485f3b9e3 (diff) | |
download | grecs-6e4ef4c272a23ffde227689bc4e65a0523f18b4d.tar.gz grecs-6e4ef4c272a23ffde227689bc4e65a0523f18b4d.tar.bz2 |
Port mailutils commit 2c2e3c50d6
* include/wordsplit.h (WRDSO_ARGV): Remove.
* src/wordsplit.c (expcmd): Always split command line into arguments.
This fixes https://savannah.gnu.org/bugs/?54830
* tests/wsp.c: Implement internal commands, instead of
calling shell ones. This fixes https://savannah.gnu.org/bugs/?54829.
* tests/wordsplit.at: Rewrite command expansion tests.
-rw-r--r-- | include/wordsplit.h | 8 | ||||
-rw-r--r-- | src/wordsplit.c | 20 | ||||
-rw-r--r-- | tests/wordsplit.at | 138 | ||||
-rw-r--r-- | tests/wsp.c | 131 |
4 files changed, 122 insertions, 175 deletions
diff --git a/include/wordsplit.h b/include/wordsplit.h index 7229df3..1a047f7 100644 --- a/include/wordsplit.h +++ b/include/wordsplit.h | |||
@@ -88,9 +88,8 @@ struct wordsplit | |||
88 | void *clos); | 88 | void *clos); |
89 | /* [Input] (!WRDSF_NOCMD) Returns in the memory | 89 | /* [Input] (!WRDSF_NOCMD) Returns in the memory |
90 | location pointed to by RET the expansion of | 90 | location pointed to by RET the expansion of |
91 | the command CMD (LEN bytes long). If WRDSO_ARGV | 91 | the command CMD (LEN bytes long). On input, |
92 | option is set, ARGV contains CMD split out to | 92 | ARGV contains CMD split out to words. |
93 | words. Otherwise ARGV is NULL. | ||
94 | 93 | ||
95 | See ws_getvar for a discussion of possible | 94 | See ws_getvar for a discussion of possible |
96 | return values. */ | 95 | return values. */ |
@@ -196,9 +195,10 @@ struct wordsplit | |||
196 | #define WRDSO_FAILGLOB 0x00000002 | 195 | #define WRDSO_FAILGLOB 0x00000002 |
197 | /* Allow a leading period to be matched by metacharacters. */ | 196 | /* Allow a leading period to be matched by metacharacters. */ |
198 | #define WRDSO_DOTGLOB 0x00000004 | 197 | #define WRDSO_DOTGLOB 0x00000004 |
199 | /* ws_command needs argv parameter */ | 198 | #if 0 /* Unused value */ |
200 | #define WRDSO_ARGV 0x00000008 | 199 | #define WRDSO_ARGV 0x00000008 |
201 | /* Keep backslash in unrecognized escape sequences in words */ | 200 | /* Keep backslash in unrecognized escape sequences in words */ |
201 | #endif | ||
202 | #define WRDSO_BSKEEP_WORD 0x00000010 | 202 | #define WRDSO_BSKEEP_WORD 0x00000010 |
203 | /* Handle octal escapes in words */ | 203 | /* Handle octal escapes in words */ |
204 | #define WRDSO_OESC_WORD 0x00000020 | 204 | #define WRDSO_OESC_WORD 0x00000020 |
diff --git a/src/wordsplit.c b/src/wordsplit.c index b4baeb3..bad59b1 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c | |||
@@ -1527,6 +1527,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, | |||
1527 | size_t j; | 1527 | size_t j; |
1528 | char *value; | 1528 | char *value; |
1529 | struct wordsplit_node *newnode; | 1529 | struct wordsplit_node *newnode; |
1530 | struct wordsplit ws; | ||
1530 | 1531 | ||
1531 | str++; | 1532 | str++; |
1532 | len--; | 1533 | len--; |
@@ -1538,22 +1539,15 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, | |||
1538 | } | 1539 | } |
1539 | 1540 | ||
1540 | *pend = str + j; | 1541 | *pend = str + j; |
1541 | if (wsp->ws_options & WRDSO_ARGV) | 1542 | rc = _wsplt_subsplit (wsp, &ws, str, j, WRDSF_WS | WRDSF_QUOTE, 1); |
1543 | if (rc) | ||
1542 | { | 1544 | { |
1543 | struct wordsplit ws; | 1545 | _wsplt_seterr_sub (wsp, &ws); |
1544 | |||
1545 | rc = _wsplt_subsplit (wsp, &ws, str, j, WRDSF_WS | WRDSF_QUOTE, 1); | ||
1546 | if (rc) | ||
1547 | { | ||
1548 | _wsplt_seterr_sub (wsp, &ws); | ||
1549 | wordsplit_free (&ws); | ||
1550 | return 1; | ||
1551 | } | ||
1552 | rc = wsp->ws_command (&value, str, j, ws.ws_wordv, wsp->ws_closure); | ||
1553 | wordsplit_free (&ws); | 1546 | wordsplit_free (&ws); |
1547 | return 1; | ||
1554 | } | 1548 | } |
1555 | else | 1549 | rc = wsp->ws_command (&value, str, j, ws.ws_wordv, wsp->ws_closure); |
1556 | rc = wsp->ws_command (&value, str, j, NULL, wsp->ws_closure); | 1550 | wordsplit_free (&ws); |
1557 | 1551 | ||
1558 | if (rc == WRDSE_NOSPACE) | 1552 | if (rc == WRDSE_NOSPACE) |
1559 | return _wsplt_nomem (wsp); | 1553 | return _wsplt_nomem (wsp); |
diff --git a/tests/wordsplit.at b/tests/wordsplit.at index 75dde85..631d939 100644 --- a/tests/wordsplit.at +++ b/tests/wordsplit.at | |||
@@ -711,142 +711,70 @@ TOTAL: 1 | |||
711 | ], | 711 | ], |
712 | [input exhausted | 712 | [input exhausted |
713 | ]) | 713 | ]) |
714 | 714 | ||
715 | dnl Something that doesn't fit into TESTWSP | 715 | TESTWSP([simple command substitution],[],[-nocmd], |
716 | 716 | [begin $(words a b) end], | |
717 | AT_SETUP([simple command substitution]) | ||
718 | AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-1]) | ||
719 | AT_CHECK([ | ||
720 | mkdir dir | ||
721 | > dir/file | ||
722 | |||
723 | wsp -nocmd <<'EOT' | ||
724 | begin $(find dir) end | ||
725 | EOT | ||
726 | ], | ||
727 | [0], | ||
728 | [NF: 4 | 717 | [NF: 4 |
729 | 0: begin | 718 | 0: begin |
730 | 1: dir | 719 | 1: a |
731 | 2: dir/file | 720 | 2: b |
732 | 3: end | 721 | 3: end |
733 | TOTAL: 4 | 722 | TOTAL: 4 |
734 | ]) | 723 | ]) |
735 | AT_CLEANUP | ||
736 | 724 | ||
737 | AT_SETUP([quoted command substitution]) | 725 | TESTWSP([quoted command substitution],[],[-nocmd], |
738 | AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-2]) | 726 | [begin "$(words a b)" end], |
739 | AT_CHECK([ | ||
740 | mkdir dir | ||
741 | > dir/file | ||
742 | |||
743 | wsp -nocmd <<'EOT' | ||
744 | begin "$(find dir)" end | ||
745 | EOT | ||
746 | ], | ||
747 | [0], | ||
748 | [NF: 3 | 727 | [NF: 3 |
749 | 0: begin | 728 | 0: begin |
750 | 1: "dir dir/file" | 729 | 1: "a b" |
751 | 2: end | 730 | 2: end |
752 | TOTAL: 3 | 731 | TOTAL: 3 |
753 | ]) | 732 | ]) |
754 | AT_CLEANUP | ||
755 | |||
756 | AT_SETUP([coalesced command substitution]) | ||
757 | AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-3]) | ||
758 | AT_CHECK([ | ||
759 | mkdir dir | ||
760 | > dir/file | ||
761 | 733 | ||
762 | wsp -nocmd <<'EOT' | 734 | TESTWSP([coalesced command substitution],[],[-nocmd], |
763 | begin($(find dir))end | 735 | [begin($(words a b))end], |
764 | EOT | ||
765 | ], | ||
766 | [0], | ||
767 | [NF: 2 | 736 | [NF: 2 |
768 | 0: begin(dir | 737 | 0: begin(a |
769 | 1: dir/file)end | 738 | 1: b)end |
770 | TOTAL: 2 | 739 | TOTAL: 2 |
771 | ]) | 740 | ]) |
772 | AT_CLEANUP | ||
773 | 741 | ||
774 | AT_SETUP([quoted coalesced command substitution]) | 742 | TESTWSP([quoted coalesced command substitution],[],[-nocmd], |
775 | AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-4]) | 743 | ["begin($(words a b))end"], |
776 | AT_CHECK([ | ||
777 | mkdir dir | ||
778 | > dir/file | ||
779 | |||
780 | wsp -nocmd <<'EOT' | ||
781 | "begin($(find dir))end" | ||
782 | EOT | ||
783 | ], | ||
784 | [0], | ||
785 | [NF: 1 | 744 | [NF: 1 |
786 | 0: "begin(dir dir/file)end" | 745 | 0: "begin(a b)end" |
787 | TOTAL: 1 | 746 | TOTAL: 1 |
788 | ]) | 747 | ]) |
789 | AT_CLEANUP | ||
790 | |||
791 | AT_SETUP([variable and command substitution]) | ||
792 | AT_KEYWORDS([wordsplit wsp wsp-var wsp-var24 wsp-cmd wsp-cmd-5]) | ||
793 | AT_CHECK([ | ||
794 | mkdir dir | ||
795 | > dir/file | ||
796 | 748 | ||
797 | DIR=dir wsp -nocmd -novar<<'EOT' | 749 | TESTWSP([variable and command substitution],[],[-nocmd -novar], |
798 | begin $DIR $(find $DIR) end | 750 | [begin $X $(words $X $Y) end], |
799 | EOT | ||
800 | ], | ||
801 | [0], | ||
802 | [NF: 5 | 751 | [NF: 5 |
803 | 0: begin | 752 | 0: begin |
804 | 1: dir | 753 | 1: a |
805 | 2: dir | 754 | 2: a |
806 | 3: dir/file | 755 | 3: b |
807 | 4: end | 756 | 4: end |
808 | TOTAL: 5 | 757 | TOTAL: 5 |
809 | ]) | 758 | ],[],[X=a Y=b]) |
810 | AT_CLEANUP | ||
811 | 759 | ||
812 | AT_SETUP([variable expansion and command substitution in quotes]) | 760 | TESTWSP([variable expansion and command substitution in quotes],[],[-nocmd -novar], |
813 | AT_KEYWORDS([wordsplit wsp wsp-var wsp-var25 wsp-cmd wsp-cmd-6]) | 761 | ["${BEGIN}($(words $X $Y))end"], |
814 | AT_CHECK([ | ||
815 | mkdir dir | ||
816 | > dir/file | ||
817 | |||
818 | DIR=dir BEGIN=begin wsp -nocmd -novar<<'EOT' | ||
819 | "${BEGIN}($(find $DIR))end" | ||
820 | EOT | ||
821 | ], | ||
822 | [0], | ||
823 | [NF: 1 | 762 | [NF: 1 |
824 | 0: "begin(dir dir/file)end" | 763 | 0: "begin(a b)end" |
825 | TOTAL: 1 | 764 | TOTAL: 1 |
826 | ]) | 765 | ],[],[X=a Y=b BEGIN=begin]) |
827 | AT_CLEANUP | 766 | |
828 | 767 | TESTWSP([nested commands],[],[-nocmd -novar], | |
829 | AT_SETUP([nested commands]) | 768 | [$(words output $(words in$SUFFIX text) end)], |
830 | AT_KEYWORDS([wordsplit wsp wsp-cmd]) | ||
831 | AT_CHECK([ | ||
832 | AT_DATA([input],[foo | ||
833 | bar | ||
834 | baz | ||
835 | ]) | ||
836 | SUFFIX=put wsp -nocmd -novar <<'EOT' | ||
837 | $(echo output $(cat in$SUFFIX)) |