diff options
-rw-r--r-- | src/wordsplit.c | 31 | ||||
-rw-r--r-- | tests/wordsplit.at | 35 |
2 files changed, 50 insertions, 16 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index 29547f6..4715547 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -304,12 +304,13 @@ alloc_space (struct wordsplit *wsp, size_t count) #define _WSNF_NULL 0x01 /* null node (a noop) */ #define _WSNF_WORD 0x02 /* node contains word in v.word */ #define _WSNF_QUOTE 0x04 /* text is quoted */ #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 segment even if it is empty */ struct wordsplit_node @@ -328,13 +329,13 @@ struct wordsplit_node } v; }; static const char * wsnode_flagstr (int flags) { - static char retbuf[6]; + static char retbuf[7]; char *p = retbuf; if (flags & _WSNF_WORD) *p++ = 'w'; else if (flags & _WSNF_NULL) *p++ = 'n'; @@ -353,12 +354,16 @@ wsnode_flagstr (int flags) else *p++ = '-'; if (flags & _WSNF_SEXP) *p++ = 's'; else *p++ = '-'; + if (flags & _WSNF_DELIM) + *p++ = 'd'; + else + *p++ = '-'; *p = 0; return retbuf; } static const char * wsnode_ptr (struct wordsplit *wsp, struct wordsplit_node *p) @@ -1145,13 +1150,13 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, { struct wordsplit ws; int i, rc; rc = _wsplt_subsplit (wsp, &ws, value, strlen (value), WRDSF_NOVAR | WRDSF_NOCMD | - WRDSF_WS | WRDSF_QUOTE); + WRDSF_QUOTE); free (value); if (rc) { _wsplt_seterr_sub (wsp, &ws); wordsplit_free (&ws); return 1; @@ -1265,12 +1270,14 @@ wsnode_nullelim (struct wordsplit *wsp) { struct wordsplit_node *p; 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); wsnode_free (p); } p = next; @@ -1443,20 +1450,27 @@ wordsplit_trimws (struct wordsplit *wsp) struct wordsplit_node *p; for (p = wsp->ws_head; p; p = p->next) { 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--); p->v.segm.end = n; if (p->v.segm.beg == p->v.segm.end) p->flags |= _WSNF_NULL; @@ -1832,12 +1846,13 @@ scan_word (struct wordsplit *wsp, size_t start) i++; } } else if (wsp->ws_flags & WRDSF_RETURN_DELIMS) { i++; + flags |= _WSNF_DELIM; } else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)) flags |= _WSNF_EMPTYOK; if (join && i > start && wsp->ws_tail) wsp->ws_tail->flags |= _WSNF_JOIN; diff --git a/tests/wordsplit.at b/tests/wordsplit.at index 49bba19..d41b60c 100644 --- a/tests/wordsplit.at +++ b/tests/wordsplit.at @@ -32,18 +32,19 @@ wspid]) m4_pushdef([WSPGROUP],[ m4_define([wspgroupname],$1) m4_define([wspgroupnum],0)]) dnl ------------------------------------------------------------ dnl TESTWSP([NAME], [KW = `'], [OPTS], [INPUT], [STDOUT = `'], -dnl [STDERR = `'], [ENV]) +dnl [STDERR = `'], [ENV], [PROLOGUE]) dnl m4_pushdef([TESTWSP],[ AT_SETUP([$1]) AT_KEYWORDS([wordsplit wsp ]genkw[ $2]) -AT_CHECK([$7 wsp $3 <<'EOT' +AT_CHECK([$8 +$7 wsp $3 <<'EOT' [$4] EOT ], [0], [$5], [$6]) @@ -369,26 +370,31 @@ TESTWSP([getvar],[wsp-getvar], [begin $foo $x end], [NF: 4 0: begin 1: bar 2: quux 3: end -]) +], +[], +[], +[unset foo; unset x]) TESTWSP([getvar and env],[wsp-getvar], -[foo=bar x=quux], -[begin $foo $TVAR $x end], -[NF: 5 +[foo=bar x=quux y=xur], +[begin $foo $TVAR $x $y end], +[NF: 6 0: begin 1: bar 2: 12 3: quux -4: end +4: zwar +5: end ], [], -[TVAR=12]) +[TVAR=12 y=zwar], +[unset foo; unset x]) TESTWSP([getvar, alternate value],[wsp-getvar], [foo=bar], [a ${foo:+isset}], [NF: 2 0: a @@ -496,12 +502,25 @@ TESTWSP([ws elimination],[wsp-ws-elim],[delim ' ()' ws return_delims], 0: ( 1: list 2: items 3: ) ]) +TESTWSP([ws elimination + return delim],[wsp-ws-elim-ret], +[-default novar nocmd delim ":," return_delims ws dquote], +["foo" : "bar", "quux" : "baaz" ], +[NF: 7 +0: foo +1: : +2: bar +3: , +4: quux +5: : +6: baaz +]) + TESTWSP([empty quotes],[wsp-empty-quotes],[delim : ws return_delims], [t=""], [NF: 1 0: t= ]) |