From 4ed0f2645ccdb8ed478cacdc5703d948d8eb9082 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Fri, 16 Jan 2015 16:15:41 +0200 Subject: 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. --- src/wordsplit.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'src') 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; -- cgit v1.2.1