summaryrefslogtreecommitdiffabout
path: root/src/wordsplit.c
Side-by-side diff
Diffstat (limited to 'src/wordsplit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/wordsplit.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index f563725..4e633fa 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -247,24 +247,27 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
}
}
wsp->ws_input = input;
wsp->ws_len = len;
if (!(wsp->ws_flags & WRDSF_DOOFFS))
wsp->ws_offs = 0;
if (!(wsp->ws_flags & WRDSF_DELIM))
wsp->ws_delim = " \t\n";
+ wsp->ws_sep[0] = wsp->ws_delim[0];
+ wsp->ws_sep[1] = 0;
+
if (!(wsp->ws_flags & WRDSF_COMMENT))
wsp->ws_comment = NULL;
if (!(wsp->ws_flags & WRDSF_CLOSURE))
wsp->ws_closure = NULL;
if (!(wsp->ws_flags & WRDSF_OPTIONS))
wsp->ws_options = 0;
if (wsp->ws_flags & WRDSF_ESCAPE)
{
if (!wsp->ws_escape[WRDSX_WORD])
@@ -340,25 +343,25 @@ alloc_space (struct wordsplit *wsp, size_t count)
return 0;
}
/* Node state flags */
#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_CONST 0x80 /* with _WSNF_WORD: v.word is constant */
#define _WSNF_EMPTYOK 0x0100 /* special flag indicating that
wordsplit_add_segm must add the
segment even if it is empty */
struct wordsplit_node
{
struct wordsplit_node *prev; /* Previous element */
struct wordsplit_node *next; /* Next element */
int flags; /* Node flags */
union
{
struct
@@ -432,25 +435,25 @@ static int
wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode)
{
struct wordsplit_node *node = calloc (1, sizeof (*node));
if (!node)
return _wsplt_nomem (wsp);
*pnode = node;
return 0;
}
static void
wsnode_free (struct wordsplit_node *p)
{
- if (p->flags & _WSNF_WORD)
+ if ((p->flags & (_WSNF_WORD|_WSNF_CONST)) == _WSNF_WORD)
free (p->v.word);
free (p);
}
static void
wsnode_append (struct wordsplit *wsp, struct wordsplit_node *node)
{
node->next = NULL;
node->prev = wsp->ws_tail;
if (wsp->ws_tail)
wsp->ws_tail->next = node;
else
@@ -1241,24 +1244,25 @@ expvar_recover (struct wordsplit *wsp, const char *str,
return 0;
}
static int
expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg,
int q)
{
struct wordsplit ws;
int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE
| (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0)
| (q ? WRDSF_NOSPLIT : 0);
size_t i;
+ struct wordsplit_node *tail = *ptail;
for (i = 0; i < wsp->ws_paramc; i++)
{
struct wordsplit_node *np;
int rc = _wsplt_subsplit (wsp, &ws,
wsp->ws_paramv[i], strlen (wsp->ws_paramv[i]),
wsflags, q);
if (rc)
{
_wsplt_seterr_sub (wsp, &ws);
wordsplit_free (&ws);
return 1;
@@ -1279,24 +1283,46 @@ expand_paramv (struct wordsplit *wsp, struct wordsplit_node **ptail, int flg,
{
for (np = ws.ws_head; np; np = np->next)
np->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
wsnode_insert (wsp, ws.ws_head, *ptail, 0);
*ptail = ws.ws_tail;
ws.ws_head = ws.ws_tail = NULL;
}
wsflags |= WRDSF_REUSE;
}
if (wsflags & WRDSF_REUSE)
wordsplit_free (&ws);
+
+ if (flg & _WSNF_QUOTE)
+ {
+ tail = tail->next;
+ /* Insert delimiters, mark nodes as joinable */
+ while (tail != *ptail)
+ {
+ struct wordsplit_node *next = tail->next;
+ struct wordsplit_node *newnode;
+
+ tail->flags |= _WSNF_JOIN;
+
+ if (wsnode_new (wsp, &newnode))
+ return 1;
+ newnode->flags = _WSNF_WORD | _WSNF_CONST | _WSNF_NOEXPAND | _WSNF_JOIN;
+ newnode->v.word = wsp->ws_sep;
+
+ wsnode_insert (wsp, newnode, tail, 0);
+ tail = next;
+ }
+ }
+
return 0;
}
static int
expvar (struct wordsplit *wsp, const char *str, size_t len,
struct wordsplit_node **ptail, const char **pend, int flg)
{
size_t i = 0;
const char *defstr = NULL;
char *value;
const char *vptr;
struct wordsplit_node *newnode;

Return to:

Send suggestions and report system problems to the System administrator.