summaryrefslogtreecommitdiffabout
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
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 (more/less context) (ignore whitespace changes)
-rw-r--r--src/wordsplit.c31
-rw-r--r--tests/wordsplit.at35
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
@@ -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;
diff --git a/tests/wordsplit.at b/tests/wordsplit.at
index 49bba19..d41b60c 100644
--- a/tests/wordsplit.at
+++ b/tests/wordsplit.at
@@ -35,12 +35,13 @@ 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
],
@@ -372,20 +373,25 @@ TESTWSP([getvar],[wsp-getvar],
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],
@@ -499,6 +505,19 @@ TESTWSP([ws elimination],[wsp-ws-elim],[delim ' ()' ws return_delims],
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

Return to:

Send suggestions and report system problems to the System administrator.