diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-05-14 19:57:42 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-05-14 19:57:42 +0300 |
commit | f6586d810d8430d6d9f833119af39726a60e4a6c (patch) | |
tree | 30529ed254805e3150e397c1f4e3e28524a80774 | |
parent | 8652a500669059d77ce7bace6e9e9da1b30c54b0 (diff) | |
download | grecs-f6586d810d8430d6d9f833119af39726a60e4a6c.tar.gz grecs-f6586d810d8430d6d9f833119af39726a60e4a6c.tar.bz2 |
wordsplit: implement $* and $@
-rw-r--r-- | src/wordsplit.c | 60 | ||||
-rw-r--r-- | tests/wordsplit.at | 17 |
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, | |||
1244 | static int | 1244 | static int |
1245 | expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg, | ||
1246 | int q) | ||
1247 | { | ||
1248 | struct wordsplit ws; | ||
1249 | int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE | ||
1250 | | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) | ||
1251 | | (q ? WRDSF_NOSPLIT : 0); | ||
1252 | size_t i; | ||
1253 | |||
1254 | for (i = 0; i < wsp->ws_paramc; i++) | ||
1255 | { | ||
1256 | struct wordsplit_node *np; | ||
1257 | int rc = _wsplt_subsplit (wsp, &ws, | ||
1258 | wsp->ws_paramv[i], strlen (wsp->ws_paramv[i]), | ||
1259 | wsflags, q); | ||
1260 | if (rc) | ||
1261 | { | ||
1262 | _wsplt_seterr_sub (wsp, &ws); | ||
1263 | wordsplit_free (&ws); | ||
1264 | return 1; | ||
1265 | } | ||
1266 | |||
1267 | if (q) | ||
1268 | { | ||
1269 | if (wsnode_new (wsp, &np)) | ||
1270 | return 1; | ||
1271 | wsnode_insert (wsp, np, *ptail, 0); | ||
1272 | *ptail = np; | ||
1273 | np->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg; | ||
1274 | np->v.word = ws.ws_wordv[0]; | ||
1275 | |||
1276 | ws.ws_wordv[0] = NULL; | ||
1277 | } | ||
1278 | else | ||
1279 | { | ||
1280 | for (np = ws.ws_head; np; np = np->next) | ||
1281 | np->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg; | ||
1282 | wsnode_insert (wsp, ws.ws_head, *ptail, 0); | ||
1283 | *ptail = ws.ws_tail; | ||
1284 | ws.ws_head = ws.ws_tail = NULL; | ||
1285 | } | ||
1286 | |||
1287 | wsflags |= WRDSF_REUSE; | ||
1288 | } | ||
1289 | if (wsflags & WRDSF_REUSE) | ||
1290 | wordsplit_free (&ws); | ||
1291 | return 0; | ||
1292 | } | ||
1293 | |||
1294 | static int | ||
1245 | expvar (struct wordsplit *wsp, const char *str, size_t len, | 1295 | expvar (struct wordsplit *wsp, const char *str, size_t len, |
@@ -1287,2 +1337,10 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, | |||
1287 | } | 1337 | } |
1338 | else if ((wsp->ws_options & WRDSO_PARAMV) && str[0] == '*') | ||
1339 | { | ||
1340 | return expand_paramv (wsp, ptail, flg, 0); | ||
1341 | } | ||
1342 | else if ((wsp->ws_options & WRDSO_PARAMV) && str[0] == '@') | ||
1343 | { | ||
1344 | return expand_paramv (wsp, ptail, flg, 1); | ||
1345 | } | ||
1288 | else if (str[0] == '{' | 1346 | else if (str[0] == '{' |
@@ -1598,3 +1656,3 @@ begin_var_p (int c) | |||
1598 | { | 1656 | { |
1599 | return c == '{' || c == '#' || ISVARBEG (c) || ISDIGIT (c); | 1657 | return memchr("{#@*", c, 4) != NULL || ISVARBEG (c) || ISDIGIT (c); |
1600 | } | 1658 | } |
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 | |||
974 | 974 | ||
975 | TESTWSP([$* and $@],[],['one two' three 'four five'], | ||
976 | [$* | ||
977 | $@], | ||
978 | [NF: 5 | ||
979 | 0: one | ||
980 | 1: two | ||
981 | 2: three | ||
982 | 3: four | ||
983 | 4: five | ||
984 | TOTAL: 5 | ||
985 | NF: 3 | ||
986 | 0: "one two" | ||
987 | 1: three | ||
988 | 2: "four five" | ||
989 | TOTAL: 3 | ||
990 | ]) | ||
991 | |||
975 | m4_popdef([TESTWSP]) | 992 | m4_popdef([TESTWSP]) |