From f6586d810d8430d6d9f833119af39726a60e4a6c Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 14 May 2019 19:57:42 +0300 Subject: wordsplit: implement $* and $@ --- src/wordsplit.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/wordsplit.c b/src/wordsplit.c index 6a33636..05c3643 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -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 -- cgit v1.2.1