aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-11-15 09:58:01 +0200
committerSergey Poznyakoff <gray@gnu.org>2018-11-15 09:58:01 +0200
commit6e4ef4c272a23ffde227689bc4e65a0523f18b4d (patch)
tree9c47e8915e0a11ff5df86ee7849cbc54eeff3882
parent82a4e4b019194d60080c1b9f34de841485f3b9e3 (diff)
downloadgrecs-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.h8
-rw-r--r--src/wordsplit.c20
-rw-r--r--tests/wordsplit.at138
-rw-r--r--tests/wsp.c131
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
715dnl Something that doesn't fit into TESTWSP 715TESTWSP([simple command substitution],[],[-nocmd],
716 716[begin $(words a b) end],
717AT_SETUP([simple command substitution])
718AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-1])
719AT_CHECK([
720mkdir dir
721> dir/file
722
723wsp -nocmd <<'EOT'
724begin $(find dir) end
725EOT
726],
727[0],
728[NF: 4 717[NF: 4
7290: begin 7180: begin
7301: dir 7191: a
7312: dir/file 7202: b
7323: end 7213: end
733TOTAL: 4 722TOTAL: 4
734]) 723])
735AT_CLEANUP
736 724
737AT_SETUP([quoted command substitution]) 725TESTWSP([quoted command substitution],[],[-nocmd],
738AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-2]) 726[begin "$(words a b)" end],
739AT_CHECK([
740mkdir dir
741> dir/file
742
743wsp -nocmd <<'EOT'
744begin "$(find dir)" end
745EOT
746],
747[0],
748[NF: 3 727[NF: 3
7490: begin 7280: begin
7501: "dir dir/file" 7291: "a b"
7512: end 7302: end
752TOTAL: 3 731TOTAL: 3
753]) 732])
754AT_CLEANUP
755
756AT_SETUP([coalesced command substitution])
757AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-3])
758AT_CHECK([
759mkdir dir
760> dir/file
761 733
762wsp -nocmd <<'EOT' 734TESTWSP([coalesced command substitution],[],[-nocmd],
763begin($(find dir))end 735[begin($(words a b))end],
764EOT
765],
766[0],
767[NF: 2 736[NF: 2
7680: begin(dir 7370: begin(a
7691: dir/file)end 7381: b)end
770TOTAL: 2 739TOTAL: 2
771]) 740])
772AT_CLEANUP
773 741
774AT_SETUP([quoted coalesced command substitution]) 742TESTWSP([quoted coalesced command substitution],[],[-nocmd],
775AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-4]) 743["begin($(words a b))end"],
776AT_CHECK([
777mkdir dir
778> dir/file
779
780wsp -nocmd <<'EOT'
781"begin($(find dir))end"
782EOT
783],
784[0],
785[NF: 1 744[NF: 1
7860: "begin(dir dir/file)end" 7450: "begin(a b)end"
787TOTAL: 1 746TOTAL: 1
788]) 747])
789AT_CLEANUP
790
791AT_SETUP([variable and command substitution])
792AT_KEYWORDS([wordsplit wsp wsp-var wsp-var24 wsp-cmd wsp-cmd-5])
793AT_CHECK([
794mkdir dir
795> dir/file
796 748
797DIR=dir wsp -nocmd -novar<<'EOT' 749TESTWSP([variable and command substitution],[],[-nocmd -novar],
798begin $DIR $(find $DIR) end 750[begin $X $(words $X $Y) end],
799EOT
800],
801[0],
802[NF: 5 751[NF: 5
8030: begin 7520: begin
8041: dir 7531: a
8052: dir 7542: a
8063: dir/file 7553: b
8074: end 7564: end
808TOTAL: 5 757TOTAL: 5
809]) 758],[],[X=a Y=b])
810AT_CLEANUP
811 759
812AT_SETUP([variable expansion and command substitution in quotes]) 760TESTWSP([variable expansion and command substitution in quotes],[],[-nocmd -novar],
813AT_KEYWORDS([wordsplit wsp wsp-var wsp-var25 wsp-cmd wsp-cmd-6]) 761["${BEGIN}($(words $X $Y))end"],
814AT_CHECK([
815mkdir dir
816> dir/file
817
818DIR=dir BEGIN=begin wsp -nocmd -novar<<'EOT'
819"${BEGIN}($(find $DIR))end"
820EOT
821],
822[0],
823[NF: 1 762[NF: 1
8240: "begin(dir dir/file)end" 7630: "begin(a b)end"
825TOTAL: 1 764TOTAL: 1
826]) 765],[],[X=a Y=b BEGIN=begin])
827AT_CLEANUP 766
828 767TESTWSP([nested commands],[],[-nocmd -novar],
829AT_SETUP([nested commands]) 768[$(words output $(words in$SUFFIX text) end)],
830AT_KEYWORDS([wordsplit wsp wsp-cmd])
831AT_CHECK([
832AT_DATA([input],[foo
833bar
834baz
835])
836SUFFIX=put wsp -nocmd -novar <<'EOT'
837$(echo output $(cat in$SUFFIX))