mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-09-20 07:04:14 +00:00
More wordsplit int cleanup
* lib/wordsplit.c: Include limits.h. (_wsplt_subsplit, wordsplit_add_segm, wsnode_quoteremoval) (wsnode_coalesce, wsnode_tail_coalesce, find_closing_paren) (expvar, begin_var_p, node_expand, begin_cmd_p, expcmd) (scan_qstring, scan_word, wordsplit_c_quoted_length) (wordsplit_string_unquote_copy, wordsplit_c_quote_copy) (exptab_matches, wordsplit_process_list): Prefer bool to int. (wordsplit_init, alloc_space, coalesce_segment) (wsnode_quoteremoval, wordsplit_finish, wordsplit_append): Use WRDSE_OK instead of 0 when the context is that of WRDSE_*. (wsnode_flagstr, coalesce_segment, wsnode_quoteremoval) (wordsplit_finish, node_split_prefix, wsplt_assign_var, expvar) (expcmd, wordsplit_tildexpand, wordsplit_pathexpand) (wsplt_unquote_char, wsplt_quote_char) (wordsplit_string_unquote_copy): Prefer '\0' to 0 when it is a char. (wsnode_insert): Omit last arg, which was always 0. All callers changed. (wordsplit_add_segm, node_split_prefix): Use unsigned, not int, for flag, for consistency. (wordsplit_finish, begin_var_p, begin_cmd_p, skip_sed_expr) (xtonum, wsplt_unquote_char, wsplt_quote_char) (wordsplit_c_unquote_char, wordsplit_c_quote_char) (wordsplit_c_quote_copy): Prefer char to int for chars. (xtonum): Don’t treat "\400" as if it were "\000".
This commit is contained in:
+138
-151
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdckdint.h>
|
#include <stdckdint.h>
|
||||||
@@ -123,7 +124,7 @@ static int wordsplit_finish (struct wordsplit *wsp);
|
|||||||
static int
|
static int
|
||||||
_wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
|
_wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
|
||||||
char const *str, idx_t len,
|
char const *str, idx_t len,
|
||||||
unsigned flags, int finalize)
|
unsigned flags, bool finalize)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -302,7 +303,7 @@ wordsplit_init (struct wordsplit *wsp, char const *input, idx_t len,
|
|||||||
|
|
||||||
wordsplit_init0 (wsp);
|
wordsplit_init0 (wsp);
|
||||||
|
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -331,7 +332,7 @@ alloc_space (struct wordsplit *wsp, idx_t count)
|
|||||||
{
|
{
|
||||||
idx_t wordroom = wsp->ws_wordn - wsp->ws_wordc;
|
idx_t wordroom = wsp->ws_wordn - wsp->ws_wordc;
|
||||||
if (offs_plus_count <= wordroom)
|
if (offs_plus_count <= wordroom)
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
|
|
||||||
/* Grow the allocation by at least MININCR. To avoid quadratic
|
/* Grow the allocation by at least MININCR. To avoid quadratic
|
||||||
behavior, also grow it by at least 50% if possible. */
|
behavior, also grow it by at least 50% if possible. */
|
||||||
@@ -350,7 +351,7 @@ alloc_space (struct wordsplit *wsp, idx_t count)
|
|||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
wsp->ws_wordn = wordn;
|
wsp->ws_wordn = wordn;
|
||||||
wsp->ws_wordv = wordv;
|
wsp->ws_wordv = wordv;
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -415,7 +416,7 @@ wsnode_flagstr (unsigned flags)
|
|||||||
*p++ = 'd';
|
*p++ = 'd';
|
||||||
else
|
else
|
||||||
*p++ = '-';
|
*p++ = '-';
|
||||||
*p = 0;
|
*p = '\0';
|
||||||
return retbuf;
|
return retbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,26 +505,13 @@ wsnode_tail (struct wordsplit_node *p)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
|
wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
|
||||||
struct wordsplit_node *anchor, int before)
|
struct wordsplit_node *anchor)
|
||||||
{
|
{
|
||||||
if (!wsp->ws_head)
|
if (!wsp->ws_head)
|
||||||
{
|
{
|
||||||
node->next = node->prev = NULL;
|
node->next = node->prev = NULL;
|
||||||
wsp->ws_head = wsp->ws_tail = node;
|
wsp->ws_head = wsp->ws_tail = node;
|
||||||
}
|
}
|
||||||
else if (before)
|
|
||||||
{
|
|
||||||
if (anchor->prev)
|
|
||||||
wsnode_insert (wsp, node, anchor->prev, 0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct wordsplit_node *tail = wsnode_tail (node);
|
|
||||||
node->prev = NULL;
|
|
||||||
tail->next = anchor;
|
|
||||||
anchor->prev = tail;
|
|
||||||
wsp->ws_head = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct wordsplit_node *p;
|
struct wordsplit_node *p;
|
||||||
@@ -540,19 +528,19 @@ wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
wordsplit_add_segm (struct wordsplit *wsp, idx_t beg, idx_t end, int flg)
|
wordsplit_add_segm (struct wordsplit *wsp, idx_t beg, idx_t end, unsigned flg)
|
||||||
{
|
{
|
||||||
if (end == beg && !(flg & _WSNF_EMPTYOK))
|
if (end == beg && !(flg & _WSNF_EMPTYOK))
|
||||||
return 0;
|
return true;
|
||||||
struct wordsplit_node *node = wsnode_new (wsp);
|
struct wordsplit_node *node = wsnode_new (wsp);
|
||||||
if (!node)
|
if (!node)
|
||||||
return 1;
|
return false;
|
||||||
node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK);
|
node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK);
|
||||||
node->v.segm.beg = beg;
|
node->v.segm.beg = beg;
|
||||||
node->v.segm.end = end;
|
node->v.segm.end = end;
|
||||||
wsnode_append (wsp, node);
|
wsnode_append (wsp, node);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -572,10 +560,8 @@ wordsplit_free_nodes (struct wordsplit *wsp)
|
|||||||
static void
|
static void
|
||||||
wordsplit_dump_nodes (struct wordsplit *wsp)
|
wordsplit_dump_nodes (struct wordsplit *wsp)
|
||||||
{
|
{
|
||||||
struct wordsplit_node *p;
|
|
||||||
intmax_t n = 0;
|
intmax_t n = 0;
|
||||||
|
for (struct wordsplit_node *p = wsp->ws_head; p; p = p->next, n++)
|
||||||
for (p = wsp->ws_head, n = 0; p; p = p->next, n++)
|
|
||||||
{
|
{
|
||||||
if (p->flags & _WSNF_WORD)
|
if (p->flags & _WSNF_WORD)
|
||||||
wsp->ws_debug ("(%02td) %4jd: %p: %#04x (%s):%s;",
|
wsp->ws_debug ("(%02td) %4jd: %p: %#04x (%s):%s;",
|
||||||
@@ -601,7 +587,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
|
|||||||
char *buf, *cur;
|
char *buf, *cur;
|
||||||
|
|
||||||
if (!(node->flags & _WSNF_JOIN))
|
if (!(node->flags & _WSNF_JOIN))
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
|
|
||||||
for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next)
|
for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next)
|
||||||
{
|
{
|
||||||
@@ -640,7 +626,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
|
|||||||
p = next;
|
p = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
*cur = 0;
|
*cur = '\0';
|
||||||
|
|
||||||
node->flags &= ~_WSNF_JOIN;
|
node->flags &= ~_WSNF_JOIN;
|
||||||
|
|
||||||
@@ -649,10 +635,10 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
|
|||||||
else
|
else
|
||||||
node->flags |= _WSNF_WORD;
|
node->flags |= _WSNF_WORD;
|
||||||
node->v.word = buf;
|
node->v.word = buf;
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
|
static void wordsplit_string_unquote_copy (struct wordsplit *ws, bool inquote,
|
||||||
char *dst, const char *src,
|
char *dst, const char *src,
|
||||||
idx_t n);
|
idx_t n);
|
||||||
|
|
||||||
@@ -663,36 +649,33 @@ wsnode_quoteremoval (struct wordsplit *wsp)
|
|||||||
|
|
||||||
for (p = wsp->ws_head; p; p = p->next)
|
for (p = wsp->ws_head; p; p = p->next)
|
||||||
{
|
{
|
||||||
const char *str = wsnode_ptr (wsp, p);
|
bool unquote = (wsp->ws_flags & WRDSF_QUOTE
|
||||||
idx_t slen = wsnode_len (p);
|
&& !(p->flags & _WSNF_NOEXPAND));
|
||||||
int unquote;
|
|
||||||
|
|
||||||
if (wsp->ws_flags & WRDSF_QUOTE)
|
|
||||||
unquote = !(p->flags & _WSNF_NOEXPAND);
|
|
||||||
else
|
|
||||||
unquote = 0;
|
|
||||||
|
|
||||||
if (unquote)
|
if (unquote)
|
||||||
{
|
{
|
||||||
|
const char *str = wsnode_ptr (wsp, p);
|
||||||
|
idx_t slen = wsnode_len (p);
|
||||||
|
|
||||||
if (!(p->flags & _WSNF_WORD))
|
if (!(p->flags & _WSNF_WORD))
|
||||||
{
|
{
|
||||||
char *newstr = imalloc (slen + 1);
|
char *newstr = imalloc (slen + 1);
|
||||||
if (!newstr)
|
if (!newstr)
|
||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
memcpy (newstr, str, slen);
|
memcpy (newstr, str, slen);
|
||||||
newstr[slen] = 0;
|
newstr[slen] = '\0';
|
||||||
p->v.word = newstr;
|
p->v.word = newstr;
|
||||||
p->flags |= _WSNF_WORD;
|
p->flags |= _WSNF_WORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
wordsplit_string_unquote_copy (wsp, p->flags & _WSNF_QUOTE,
|
wordsplit_string_unquote_copy (wsp, !!(p->flags & _WSNF_QUOTE),
|
||||||
p->v.word, str, slen);
|
p->v.word, str, slen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
wsnode_coalesce (struct wordsplit *wsp)
|
wsnode_coalesce (struct wordsplit *wsp)
|
||||||
{
|
{
|
||||||
struct wordsplit_node *p;
|
struct wordsplit_node *p;
|
||||||
@@ -701,12 +684,12 @@ wsnode_coalesce (struct wordsplit *wsp)
|
|||||||
{
|
{
|
||||||
if (p->flags & _WSNF_JOIN)
|
if (p->flags & _WSNF_JOIN)
|
||||||
if (coalesce_segment (wsp, p))
|
if (coalesce_segment (wsp, p))
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
wsnode_tail_coalesce (struct wordsplit *wsp, struct wordsplit_node *p)
|
wsnode_tail_coalesce (struct wordsplit *wsp, struct wordsplit_node *p)
|
||||||
{
|
{
|
||||||
if (p->next)
|
if (p->next)
|
||||||
@@ -718,9 +701,9 @@ wsnode_tail_coalesce (struct wordsplit *wsp, struct wordsplit_node *p)
|
|||||||
np = np->next;
|
np = np->next;
|
||||||
}
|
}
|
||||||
if (coalesce_segment (wsp, p))
|
if (coalesce_segment (wsp, p))
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static idx_t skip_delim (struct wordsplit *wsp);
|
static idx_t skip_delim (struct wordsplit *wsp);
|
||||||
@@ -730,7 +713,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
|||||||
{
|
{
|
||||||
struct wordsplit_node *p;
|
struct wordsplit_node *p;
|
||||||
idx_t n;
|
idx_t n;
|
||||||
int delim;
|
char delim;
|
||||||
|
|
||||||
/* Postprocess delimiters. It would be rather simple, if it weren't for
|
/* Postprocess delimiters. It would be rather simple, if it weren't for
|
||||||
the incremental operation.
|
the incremental operation.
|
||||||
@@ -758,7 +741,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
|||||||
is set.
|
is set.
|
||||||
*/
|
*/
|
||||||
again:
|
again:
|
||||||
delim = 0; /* Delimiter being processed (if any) */
|
delim = '\0'; /* Delimiter being processed (if any) */
|
||||||
n = 0; /* Number of words processed so far */
|
n = 0; /* Number of words processed so far */
|
||||||
p = wsp->ws_head; /* Current node */
|
p = wsp->ws_head; /* Current node */
|
||||||
|
|
||||||
@@ -782,7 +765,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delim = 0;
|
delim = '\0';
|
||||||
n++; /* Count this node; it will be returned */
|
n++; /* Count this node; it will be returned */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -808,7 +791,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
|||||||
/* Last node was a delimiter or a compressed run of delimiters;
|
/* Last node was a delimiter or a compressed run of delimiters;
|
||||||
Count it, and clear the delimiter marker */
|
Count it, and clear the delimiter marker */
|
||||||
n++;
|
n++;
|
||||||
delim = 0;
|
delim = '\0';
|
||||||
}
|
}
|
||||||
if (wsp->ws_options & WRDSO_MAXWORDS)
|
if (wsp->ws_options & WRDSO_MAXWORDS)
|
||||||
{
|
{
|
||||||
@@ -870,7 +853,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
|||||||
if (!newstr)
|
if (!newstr)
|
||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
memcpy (newstr, str, slen);
|
memcpy (newstr, str, slen);
|
||||||
newstr[slen] = 0;
|
newstr[slen] = '\0';
|
||||||
|
|
||||||
wsnode_remove (wsp, wsp->ws_head);
|
wsnode_remove (wsp, wsp->ws_head);
|
||||||
|
|
||||||
@@ -881,7 +864,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
|
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -910,7 +893,7 @@ wordsplit_append (wordsplit_t *wsp, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
wsp->ws_wordc += i;
|
wsp->ws_wordc += i;
|
||||||
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
|
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
|
||||||
return 0;
|
return WRDSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Variable expansion */
|
/* Variable expansion */
|
||||||
@@ -918,14 +901,14 @@ static int
|
|||||||
node_split_prefix (struct wordsplit *wsp,
|
node_split_prefix (struct wordsplit *wsp,
|
||||||
struct wordsplit_node **ptail,
|
struct wordsplit_node **ptail,
|
||||||
struct wordsplit_node *node,
|
struct wordsplit_node *node,
|
||||||
idx_t beg, idx_t len, int flg)
|
idx_t beg, idx_t len, unsigned flg)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return 0;
|
return 0;
|
||||||
struct wordsplit_node *newnode = wsnode_new (wsp);
|
struct wordsplit_node *newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
if (node->flags & _WSNF_WORD)
|
if (node->flags & _WSNF_WORD)
|
||||||
{
|
{
|
||||||
const char *str = wsnode_ptr (wsp, node);
|
const char *str = wsnode_ptr (wsp, node);
|
||||||
@@ -933,7 +916,7 @@ node_split_prefix (struct wordsplit *wsp,
|
|||||||
if (!newstr)
|
if (!newstr)
|
||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
memcpy (newstr, str + beg, len);
|
memcpy (newstr, str + beg, len);
|
||||||
newstr[len] = 0;
|
newstr[len] = '\0';
|
||||||
newnode->flags = _WSNF_WORD;
|
newnode->flags = _WSNF_WORD;
|
||||||
newnode->v.word = newstr;
|
newnode->v.word = newstr;
|
||||||
}
|
}
|
||||||
@@ -947,7 +930,7 @@ node_split_prefix (struct wordsplit *wsp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
|
find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
|
||||||
char const *paren)
|
char const *paren)
|
||||||
{
|
{
|
||||||
@@ -972,7 +955,7 @@ find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
|
|||||||
if (--level == 0)
|
if (--level == 0)
|
||||||
{
|
{
|
||||||
*poff = i;
|
*poff = i;
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1001,7 +984,7 @@ find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1132,7 +1115,7 @@ wsplt_assign_var (struct wordsplit *wsp, char const *name, idx_t namelen,
|
|||||||
if (!p)
|
if (!p)
|
||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
memcpy (p, name, namelen);
|
memcpy (p, name, namelen);
|
||||||
p[namelen] = 0;
|
p[namelen] = '\0';
|
||||||
|
|
||||||
v = strdup (value);
|
v = strdup (value);
|
||||||
if (!v)
|
if (!v)
|
||||||
@@ -1218,7 +1201,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
newnode = wsnode_new (wsp);
|
newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_WORD | flg;
|
newnode->flags = _WSNF_WORD | flg;
|
||||||
newnode->v.word = malloc (3);
|
newnode->v.word = malloc (3);
|
||||||
@@ -1226,7 +1209,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
newnode->v.word[0] = '$';
|
newnode->v.word[0] = '$';
|
||||||
newnode->v.word[1] = str[0];
|
newnode->v.word[1] = str[0];
|
||||||
newnode->v.word[2] = 0;
|
newnode->v.word[2] = '\0';
|
||||||
*pend = str;
|
*pend = str;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1261,7 +1244,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
rc = WRDSE_UNDEF;
|
rc = WRDSE_UNDEF;
|
||||||
|
|
||||||
if (rc == WRDSE_OK
|
if (rc == WRDSE_OK
|
||||||
&& (!value || value[0] == 0)
|
&& !(value && *value)
|
||||||
&& defstr && defstr[-1] == ':')
|
&& defstr && defstr[-1] == ':')
|
||||||
{
|
{
|
||||||
free (value);
|
free (value);
|
||||||
@@ -1279,7 +1262,8 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
|
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
|
||||||
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
|
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
|
||||||
(wsp->ws_flags &
|
(wsp->ws_flags &
|
||||||
(WRDSF_NOVAR | WRDSF_NOCMD)), 1);
|
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
||||||
|
true);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
free (value);
|
free (value);
|
||||||
@@ -1301,7 +1285,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
|
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
|
||||||
(wsp->ws_flags &
|
(wsp->ws_flags &
|
||||||
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
||||||
1);
|
true);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -1327,7 +1311,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
WRDSF_QUOTE |
|
WRDSF_QUOTE |
|
||||||
(wsp->ws_flags &
|
(wsp->ws_flags &
|
||||||
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
||||||
1);
|
true);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
wsp->ws_error ("%.*s%s: %s",
|
wsp->ws_error ("%.*s%s: %s",
|
||||||
printflen (i), str, printfdots (i),
|
printflen (i), str, printfdots (i),
|
||||||
@@ -1387,19 +1371,19 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
free (value);
|
free (value);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
||||||
newnode->v.word = value;
|
newnode->v.word = value;
|
||||||
}
|
}
|
||||||
else if (*value == 0)
|
else if (!*value)
|
||||||
{
|
{
|
||||||
free (value);
|
free (value);
|
||||||
/* Empty string is a special case */
|
/* Empty string is a special case */
|
||||||
newnode = wsnode_new (wsp);
|
newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_NULL;
|
newnode->flags = _WSNF_NULL;
|
||||||
}
|
}
|
||||||
@@ -1409,10 +1393,10 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
|
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
|
||||||
WRDSF_NOVAR | WRDSF_NOCMD |
|
(WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE
|
||||||
WRDSF_QUOTE
|
| (WSP_RETURN_DELIMS (wsp)
|
||||||
| (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) ,
|
? WRDSF_RETURN_DELIMS : 0)),
|
||||||
0);
|
false);
|
||||||
free (value);
|
free (value);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@@ -1420,7 +1404,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
wordsplit_free (&ws);
|
wordsplit_free (&ws);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
wsnode_insert (wsp, ws.ws_head, *ptail, 0);
|
wsnode_insert (wsp, ws.ws_head, *ptail);
|
||||||
*ptail = ws.ws_tail;
|
*ptail = ws.ws_tail;
|
||||||
ws.ws_head = ws.ws_tail = NULL;
|
ws.ws_head = ws.ws_tail = NULL;
|
||||||
wordsplit_free (&ws);
|
wordsplit_free (&ws);
|
||||||
@@ -1433,36 +1417,36 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
newnode = wsnode_new (wsp);
|
newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
||||||
newnode->v.word = malloc (size + 1);
|
newnode->v.word = malloc (size + 1);
|
||||||
if (!newnode->v.word)
|
if (!newnode->v.word)
|
||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
memcpy (newnode->v.word, start, size);
|
memcpy (newnode->v.word, start, size);
|
||||||
newnode->v.word[size] = 0;
|
newnode->v.word[size] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newnode = wsnode_new (wsp);
|
newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_NULL;
|
newnode->flags = _WSNF_NULL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
begin_var_p (int c)
|
begin_var_p (char c)
|
||||||
{
|
{
|
||||||
return c == '{' || ISVARBEG (c);
|
return c == '{' || ISVARBEG (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
|
node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
|
||||||
int (*beg_p) (int),
|
bool (*beg_p) (char),
|
||||||
int (*ws_exp_fn) (struct wordsplit *wsp,
|
int (*ws_exp_fn) (struct wordsplit *wsp,
|
||||||
char const *str, idx_t len,
|
char const *str, idx_t len,
|
||||||
struct wordsplit_node **ptail,
|
struct wordsplit_node **ptail,
|
||||||
@@ -1490,11 +1474,11 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
|
|||||||
if (tail != node)
|
if (tail != node)
|
||||||
tail->flags |= _WSNF_JOIN;
|
tail->flags |= _WSNF_JOIN;
|
||||||
if (node_split_prefix (wsp, &tail, node, off, n, _WSNF_JOIN))
|
if (node_split_prefix (wsp, &tail, node, off, n, _WSNF_JOIN))
|
||||||
return 1;
|
return false;
|
||||||
p++;
|
p++;
|
||||||
if (ws_exp_fn (wsp, p, slen - n, &tail, &p,
|
if (ws_exp_fn (wsp, p, slen - n, &tail, &p,
|
||||||
node->flags & (_WSNF_JOIN | _WSNF_QUOTE)))
|
node->flags & (_WSNF_JOIN | _WSNF_QUOTE)))
|
||||||
return 1;
|
return false;
|
||||||
off += p - str + 1;
|
off += p - str + 1;
|
||||||
str = p + 1;
|
str = p + 1;
|
||||||
}
|
}
|
||||||
@@ -1505,14 +1489,14 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
|
|||||||
tail->flags |= _WSNF_JOIN;
|
tail->flags |= _WSNF_JOIN;
|
||||||
if (node_split_prefix (wsp, &tail, node, off, p - str,
|
if (node_split_prefix (wsp, &tail, node, off, p - str,
|
||||||
node->flags & (_WSNF_JOIN|_WSNF_QUOTE)))
|
node->flags & (_WSNF_JOIN|_WSNF_QUOTE)))
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
if (tail != node)
|
if (tail != node)
|
||||||
{
|
{
|
||||||
wsnode_remove (wsp, node);
|
wsnode_remove (wsp, node);
|
||||||
wsnode_free (node);
|
wsnode_free (node);
|
||||||
}
|
}
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove NULL nodes from the list */
|
/* Remove NULL nodes from the list */
|
||||||
@@ -1544,7 +1528,7 @@ wordsplit_varexp (struct wordsplit *wsp)
|
|||||||
{
|
{
|
||||||
struct wordsplit_node *next = p->next;
|
struct wordsplit_node *next = p->next;
|
||||||
if (!(p->flags & (_WSNF_NOEXPAND|_WSNF_DELIM)))
|
if (!(p->flags & (_WSNF_NOEXPAND|_WSNF_DELIM)))
|
||||||
if (node_expand (wsp, p, begin_var_p, expvar))
|
if (!node_expand (wsp, p, begin_var_p, expvar))
|
||||||
return 1;
|
return 1;
|
||||||
p = next;
|
p = next;
|
||||||
}
|
}
|
||||||
@@ -1553,8 +1537,8 @@ wordsplit_varexp (struct wordsplit *wsp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
begin_cmd_p (int c)
|
begin_cmd_p (char c)
|
||||||
{
|
{
|
||||||
return c == '(';
|
return c == '(';
|
||||||
}
|
}
|
||||||
@@ -1582,7 +1566,7 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
{
|
{
|
||||||
struct wordsplit ws;
|
struct wordsplit ws;
|
||||||
|
|
||||||
rc = _wsplt_subsplit (wsp, &ws, str, j, WRDSF_WS | WRDSF_QUOTE, 1);
|
rc = _wsplt_subsplit (wsp, &ws, str, j, WRDSF_WS | WRDSF_QUOTE, true);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
_wsplt_seterr_sub (wsp, &ws);
|
_wsplt_seterr_sub (wsp, &ws);
|
||||||
@@ -1616,19 +1600,19 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
newnode = wsnode_new (wsp);
|
newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
||||||
newnode->v.word = value;
|
newnode->v.word = value;
|
||||||
}
|
}
|
||||||
else if (*value == 0)
|
else if (!*value)
|
||||||
{
|
{
|
||||||
free (value);
|
free (value);
|
||||||
/* Empty string is a special case */
|
/* Empty string is a special case */
|
||||||
newnode = wsnode_new (wsp);
|
newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_NULL;
|
newnode->flags = _WSNF_NULL;
|
||||||
}
|
}
|
||||||
@@ -1638,10 +1622,11 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
|
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
|
||||||
WRDSF_NOVAR | WRDSF_NOCMD
|
(WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_WS
|
||||||
| WRDSF_WS | WRDSF_QUOTE
|
| WRDSF_QUOTE
|
||||||
| (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0),
|
| (WSP_RETURN_DELIMS (wsp)
|
||||||
0);
|
? WRDSF_RETURN_DELIMS : 0)),
|
||||||
|
false);
|
||||||
free (value);
|
free (value);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@@ -1649,7 +1634,7 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
wordsplit_free (&ws);
|
wordsplit_free (&ws);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
wsnode_insert (wsp, ws.ws_head, *ptail, 0);
|
wsnode_insert (wsp, ws.ws_head, *ptail);
|
||||||
*ptail = ws.ws_tail;
|
*ptail = ws.ws_tail;
|
||||||
ws.ws_head = ws.ws_tail = NULL;
|
ws.ws_head = ws.ws_tail = NULL;
|
||||||
wordsplit_free (&ws);
|
wordsplit_free (&ws);
|
||||||
@@ -1660,7 +1645,7 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
|||||||
newnode = wsnode_new (wsp);
|
newnode = wsnode_new (wsp);
|
||||||
if (!newnode)
|
if (!newnode)
|
||||||
return 1;
|
return 1;
|
||||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
wsnode_insert (wsp, newnode, *ptail);
|
||||||
*ptail = newnode;
|
*ptail = newnode;
|
||||||
newnode->flags = _WSNF_NULL;
|
newnode->flags = _WSNF_NULL;
|
||||||
}
|
}
|
||||||
@@ -1676,7 +1661,7 @@ wordsplit_cmdexp (struct wordsplit *wsp)
|
|||||||
{
|
{
|
||||||
struct wordsplit_node *next = p->next;
|
struct wordsplit_node *next = p->next;
|
||||||
if (!(p->flags & _WSNF_NOEXPAND))
|
if (!(p->flags & _WSNF_NOEXPAND))
|
||||||
if (node_expand (wsp, p, begin_cmd_p, expcmd))
|
if (!node_expand (wsp, p, begin_cmd_p, expcmd))
|
||||||
return 1;
|
return 1;
|
||||||
p = next;
|
p = next;
|
||||||
}
|
}
|
||||||
@@ -1765,7 +1750,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
|
|||||||
}
|
}
|
||||||
--i;
|
--i;
|
||||||
memcpy (uname, str + 1, i);
|
memcpy (uname, str + 1, i);
|
||||||
uname[i] = 0;
|
uname[i] = '\0';
|
||||||
pw = getpwnam (uname);
|
pw = getpwnam (uname);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1786,7 +1771,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
|
|||||||
|
|
||||||
memcpy (newstr, pw->pw_dir, dlen);
|
memcpy (newstr, pw->pw_dir, dlen);
|
||||||
memcpy (newstr + dlen, str + i + 1, slen - i - 1);
|
memcpy (newstr + dlen, str + i + 1, slen - i - 1);
|
||||||
newstr[size] = 0;
|
newstr[size] = '\0';
|
||||||
if (p->flags & _WSNF_WORD)
|
if (p->flags & _WSNF_WORD)
|
||||||
free (p->v.word);
|
free (p->v.word);
|
||||||
p->v.word = newstr;
|
p->v.word = newstr;
|
||||||
@@ -1844,7 +1829,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
|
|||||||
if (!pattern)
|
if (!pattern)
|
||||||
return _wsplt_nomem (wsp);
|
return _wsplt_nomem (wsp);
|
||||||
memcpy (pattern, str, slen);
|
memcpy (pattern, str, slen);
|
||||||
pattern[slen] = 0;
|
pattern[slen] = '\0';
|
||||||
|
|
||||||
switch (glob (pattern, flags, NULL, &g))
|
switch (glob (pattern, flags, NULL, &g))
|
||||||
{
|
{
|
||||||
@@ -1900,7 +1885,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
|
|||||||
}
|
}
|
||||||
newnode->v.word = newstr;
|
newnode->v.word = newstr;
|
||||||
newnode->flags |= _WSNF_WORD|_WSNF_QUOTE;
|
newnode->flags |= _WSNF_WORD|_WSNF_QUOTE;
|
||||||
wsnode_insert (wsp, newnode, prev, 0);
|
wsnode_insert (wsp, newnode, prev);
|
||||||
prev = newnode;
|
prev = newnode;
|
||||||
}
|
}
|
||||||
globfree (&g);
|
globfree (&g);
|
||||||
@@ -1919,7 +1904,7 @@ skip_sed_expr (char const *command, idx_t i, idx_t len)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int delim;
|
char delim;
|
||||||
|
|
||||||
if (command[i] == ';')
|
if (command[i] == ';')
|
||||||
i++;
|
i++;
|
||||||
@@ -1969,7 +1954,7 @@ skip_delim_real (struct wordsplit *wsp)
|
|||||||
#define _WRDS_OK 1
|
#define _WRDS_OK 1
|
||||||
#define _WRDS_ERR 2
|
#define _WRDS_ERR 2
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
scan_qstring (struct wordsplit *wsp, idx_t start, idx_t *end)
|
scan_qstring (struct wordsplit *wsp, idx_t start, idx_t *end)
|
||||||
{
|
{
|
||||||
idx_t j;
|
idx_t j;
|
||||||
@@ -1985,26 +1970,26 @@ scan_qstring (struct wordsplit *wsp, idx_t start, idx_t *end)
|
|||||||
unsigned flags = _WSNF_QUOTE | _WSNF_EMPTYOK;
|
unsigned flags = _WSNF_QUOTE | _WSNF_EMPTYOK;
|
||||||
if (q == '\'')
|
if (q == '\'')
|
||||||
flags |= _WSNF_NOEXPAND;
|
flags |= _WSNF_NOEXPAND;
|
||||||
if (wordsplit_add_segm (wsp, start + 1, j, flags))
|
if (!wordsplit_add_segm (wsp, start + 1, j, flags))
|
||||||
return _WRDS_ERR;
|
return false;
|
||||||
*end = j;
|
*end = j;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wsp->ws_endp = start;
|
wsp->ws_endp = start;
|
||||||
_wsplt_seterr (wsp, WRDSE_QUOTE);
|
_wsplt_seterr (wsp, WRDSE_QUOTE);
|
||||||
return _WRDS_ERR;
|
return false;
|
||||||
}
|
}
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
scan_word (struct wordsplit *wsp, idx_t start, bool consume_all)
|
||||||
{
|
{
|
||||||
idx_t len = wsp->ws_len;
|
idx_t len = wsp->ws_len;
|
||||||
const char *command = wsp->ws_input;
|
const char *command = wsp->ws_input;
|
||||||
const char *comment = wsp->ws_comment;
|
const char *comment = wsp->ws_comment;
|
||||||
int join = 0;
|
bool join = false;
|
||||||
unsigned flags = 0;
|
unsigned flags = 0;
|
||||||
struct wordsplit_node *np = wsp->ws_tail;
|
struct wordsplit_node *np = wsp->ws_tail;
|
||||||
|
|
||||||
@@ -2033,7 +2018,7 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
|||||||
idx_t j;
|
idx_t j;
|
||||||
for (j = i + 1; j < len && command[j] != '\n'; j++)
|
for (j = i + 1; j < len && command[j] != '\n'; j++)
|
||||||
;
|
;
|
||||||
if (wordsplit_add_segm (wsp, start, i, 0))
|
if (!wordsplit_add_segm (wsp, start, i, 0))
|
||||||
return _WRDS_ERR;
|
return _WRDS_ERR;
|
||||||
wsp->ws_endp = j;
|
wsp->ws_endp = j;
|
||||||
return _WRDS_OK;
|
return _WRDS_OK;
|
||||||
@@ -2054,12 +2039,12 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
|||||||
{
|
{
|
||||||
if (join && wsp->ws_tail)
|
if (join && wsp->ws_tail)
|
||||||
wsp->ws_tail->flags |= _WSNF_JOIN;
|
wsp->ws_tail->flags |= _WSNF_JOIN;
|
||||||
if (wordsplit_add_segm (wsp, start, i, _WSNF_JOIN))
|
if (!wordsplit_add_segm (wsp, start, i, _WSNF_JOIN))
|
||||||
return _WRDS_ERR;
|
return _WRDS_ERR;
|
||||||
if (scan_qstring (wsp, i, &i))
|
if (!scan_qstring (wsp, i, &i))
|
||||||
return _WRDS_ERR;
|
return _WRDS_ERR;
|
||||||
start = i + 1;
|
start = i + 1;
|
||||||
join = 1;
|
join = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2067,11 +2052,11 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
|||||||
{
|
{
|
||||||
if (!(wsp->ws_flags & WRDSF_NOVAR)
|
if (!(wsp->ws_flags & WRDSF_NOVAR)
|
||||||
&& command[i+1] == '{'
|
&& command[i+1] == '{'
|
||||||
&& find_closing_paren (command, i + 2, len, &i, "{}") == 0)
|
&& !find_closing_paren (command, i + 2, len, &i, "{}"))
|
||||||
continue;
|
continue;
|
||||||
if (!(wsp->ws_flags & WRDSF_NOCMD)
|
if (!(wsp->ws_flags & WRDSF_NOCMD)
|
||||||
&& command[i+1] == '('
|
&& command[i+1] == '('
|
||||||
&& find_closing_paren (command, i + 2, len, &i, "()") == 0)
|
&& !find_closing_paren (command, i + 2, len, &i, "()"))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2091,7 +2076,7 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
|||||||
|
|
||||||
if (join && i > start && wsp->ws_tail)
|
if (join && i > start && wsp->ws_tail)
|
||||||
wsp->ws_tail->flags |= _WSNF_JOIN;
|
wsp->ws_tail->flags |= _WSNF_JOIN;
|
||||||
if (wordsplit_add_segm (wsp, start, i, flags))
|
if (!wordsplit_add_segm (wsp, start, i, flags))
|
||||||
return _WRDS_ERR;
|
return _WRDS_ERR;
|
||||||
wsp->ws_endp = i;
|
wsp->ws_endp = i;
|
||||||
if (wsp->ws_flags & WRDSF_INCREMENTAL)
|
if (wsp->ws_flags & WRDSF_INCREMENTAL)
|
||||||
@@ -2112,11 +2097,17 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xtonum (int *pval, const char *src, int base, int cnt)
|
xtonum (char *pval, char const *src, int base, int cnt)
|
||||||
{
|
{
|
||||||
int i, val = 0;
|
int i;
|
||||||
|
unsigned char val = 0;
|
||||||
|
|
||||||
for (i = 0; i < cnt; i++)
|
/* The maximum value that a prefix of a number can represent.
|
||||||
|
This is 31 if base is 8 and UCHAR_MAX == 255,
|
||||||
|
so that "\400" is treated as "\40" followed by "0", not as "\000". */
|
||||||
|
unsigned char max_prefix = UCHAR_MAX / base;
|
||||||
|
|
||||||
|
for (i = 0; i < cnt && val <= max_prefix; i++)
|
||||||
{
|
{
|
||||||
unsigned char c = src[i];
|
unsigned char c = src[i];
|
||||||
unsigned char digit;
|
unsigned char digit;
|
||||||
@@ -2137,15 +2128,15 @@ xtonum (int *pval, const char *src, int base, int cnt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
idx_t
|
idx_t
|
||||||
wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote)
|
wordsplit_c_quoted_length (const char *str, bool quote_hex, bool *quote)
|
||||||
{
|
{
|
||||||
idx_t len = 0;
|
idx_t len = 0;
|
||||||
|
|
||||||
*quote = 0;
|
*quote = false;
|
||||||
for (; *str; str++)
|
for (; *str; str++)
|
||||||
{
|
{
|
||||||
if (strchr (" \"", *str))
|
if (strchr (" \"", *str))
|
||||||
*quote = 1;
|
*quote = true;
|
||||||
|
|
||||||
if (*str == ' ')
|
if (*str == ' ')
|
||||||
len++;
|
len++;
|
||||||
@@ -2166,8 +2157,8 @@ wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static char
|
||||||
wsplt_unquote_char (const char *transtab, int c)
|
wsplt_unquote_char (const char *transtab, char c)
|
||||||
{
|
{
|
||||||
while (*transtab && transtab[1])
|
while (*transtab && transtab[1])
|
||||||
{
|
{
|
||||||
@@ -2175,44 +2166,41 @@ wsplt_unquote_char (const char *transtab, int c)
|
|||||||
return *transtab;
|
return *transtab;
|
||||||
++transtab;
|
++transtab;
|
||||||
}
|
}
|
||||||
return 0;
|
return '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static char
|
||||||
wsplt_quote_char (const char *transtab, int c)
|
wsplt_quote_char (const char *transtab, char c)
|
||||||
{
|
{
|
||||||
for (; *transtab && transtab[1]; transtab += 2)
|
for (; *transtab && transtab[1]; transtab += 2)
|
||||||
{
|
{
|
||||||
if (transtab[1] == c)
|
if (transtab[1] == c)
|
||||||
return *transtab;
|
return *transtab;
|
||||||
}
|
}
|
||||||
return 0;
|
return '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
char
|
||||||
wordsplit_c_unquote_char (int c)
|
wordsplit_c_unquote_char (char c)
|
||||||
{
|
{
|
||||||
return wsplt_unquote_char (wordsplit_c_escape_tab, c);
|
return wsplt_unquote_char (wordsplit_c_escape_tab, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
char
|
||||||
wordsplit_c_quote_char (int c)
|
wordsplit_c_quote_char (char c)
|
||||||
{
|
{
|
||||||
return wsplt_quote_char (wordsplit_c_escape_tab, c);
|
return wsplt_quote_char (wordsplit_c_escape_tab, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
|
wordsplit_string_unquote_copy (struct wordsplit *ws, bool inquote,
|
||||||
char *dst, char const *src, idx_t n)
|
char *dst, char const *src, idx_t n)
|
||||||
{
|
{
|
||||||
idx_t i = 0;
|
for (idx_t i = 0; i < n; )
|
||||||
int c;
|
|
||||||
|
|
||||||
inquote = !!inquote;
|
|
||||||
while (i < n)
|
|
||||||
{
|
{
|
||||||
if (src[i] == '\\')
|
if (src[i] == '\\')
|
||||||
{
|
{
|
||||||
|
char c;
|
||||||
++i;
|
++i;
|
||||||
if (WRDSO_ESC_TEST (ws, inquote, WRDSO_XESC)
|
if (WRDSO_ESC_TEST (ws, inquote, WRDSO_XESC)
|
||||||
&& (src[i] == 'x' || src[i] == 'X'))
|
&& (src[i] == 'x' || src[i] == 'X'))
|
||||||
@@ -2224,8 +2212,7 @@ wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int off = xtonum (&c, src + i + 1,
|
int off = xtonum (&c, src + i + 1, 16, 2);
|
||||||
16, 2);
|
|
||||||
if (off == 0)
|
if (off == 0)
|
||||||
{
|
{
|
||||||
*dst++ = '\\';
|
*dst++ = '\\';
|
||||||
@@ -2276,11 +2263,11 @@ wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
|
|||||||
else
|
else
|
||||||
*dst++ = src[i++];
|
*dst++ = src[i++];
|
||||||
}
|
}
|
||||||
*dst = 0;
|
*dst = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
|
wordsplit_c_quote_copy (char *dst, const char *src, bool quote_hex)
|
||||||
{
|
{
|
||||||
for (; *src; src++)
|
for (; *src; src++)
|
||||||
{
|
{
|
||||||
@@ -2304,7 +2291,7 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int c = wordsplit_c_quote_char (*src);
|
char c = wordsplit_c_quote_char (*src);
|
||||||
*dst++ = '\\';
|
*dst++ = '\\';
|
||||||
if (c)
|
if (c)
|
||||||
*dst++ = c;
|
*dst++ = c;
|
||||||
@@ -2360,7 +2347,7 @@ static struct exptab exptab[] = {
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
exptab_matches (struct exptab *p, struct wordsplit *wsp)
|
exptab_matches (struct exptab *p, struct wordsplit *wsp)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
@@ -2371,7 +2358,7 @@ exptab_matches (struct exptab *p, struct wordsplit *wsp)
|
|||||||
if (p->opt & EXPOPT_NEG)
|
if (p->opt & EXPOPT_NEG)
|
||||||
result = !result;
|
result = !result;
|
||||||
|
|
||||||
return result;
|
return !!result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -2389,14 +2376,14 @@ wordsplit_process_list (struct wordsplit *wsp, idx_t start)
|
|||||||
&& wsp->ws_wordi + 1 == wsp->ws_maxwords))
|
&& wsp->ws_wordi + 1 == wsp->ws_maxwords))
|
||||||
{
|
{
|
||||||
/* Treat entire input as a single word */
|
/* Treat entire input as a single word */
|
||||||
if (scan_word (wsp, start, 1) == _WRDS_ERR)
|
if (scan_word (wsp, start, true) == _WRDS_ERR)
|
||||||
return wsp->ws_errno;
|
return wsp->ws_errno;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
while ((rc = scan_word (wsp, start, 0)) == _WRDS_OK)
|
while ((rc = scan_word (wsp, start, false)) == _WRDS_OK)
|
||||||
start = skip_delim (wsp);
|
start = skip_delim (wsp);
|
||||||
/* Make sure tail element is not joinable */
|
/* Make sure tail element is not joinable */
|
||||||
if (wsp->ws_tail)
|
if (wsp->ws_tail)
|
||||||
|
|||||||
+7
-5
@@ -101,7 +101,8 @@ struct wordsplit
|
|||||||
idx_t ws_len; /* Length of ws_input. */
|
idx_t ws_len; /* Length of ws_input. */
|
||||||
idx_t ws_endp; /* Points past the last processed byte in
|
idx_t ws_endp; /* Points past the last processed byte in
|
||||||
ws_input. */
|
ws_input. */
|
||||||
int ws_errno; /* [Output] Error code, if an error occurred. */
|
int ws_errno; /* [Output] Error code, if an error occurred.
|
||||||
|
This is not the same as a POSIX errno value. */
|
||||||
char *ws_usererr; /* Points to textual description of
|
char *ws_usererr; /* Points to textual description of
|
||||||
the error, if ws_errno is WRDSE_USERERR. Must
|
the error, if ws_errno is WRDSE_USERERR. Must
|
||||||
be allocated with malloc(3). */
|
be allocated with malloc(3). */
|
||||||
@@ -230,6 +231,7 @@ struct wordsplit
|
|||||||
/* Test WS for escape option F for words (Q==0) or quoted strings (Q==1) */
|
/* Test WS for escape option F for words (Q==0) or quoted strings (Q==1) */
|
||||||
#define WRDSO_ESC_TEST(ws,q,f) ((ws)->ws_options & ((f) << 4*(q)))
|
#define WRDSO_ESC_TEST(ws,q,f) ((ws)->ws_options & ((f) << 4*(q)))
|
||||||
|
|
||||||
|
/* Error codes. */
|
||||||
#define WRDSE_OK 0
|
#define WRDSE_OK 0
|
||||||
#define WRDSE_EOF WRDSE_OK
|
#define WRDSE_EOF WRDSE_OK
|
||||||
#define WRDSE_QUOTE 1
|
#define WRDSE_QUOTE 1
|
||||||
@@ -251,10 +253,10 @@ int wordsplit_get_words (wordsplit_t *ws, idx_t *wordc, char ***wordv);
|
|||||||
|
|
||||||
int wordsplit_append (wordsplit_t *wsp, int argc, char **argv);
|
int wordsplit_append (wordsplit_t *wsp, int argc, char **argv);
|
||||||
|
|
||||||
int wordsplit_c_unquote_char (int c);
|
char wordsplit_c_unquote_char (char c);
|
||||||
int wordsplit_c_quote_char (int c);
|
char wordsplit_c_quote_char (char c);
|
||||||
idx_t wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote);
|
idx_t wordsplit_c_quoted_length (const char *str, bool quote_hex, bool *quote);
|
||||||
void wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex);
|
void wordsplit_c_quote_copy (char *dst, const char *src, bool quote_hex);
|
||||||
|
|
||||||
void wordsplit_perror (wordsplit_t *ws);
|
void wordsplit_perror (wordsplit_t *ws);
|
||||||
const char *wordsplit_strerror (wordsplit_t *ws);
|
const char *wordsplit_strerror (wordsplit_t *ws);
|
||||||
|
|||||||
Reference in New Issue
Block a user