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 | |
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.
-rw-r--r-- | src/wordsplit.c | 25 | ||||
-rw-r--r-- | tests/wordsplit.at | 35 |
2 files changed, 47 insertions, 13 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index 29547f6..4715547 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -309,2 +309,3 @@ alloc_space (struct wordsplit *wsp, size_t count) #define _WSNF_SEXP 0x20 /* is a sed expression */ +#define _WSNF_DELIM 0x40 /* node is a delimiter */ @@ -333,3 +334,3 @@ wsnode_flagstr (int flags) { - static char retbuf[6]; + static char retbuf[7]; char *p = retbuf; @@ -358,2 +359,6 @@ wsnode_flagstr (int flags) *p++ = '-'; + if (flags & _WSNF_DELIM) + *p++ = 'd'; + else + *p++ = '-'; *p = 0; @@ -1150,3 +1155,3 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, WRDSF_NOVAR | WRDSF_NOCMD | - WRDSF_WS | WRDSF_QUOTE); + WRDSF_QUOTE); free (value); @@ -1270,2 +1275,4 @@ wsnode_nullelim (struct wordsplit *wsp) struct wordsplit_node *next = p->next; + if (p->flags & _WSNF_DELIM && p->prev) + p->prev->flags &= ~_WSNF_JOIN; if (p->flags & _WSNF_NULL) @@ -1448,5 +1455,4 @@ wordsplit_trimws (struct wordsplit *wsp) - if (p->flags & _WSNF_QUOTE) - continue; - + if (!(p->flags & _WSNF_QUOTE)) + { /* Skip leading whitespace: */ @@ -1456,2 +1462,10 @@ wordsplit_trimws (struct wordsplit *wsp) p->v.segm.beg = n; + } + + while (p->next && (p->flags & _WSNF_JOIN)) + p = p->next; + + if (p->flags & _WSNF_QUOTE) + continue; + /* Trim trailing whitespace */ @@ -1837,2 +1851,3 @@ scan_word (struct wordsplit *wsp, size_t start) i++; + flags |= _WSNF_DELIM; } diff --git a/tests/wordsplit.at b/tests/wordsplit.at index 49bba19..d41b60c 100644 --- a/tests/wordsplit.at +++ b/tests/wordsplit.at @@ -37,3 +37,3 @@ dnl ------------------------------------------------------------ dnl TESTWSP([NAME], [KW = `'], [OPTS], [INPUT], [STDOUT = `'], -dnl [STDERR = `'], [ENV]) +dnl [STDERR = `'], [ENV], [PROLOGUE]) dnl @@ -42,3 +42,4 @@ AT_SETUP([$1]) AT_KEYWORDS([wordsplit wsp ]genkw[ $2]) -AT_CHECK([$7 wsp $3 <<'EOT' +AT_CHECK([$8 +$7 wsp $3 <<'EOT' [$4] @@ -374,8 +375,11 @@ TESTWSP([getvar],[wsp-getvar], 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 @@ -384,6 +388,8 @@ TESTWSP([getvar and env],[wsp-getvar], 3: quux -4: end +4: zwar +5: end ], [], -[TVAR=12]) +[TVAR=12 y=zwar], +[unset foo; unset x]) @@ -501,2 +507,15 @@ TESTWSP([ws elimination],[wsp-ws-elim],[delim ' ()' ws return_delims], +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], |