summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org>2019-05-14 16:57:42 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2019-05-14 16:57:42 (GMT)
commitf6586d810d8430d6d9f833119af39726a60e4a6c (patch) (side-by-side diff)
tree30529ed254805e3150e397c1f4e3e28524a80774
parent8652a500669059d77ce7bace6e9e9da1b30c54b0 (diff)
downloadgrecs-f6586d810d8430d6d9f833119af39726a60e4a6c.tar.gz
grecs-f6586d810d8430d6d9f833119af39726a60e4a6c.tar.bz2
wordsplit: implement $* and $@
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--src/wordsplit.c60
-rw-r--r--tests/wordsplit.at17
2 files changed, 76 insertions, 1 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index 6a33636..05c3643 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -1244,2 +1244,52 @@ expvar_recover (struct wordsplit *wsp, const char *str,
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,
@@ -1287,2 +1337,10 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
+ 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] == '{'
@@ -1598,3 +1656,3 @@ begin_var_p (int c)
{
- return c == '{' || c == '#' || ISVARBEG (c) || ISDIGIT (c);
+ return memchr("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c);
}
diff --git a/tests/wordsplit.at b/tests/wordsplit.at
index ebd168b..0a9c4d6 100644
--- a/tests/wordsplit.at
+++ b/tests/wordsplit.at
@@ -974,2 +974,19 @@ 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])

Return to:

Send suggestions and report system problems to the System administrator.