diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-01-16 16:15:41 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-12-17 15:26:28 +0200 |
commit | 4ed0f2645ccdb8ed478cacdc5703d948d8eb9082 (patch) | |
tree | 38961dd426e0c60be51a9ef6ec11dd3c789167fb /src | |
parent | 6b6494305818b209334c9da240717a66948467ae (diff) | |
download | grecs-4ed0f2645ccdb8ed478cacdc5703d948d8eb9082.tar.gz grecs-4ed0f2645ccdb8ed478cacdc5703d948d8eb9082.tar.bz2 |
wordsplit: fix ws trimming and return_delim option
* src/wordsplit.c (_WSNF_DELIM): New node flag
(wsnode_flagstr): Print 'd' for that flag.
(expvar): Don't set WRDSF_WS when expanding variable
value. This fixes, e.g., expansion of a$x if x begins with
a whitespace.
(wsnode_nullelim): A _WSNF_DELIM node breaks join chain.
(wordsplit_trimws): Don't affect nodes within join chains.
(scan_word): Set _WSNF_DELIM for returned delimiters.
* tests/wordsplit.at (TESTWSP): 8th argument - prologue
shell code. Use it to unset environment variables in
env/getenv tests.
Test ws elimination with return_delims set.
Diffstat (limited to 'src')
-rw-r--r-- | src/wordsplit.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index 29547f6..4715547 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c | |||
@@ -307,6 +307,7 @@ alloc_space (struct wordsplit *wsp, size_t count) | |||
307 | #define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */ | 307 | #define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */ |
308 | #define _WSNF_JOIN 0x10 /* node must be joined with the next node */ | 308 | #define _WSNF_JOIN 0x10 /* node must be joined with the next node */ |
309 | #define _WSNF_SEXP 0x20 /* is a sed expression */ | 309 | #define _WSNF_SEXP 0x20 /* is a sed expression */ |
310 | #define _WSNF_DELIM 0x40 /* node is a delimiter */ | ||
310 | 311 | ||
311 | #define _WSNF_EMPTYOK 0x0100 /* special flag indicating that | 312 | #define _WSNF_EMPTYOK 0x0100 /* special flag indicating that |
312 | wordsplit_add_segm must add the | 313 | wordsplit_add_segm must add the |
@@ -331,7 +332,7 @@ struct wordsplit_node | |||
331 | static const char * | 332 | static const char * |
332 | wsnode_flagstr (int flags) | 333 | wsnode_flagstr (int flags) |
333 | { | 334 | { |
334 | static char retbuf[6]; | 335 | static char retbuf[7]; |
335 | char *p = retbuf; | 336 | char *p = retbuf; |
336 | 337 | ||
337 | if (flags & _WSNF_WORD) | 338 | if (flags & _WSNF_WORD) |
@@ -356,6 +357,10 @@ wsnode_flagstr (int flags) | |||
356 | *p++ = 's'; | 357 | *p++ = 's'; |
357 | else | 358 | else |
358 | *p++ = '-'; | 359 | *p++ = '-'; |
360 | if (flags & _WSNF_DELIM) | ||
361 | *p++ = 'd'; | ||
362 | else | ||
363 | *p++ = '-'; | ||
359 | *p = 0; | 364 | *p = 0; |
360 | return retbuf; | 365 | return retbuf; |
361 | } | 366 | } |
@@ -1148,7 +1153,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, | |||
1148 | 1153 | ||
1149 | rc = _wsplt_subsplit (wsp, &ws, value, strlen (value), | 1154 | rc = _wsplt_subsplit (wsp, &ws, value, strlen (value), |
1150 | WRDSF_NOVAR | WRDSF_NOCMD | | 1155 | WRDSF_NOVAR | WRDSF_NOCMD | |
1151 | WRDSF_WS | WRDSF_QUOTE); | 1156 | WRDSF_QUOTE); |
1152 | free (value); | 1157 | free (value); |
1153 | if (rc) | 1158 | if (rc) |
1154 | { | 1159 | { |
@@ -1268,6 +1273,8 @@ wsnode_nullelim (struct wordsplit *wsp) | |||
1268 | for (p = wsp->ws_head; p;) | 1273 | for (p = wsp->ws_head; p;) |
1269 | { | 1274 | { |
1270 | struct wordsplit_node *next = p->next; | 1275 | struct wordsplit_node *next = p->next; |
1276 | if (p->flags & _WSNF_DELIM && p->prev) | ||
1277 | p->prev->flags &= ~_WSNF_JOIN; | ||
1271 | if (p->flags & _WSNF_NULL) | 1278 | if (p->flags & _WSNF_NULL) |
1272 | { | 1279 | { |
1273 | wsnode_remove (wsp, p); | 1280 | wsnode_remove (wsp, p); |
@@ -1446,14 +1453,21 @@ wordsplit_trimws (struct wordsplit *wsp) | |||
1446 | { | 1453 | { |
1447 | size_t n; | 1454 | size_t n; |
1448 | 1455 | ||
1456 | if (!(p->flags & _WSNF_QUOTE)) | ||
1457 | { | ||
1458 | /* Skip leading whitespace: */ | ||
1459 | for (n = p->v.segm.beg; n < p->v.segm.end && ISWS (wsp->ws_input[n]); | ||
1460 | n++) | ||
1461 | ; | ||
1462 | p->v.segm.beg = n; | ||
1463 | } | ||
1464 | |||
1465 | while (p->next && (p->flags & _WSNF_JOIN)) | ||
1466 | p = p->next; | ||
1467 | |||
1449 | if (p->flags & _WSNF_QUOTE) | 1468 | if (p->flags & _WSNF_QUOTE) |
1450 | continue; | 1469 | continue; |
1451 | 1470 | ||
1452 | /* Skip leading whitespace: */ | ||
1453 | for (n = p->v.segm.beg; n < p->v.segm.end && ISWS (wsp->ws_input[n]); | ||
1454 | n++) | ||
1455 | ; | ||
1456 | p->v.segm.beg = n; | ||
1457 | /* Trim trailing whitespace */ | 1471 | /* Trim trailing whitespace */ |
1458 | for (n = p->v.segm.end; | 1472 | for (n = p->v.segm.end; |
1459 | n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--); | 1473 | n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--); |
@@ -1835,6 +1849,7 @@ scan_word (struct wordsplit *wsp, size_t start) | |||
1835 | else if (wsp->ws_flags & WRDSF_RETURN_DELIMS) | 1849 | else if (wsp->ws_flags & WRDSF_RETURN_DELIMS) |
1836 | { | 1850 | { |
1837 | i++; | 1851 | i++; |
1852 | flags |= _WSNF_DELIM; | ||
1838 | } | 1853 | } |
1839 | else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)) | 1854 | else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)) |
1840 | flags |= _WSNF_EMPTYOK; | 1855 | flags |= _WSNF_EMPTYOK; |