aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-01-16 16:15:41 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2015-12-17 15:26:28 +0200
commit4ed0f2645ccdb8ed478cacdc5703d948d8eb9082 (patch)
tree38961dd426e0c60be51a9ef6ec11dd3c789167fb
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.
-rw-r--r--src/wordsplit.c25
-rw-r--r--tests/wordsplit.at35
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],

Return to:

Send suggestions and report system problems to the System administrator.