Implement $* and $@

This commit is contained in:
Sergey Poznyakoff 2019-05-14 19:57:42 +03:00
parent c884936422
commit a2c81cc5fa
2 changed files with 76 additions and 1 deletions

View file

@ -1241,6 +1241,56 @@ expvar_recover (struct wordsplit *wsp, const char *str,
return 0;
}
static int
expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg,
int q)
{
struct wordsplit ws;
int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE
| (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0)
| (q ? WRDSF_NOSPLIT : 0);
size_t i;
for (i = 0; i < wsp->ws_paramc; i++)
{
struct wordsplit_node *np;
int rc = _wsplt_subsplit (wsp, &ws,
wsp->ws_paramv[i], strlen (wsp->ws_paramv[i]),
wsflags, q);
if (rc)
{
_wsplt_seterr_sub (wsp, &ws);
wordsplit_free (&ws);
return 1;
}
if (q)
{
if (wsnode_new (wsp, &np))
return 1;
wsnode_insert (wsp, np, *ptail, 0);
*ptail = np;
np->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
np->v.word = ws.ws_wordv[0];
ws.ws_wordv[0] = NULL;
}
else
{
for (np = ws.ws_head; np; np = np->next)
np->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
wsnode_insert (wsp, ws.ws_head, *ptail, 0);
*ptail = ws.ws_tail;
ws.ws_head = ws.ws_tail = NULL;
}
wsflags |= WRDSF_REUSE;
}
if (wsflags & WRDSF_REUSE)
wordsplit_free (&ws);
return 0;
}
static int
expvar (struct wordsplit *wsp, const char *str, size_t len,
struct wordsplit_node **ptail, const char **pend, int flg)
@ -1285,6 +1335,14 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
newnode->v.word = value;
return 0;
}
else if ((wsp->ws_options & WRDSO_PARAMV) && str[0] == '*')
{
return expand_paramv (wsp, ptail, flg, 0);
}
else if ((wsp->ws_options & WRDSO_PARAMV) && str[0] == '@')
{
return expand_paramv (wsp, ptail, flg, 1);
}
else if (str[0] == '{'
&& (ISVARBEG (str[1])
|| (is_param = (((wsp->ws_options & WRDSO_PARAMV)
@ -1596,7 +1654,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
static int
begin_var_p (int c)
{
return c == '{' || c == '#' || ISVARBEG (c) || ISDIGIT (c);
return memchr("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c);
}
static int

View file

@ -972,6 +972,23 @@ NF: 1
TOTAL: 1
])
TESTWSP([$* and $@],[],['one two' three 'four five'],
[$*
$@],
[NF: 5
0: one
1: two
2: three
3: four
4: five
TOTAL: 5
NF: 3
0: "one two"
1: three
2: "four five"
TOTAL: 3
])
m4_popdef([TESTWSP])
m4_popdef([wspnum])
m4_popdef([wspid])