summaryrefslogtreecommitdiffabout
path: root/src
authorSergey Poznyakoff <gray@gnu.org.ua>2015-01-16 14:15:41 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2015-12-17 13:26:28 (GMT)
commit4ed0f2645ccdb8ed478cacdc5703d948d8eb9082 (patch) (side-by-side diff)
tree38961dd426e0c60be51a9ef6ec11dd3c789167fb /src
parent6b6494305818b209334c9da240717a66948467ae (diff)
downloadgrecs-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') (more/less context) (ignore whitespace changes)
-rw-r--r--src/wordsplit.c31
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)
#define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */
#define _WSNF_JOIN 0x10 /* node must be joined with the next node */
#define _WSNF_SEXP 0x20 /* is a sed expression */
+#define _WSNF_DELIM 0x40 /* node is a delimiter */
#define _WSNF_EMPTYOK 0x0100 /* special flag indicating that
wordsplit_add_segm must add the
@@ -331,7 +332,7 @@ struct wordsplit_node
static const char *
wsnode_flagstr (int flags)
{
- static char retbuf[6];
+ static char retbuf[7];
char *p = retbuf;
if (flags & _WSNF_WORD)
@@ -356,6 +357,10 @@ wsnode_flagstr (int flags)
*p++ = 's';
else
*p++ = '-';
+ if (flags & _WSNF_DELIM)
+ *p++ = 'd';
+ else
+ *p++ = '-';
*p = 0;
return retbuf;
}
@@ -1148,7 +1153,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
WRDSF_NOVAR | WRDSF_NOCMD |
- WRDSF_WS | WRDSF_QUOTE);
+ WRDSF_QUOTE);
free (value);
if (rc)
{
@@ -1268,6 +1273,8 @@ wsnode_nullelim (struct wordsplit *wsp)
for (p = wsp->ws_head; p;)
{
struct wordsplit_node *next = p->next;
+ if (p->flags & _WSNF_DELIM && p->prev)
+ p->prev->flags &= ~_WSNF_JOIN;
if (p->flags & _WSNF_NULL)
{
wsnode_remove (wsp, p);
@@ -1446,14 +1453,21 @@ wordsplit_trimws (struct wordsplit *wsp)
{
size_t n;
+ if (!(p->flags & _WSNF_QUOTE))
+ {
+ /* Skip leading whitespace: */
+ for (n = p->v.segm.beg; n < p->v.segm.end && ISWS (wsp->ws_input[n]);
+ n++)
+ ;
+ p->v.segm.beg = n;
+ }
+
+ while (p->next && (p->flags & _WSNF_JOIN))
+ p = p->next;
+
if (p->flags & _WSNF_QUOTE)
continue;
-
- /* Skip leading whitespace: */
- for (n = p->v.segm.beg; n < p->v.segm.end && ISWS (wsp->ws_input[n]);
- n++)
- ;
- p->v.segm.beg = n;
+
/* Trim trailing whitespace */
for (n = p->v.segm.end;
n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--);
@@ -1835,6 +1849,7 @@ scan_word (struct wordsplit *wsp, size_t start)
else if (wsp->ws_flags & WRDSF_RETURN_DELIMS)
{
i++;
+ flags |= _WSNF_DELIM;
}
else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS))
flags |= _WSNF_EMPTYOK;

Return to:

Send suggestions and report system problems to the System administrator.