mirror of
git://git.gnu.org.ua/wordsplit.git
synced 2025-04-26 00:29:54 +03:00
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.
This commit is contained in:
parent
4650905537
commit
6da71ddacb
2 changed files with 136 additions and 33 deletions
|
@ -74,6 +74,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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
|
|
@ -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])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue