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 | |||
@@ -1239,12 +1239,62 @@ expvar_recover (struct wordsplit *wsp, const char *str, | |||
1239 | newnode->v.word[2] = 0; | 1239 | newnode->v.word[2] = 0; |
1240 | *pend = str; | 1240 | *pend = str; |
1241 | return 0; | 1241 | return 0; |
1242 | } | 1242 | } |
1243 | 1243 | ||
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, |
1246 | struct wordsplit_node **ptail, const char **pend, int flg) | 1296 | struct wordsplit_node **ptail, const char **pend, int flg) |
1247 | { | 1297 | { |
1248 | size_t i = 0; | 1298 | size_t i = 0; |
1249 | const char *defstr = NULL; | 1299 | const char *defstr = NULL; |
1250 | char *value; | 1300 | char *value; |
@@ -1282,12 +1332,20 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, | |||
1282 | wsnode_insert (wsp, newnode, *ptail, 0); | 1332 | wsnode_insert (wsp, newnode, *ptail, 0); |
1283 | *ptail = newnode; | 1333 | *ptail = newnode; |
1284 | newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg; | 1334 | newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg; |
1285 | newnode->v.word = value; | 1335 | newnode->v.word = value; |
1286 | return 0; | 1336 | return 0; |
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] == '{' |
1289 | && (ISVARBEG (str[1]) | 1347 | && (ISVARBEG (str[1]) |
1290 | || (is_param = (((wsp->ws_options & WRDSO_PARAMV) | 1348 | || (is_param = (((wsp->ws_options & WRDSO_PARAMV) |
1291 | && ISDIGIT (str[1])) | 1349 | && ISDIGIT (str[1])) |
1292 | || ((wsp->ws_options & WRDSO_PARAM_NEGIDX) | 1350 | || ((wsp->ws_options & WRDSO_PARAM_NEGIDX) |
1293 | && (str[1] == '-' | 1351 | && (str[1] == '-' |
@@ -1593,13 +1651,13 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, | |||
1593 | return 0; | 1651 | return 0; |
1594 | } | 1652 | } |
1595 | 1653 | ||
1596 | static int | 1654 | static int |
1597 | begin_var_p (int c) | 1655 | 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 | } |
1601 | 1659 | ||
1602 | static int | 1660 | static int |
1603 | node_expand (struct wordsplit *wsp, struct wordsplit_node *node, | 1661 | node_expand (struct wordsplit *wsp, struct wordsplit_node *node, |
1604 | int (*beg_p) (int), | 1662 | int (*beg_p) (int), |
1605 | int (*ws_exp_fn) (struct wordsplit *wsp, | 1663 | int (*ws_exp_fn) (struct wordsplit *wsp, |
diff --git a/tests/wordsplit.at b/tests/wordsplit.at index ebd168b..0a9c4d6 100644 --- a/tests/wordsplit.at +++ b/tests/wordsplit.at | |||
@@ -969,12 +969,29 @@ $#], | |||
969 | TOTAL: 3 | 969 | TOTAL: 3 |
970 | NF: 1 | 970 | NF: 1 |
971 | 0: 12 | 971 | 0: 12 |
972 | TOTAL: 1 | 972 | TOTAL: 1 |
973 | ]) | 973 | ]) |
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]) |
976 | m4_popdef([wspnum]) | 993 | m4_popdef([wspnum]) |
977 | m4_popdef([wspid]) | 994 | m4_popdef([wspid]) |
978 | m4_popdef([genkw]) | 995 | m4_popdef([genkw]) |
979 | m4_popdef([wspgroupnum]) | 996 | m4_popdef([wspgroupnum]) |
980 | m4_popdef([wspgroupname]) | 997 | m4_popdef([wspgroupname]) |