aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2014-10-23 15:35:40 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-12-17 15:25:24 +0200
commitfc6012da9a3c264d168f47219630054747a553ac (patch)
treed183baefeab46f7f4c9bc9d607cc2b556143cbdd
parente66e2edfa50c8535e05b334c6a5d867fafeb9469 (diff)
downloadgrecs-fc6012da9a3c264d168f47219630054747a553ac.tar.gz
grecs-fc6012da9a3c264d168f47219630054747a553ac.tar.bz2
wordsplit: fix variable expansion within commands
* src/wordsplit.c (_wsplt_seterr): New static function. Use instead of assigning value to ws_errno. (coalesce_segment): Propagate _WSNF_QUOTE flag to the resulting node. (wordsplit_process_list): Coalesce the list before running command expansion. * tests/testsuite.at: Test wordsplit first. If it fails, most other tests will fail too. * tests/wordsplit.at: Test command expansion.
-rw-r--r--src/wordsplit.c62
-rw-r--r--tests/testsuite.at4
-rw-r--r--tests/wordsplit.at107
3 files changed, 138 insertions, 35 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index 2b99b42..a67e455 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -75,6 +75,15 @@ _wsplt_error (const char *fmt, ...)
static void wordsplit_free_nodes (struct wordsplit *);
static int
+_wsplt_seterr (struct wordsplit *wsp, int ec)
+{
+ wsp->ws_errno = ec;
+ if (wsp->ws_flags & WRDSF_SHOWERR)
+ wordsplit_perror (wsp);
+ return ec;
+}
+
+static int
_wsplt_nomem (struct wordsplit *wsp)
{
errno = ENOMEM;
@@ -123,10 +132,8 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
if (!(wsp->ws_flags & WRDSF_NOVAR)
&& !(wsp->ws_flags & (WRDSF_ENV | WRDSF_GETVAR)))
{
+ _wsplt_seterr (wsp, WRDSE_USAGE);
errno = EINVAL;
- wsp->ws_errno = WRDSE_USAGE;
- if (wsp->ws_flags & WRDSF_SHOWERR)
- wordsplit_perror (wsp);
return wsp->ws_errno;
}
@@ -134,10 +141,8 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
{
if (!wsp->ws_command)
{
+ _wsplt_seterr (wsp, WRDSE_USAGE);
errno = EINVAL;
- wsp->ws_errno = WRDSE_USAGE;
- if (wsp->ws_flags & WRDSF_SHOWERR)
- wordsplit_perror (wsp);
return wsp->ws_errno;
}
}
@@ -464,6 +469,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
cur += slen;
if (p != node)
{
+ node->flags |= p->flags & _WSNF_QUOTE;
wsnode_remove (wsp, p);
stop = p == end;
wsnode_free (p);
@@ -741,10 +747,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
defstr = str + i + 1;
if (find_closing_paren (str, i + 1, len, &j, "{}"))
- {
- wsp->ws_errno = WRDSE_CBRACE;
- return 1;
- }
+ return _wsplt_seterr (wsp, WRDSE_CBRACE);
*pend = str + j;
}
else if (str[i] == '}')
@@ -752,10 +755,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
*pend = str + i;
}
else
- {
- wsp->ws_errno = WRDSE_CBRACE;
- return 1;
- }
+ return _wsplt_seterr (wsp, WRDSE_CBRACE);
}
else
{
@@ -805,9 +805,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
wsp->ws_usererr = value;
/* fall through */
default:
- wsp->ws_errno = rc;
- if (wsp->ws_flags & WRDSF_SHOWERR)
- wordsplit_perror (wsp);
+ _wsplt_seterr (wsp, rc);
return 1;
}
}
@@ -841,9 +839,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else if (wsp->ws_flags & WRDSF_UNDEF)
{
- wsp->ws_errno = WRDSE_UNDEF;
- if (wsp->ws_flags & WRDSF_SHOWERR)
- wordsplit_perror (wsp);
+ _wsplt_seterr (wsp, WRDSE_UNDEF);
return 1;
}
else
@@ -1067,7 +1063,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
if (find_closing_paren (str, 0, len, &j, "()"))
{
- wsp->ws_errno = WRDSE_CBRACE;
+ _wsplt_seterr (wsp, WRDSE_CBRACE);
return 1;
}
@@ -1091,9 +1087,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len,
{
if (rc == WRDSE_USERERR)
wsp->ws_usererr = value;
- wsp->ws_errno = rc;
- if (wsp->ws_flags & WRDSF_SHOWERR)
- wordsplit_perror (wsp);
+ _wsplt_seterr (wsp, rc);
return 1;
}
@@ -1298,9 +1292,7 @@ scan_qstring (struct wordsplit *wsp, size_t start, size_t * end)
else
{
wsp->ws_endp = start;
- wsp->ws_errno = WRDSE_QUOTE;
- if (wsp->ws_flags & WRDSF_SHOWERR)
- wordsplit_perror (wsp);
+ _wsplt_seterr (wsp, WRDSE_QUOTE);
return _WRDS_ERR;
}
return 0;
@@ -1672,6 +1664,15 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
if (!(wsp->ws_flags & WRDSF_NOCMD))
{
+ if (wsnode_coalesce (wsp))
+ return wsp->ws_errno;
+
+ if (wsp->ws_flags & WRDSF_SHOWDBG)
+ {
+ wsp->ws_debug ("Coalesced list:");
+ wordsplit_dump_nodes (wsp);
+ }
+
if (wordsplit_cmdexp (wsp))
{
wordsplit_free_nodes (wsp);
@@ -1723,12 +1724,7 @@ wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
start = skip_delim (wsp);
if (wsp->ws_endp == wsp->ws_len)
- {
- wsp->ws_errno = WRDSE_NOINPUT;
- if (wsp->ws_flags & WRDSF_SHOWERR)
- wordsplit_perror (wsp);
- return wsp->ws_errno;
- }
+ return _wsplt_seterr (wsp, WRDSE_NOINPUT);
cmdptr = wsp->ws_input + wsp->ws_endp;
cmdlen = wsp->ws_len - wsp->ws_endp;
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 7f2e511..da47548 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -47,6 +47,8 @@ dnl # Begin tests
AT_INIT
m4_if(GRECS_DISTCK_AT,,,[m4_include(GRECS_DISTCK_AT)])
+m4_include([wordsplit.at])
+
AT_BANNER([Formats])
m4_include([format00.at])
m4_include([format01.at])
@@ -118,6 +120,4 @@ m4_include([locus01.at])
m4_include([locus02.at])
m4_include([path-locus.at])
-m4_include([wordsplit.at])
-
# End of testsuite.at
diff --git a/tests/wordsplit.at b/tests/wordsplit.at
index dbebcae..2cc9e4a 100644
--- a/tests/wordsplit.at
+++ b/tests/wordsplit.at
@@ -538,4 +538,111 @@ TESTWSP([getvar, alternate value],[wsp-var wsp-var23 wsp-alt wsp-alt02 wsp-getva
1: isset
])
+dnl Something that doesn't fit into TESTWSP
+
+AT_SETUP([simple command expansion])
+AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-1 wsp50])
+AT_CHECK([
+mkdir dir
+> dir/file
+
+wsp -nocmd <<'EOT'
+begin $(find dir) end
+EOT
+],
+[0],
+[NF: 4
+0: begin
+1: dir
+2: dir/file
+3: end
+])
+AT_CLEANUP
+
+AT_SETUP([quoted command expansion])
+AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-2 wsp51])
+AT_CHECK([
+mkdir dir
+> dir/file
+
+wsp -nocmd <<'EOT'
+begin "$(find dir)" end
+EOT
+],
+[0],
+[NF: 3
+0: begin
+1: "dir dir/file"
+2: end
+])
+AT_CLEANUP
+
+AT_SETUP([coalesced command expansion])
+AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-3 wsp52])
+AT_CHECK([
+mkdir dir
+> dir/file
+
+wsp -nocmd <<'EOT'
+begin($(find dir))end
+EOT
+],
+[0],
+[NF: 2
+0: begin(dir
+1: dir/file)end
+])
+AT_CLEANUP
+
+AT_SETUP([quoted coalesced command expansion])
+AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-4 wsp53])
+AT_CHECK([
+mkdir dir
+> dir/file
+
+wsp -nocmd <<'EOT'
+"begin($(find dir))end"
+EOT
+],
+[0],
+[NF: 1
+0: "begin(dir dir/file)end"
+])
+AT_CLEANUP
+
+AT_SETUP([variable and command expansion])
+AT_KEYWORDS([wordsplit wsp wsp-var wsp-var24 wsp-cmd wsp-cmd-5 wsp54])
+AT_CHECK([
+mkdir dir
+> dir/file
+
+DIR=dir wsp -nocmd -novar<<'EOT'
+begin $(find $DIR) end
+EOT
+],
+[0],
+[NF: 4
+0: begin
+1: dir
+2: dir/file
+3: end
+])
+AT_CLEANUP
+
+AT_SETUP([variable and command expansion in quotes])
+AT_KEYWORDS([wordsplit wsp wsp-var wsp-var25 wsp-cmd wsp-cmd-6 wsp55])
+AT_CHECK([
+mkdir dir
+> dir/file
+
+DIR=dir wsp -nocmd -novar<<'EOT'
+"begin($(find $DIR))end"
+EOT
+],
+[0],
+[NF: 1
+0: "begin(dir dir/file)end"
+])
+AT_CLEANUP
+
m4_popdef([TESTWSP])

Return to:

Send suggestions and report system problems to the System administrator.