aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
@@ -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=
])

Return to:

Send suggestions and report system problems to the System administrator.