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:
289
lib/wordsplit.c
289
lib/wordsplit.c
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <glob.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdckdint.h>
|
||||
@@ -123,7 +124,7 @@ static int wordsplit_finish (struct wordsplit *wsp);
|
||||
static int
|
||||
_wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
|
||||
char const *str, idx_t len,
|
||||
unsigned flags, int finalize)
|
||||
unsigned flags, bool finalize)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -302,7 +303,7 @@ wordsplit_init (struct wordsplit *wsp, char const *input, idx_t len,
|
||||
|
||||
wordsplit_init0 (wsp);
|
||||
|
||||
return 0;
|
||||
return WRDSE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -331,7 +332,7 @@ alloc_space (struct wordsplit *wsp, idx_t count)
|
||||
{
|
||||
idx_t wordroom = wsp->ws_wordn - wsp->ws_wordc;
|
||||
if (offs_plus_count <= wordroom)
|
||||
return 0;
|
||||
return WRDSE_OK;
|
||||
|
||||
/* Grow the allocation by at least MININCR. To avoid quadratic
|
||||
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);
|
||||
wsp->ws_wordn = wordn;
|
||||
wsp->ws_wordv = wordv;
|
||||
return 0;
|
||||
return WRDSE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -415,7 +416,7 @@ wsnode_flagstr (unsigned flags)
|
||||
*p++ = 'd';
|
||||
else
|
||||
*p++ = '-';
|
||||
*p = 0;
|
||||
*p = '\0';
|
||||
return retbuf;
|
||||
}
|
||||
|
||||
@@ -504,26 +505,13 @@ wsnode_tail (struct wordsplit_node *p)
|
||||
|
||||
static void
|
||||
wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
|
||||
struct wordsplit_node *anchor, int before)
|
||||
struct wordsplit_node *anchor)
|
||||
{
|
||||
if (!wsp->ws_head)
|
||||
{
|
||||
node->next = node->prev = NULL;
|
||||
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
|
||||
{
|
||||
struct wordsplit_node *p;
|
||||
@@ -540,19 +528,19 @@ wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
wordsplit_add_segm (struct wordsplit *wsp, idx_t beg, idx_t end, int flg)
|
||||
static bool
|
||||
wordsplit_add_segm (struct wordsplit *wsp, idx_t beg, idx_t end, unsigned flg)
|
||||
{
|
||||
if (end == beg && !(flg & _WSNF_EMPTYOK))
|
||||
return 0;
|
||||
return true;
|
||||
struct wordsplit_node *node = wsnode_new (wsp);
|
||||
if (!node)
|
||||
return 1;
|
||||
return false;
|
||||
node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK);
|
||||
node->v.segm.beg = beg;
|
||||
node->v.segm.end = end;
|
||||
wsnode_append (wsp, node);
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -572,10 +560,8 @@ wordsplit_free_nodes (struct wordsplit *wsp)
|
||||
static void
|
||||
wordsplit_dump_nodes (struct wordsplit *wsp)
|
||||
{
|
||||
struct wordsplit_node *p;
|
||||
intmax_t n = 0;
|
||||
|
||||
for (p = wsp->ws_head, n = 0; p; p = p->next, n++)
|
||||
for (struct wordsplit_node *p = wsp->ws_head; p; p = p->next, n++)
|
||||
{
|
||||
if (p->flags & _WSNF_WORD)
|
||||
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;
|
||||
|
||||
if (!(node->flags & _WSNF_JOIN))
|
||||
return 0;
|
||||
return WRDSE_OK;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
*cur = 0;
|
||||
*cur = '\0';
|
||||
|
||||
node->flags &= ~_WSNF_JOIN;
|
||||
|
||||
@@ -649,10 +635,10 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
|
||||
else
|
||||
node->flags |= _WSNF_WORD;
|
||||
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,
|
||||
idx_t n);
|
||||
|
||||
@@ -663,36 +649,33 @@ wsnode_quoteremoval (struct wordsplit *wsp)
|
||||
|
||||
for (p = wsp->ws_head; p; p = p->next)
|
||||
{
|
||||
const char *str = wsnode_ptr (wsp, p);
|
||||
idx_t slen = wsnode_len (p);
|
||||
int unquote;
|
||||
|
||||
if (wsp->ws_flags & WRDSF_QUOTE)
|
||||
unquote = !(p->flags & _WSNF_NOEXPAND);
|
||||
else
|
||||
unquote = 0;
|
||||
bool unquote = (wsp->ws_flags & WRDSF_QUOTE
|
||||
&& !(p->flags & _WSNF_NOEXPAND));
|
||||
|
||||
if (unquote)
|
||||
{
|
||||
const char *str = wsnode_ptr (wsp, p);
|
||||
idx_t slen = wsnode_len (p);
|
||||
|
||||
if (!(p->flags & _WSNF_WORD))
|
||||
{
|
||||
char *newstr = imalloc (slen + 1);
|
||||
if (!newstr)
|
||||
return _wsplt_nomem (wsp);
|
||||
memcpy (newstr, str, slen);
|
||||
newstr[slen] = 0;
|
||||
newstr[slen] = '\0';
|
||||
p->v.word = newstr;
|
||||
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);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return WRDSE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
wsnode_coalesce (struct wordsplit *wsp)
|
||||
{
|
||||
struct wordsplit_node *p;
|
||||
@@ -701,12 +684,12 @@ wsnode_coalesce (struct wordsplit *wsp)
|
||||
{
|
||||
if (p->flags & _WSNF_JOIN)
|
||||
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)
|
||||
{
|
||||
if (p->next)
|
||||
@@ -718,9 +701,9 @@ wsnode_tail_coalesce (struct wordsplit *wsp, struct wordsplit_node *p)
|
||||
np = np->next;
|
||||
}
|
||||
if (coalesce_segment (wsp, p))
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static idx_t skip_delim (struct wordsplit *wsp);
|
||||
@@ -730,7 +713,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
||||
{
|
||||
struct wordsplit_node *p;
|
||||
idx_t n;
|
||||
int delim;
|
||||
char delim;
|
||||
|
||||
/* Postprocess delimiters. It would be rather simple, if it weren't for
|
||||
the incremental operation.
|
||||
@@ -758,7 +741,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
||||
is set.
|
||||
*/
|
||||
again:
|
||||
delim = 0; /* Delimiter being processed (if any) */
|
||||
delim = '\0'; /* Delimiter being processed (if any) */
|
||||
n = 0; /* Number of words processed so far */
|
||||
p = wsp->ws_head; /* Current node */
|
||||
|
||||
@@ -782,7 +765,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
||||
}
|
||||
else
|
||||
{
|
||||
delim = 0;
|
||||
delim = '\0';
|
||||
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;
|
||||
Count it, and clear the delimiter marker */
|
||||
n++;
|
||||
delim = 0;
|
||||
delim = '\0';
|
||||
}
|
||||
if (wsp->ws_options & WRDSO_MAXWORDS)
|
||||
{
|
||||
@@ -870,7 +853,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
||||
if (!newstr)
|
||||
return _wsplt_nomem (wsp);
|
||||
memcpy (newstr, str, slen);
|
||||
newstr[slen] = 0;
|
||||
newstr[slen] = '\0';
|
||||
|
||||
wsnode_remove (wsp, wsp->ws_head);
|
||||
|
||||
@@ -881,7 +864,7 @@ wordsplit_finish (struct wordsplit *wsp)
|
||||
break;
|
||||
}
|
||||
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
|
||||
return 0;
|
||||
return WRDSE_OK;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -910,7 +893,7 @@ wordsplit_append (wordsplit_t *wsp, int argc, char **argv)
|
||||
}
|
||||
wsp->ws_wordc += i;
|
||||
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
|
||||
return 0;
|
||||
return WRDSE_OK;
|
||||
}
|
||||
|
||||
/* Variable expansion */
|
||||
@@ -918,14 +901,14 @@ static int
|
||||
node_split_prefix (struct wordsplit *wsp,
|
||||
struct wordsplit_node **ptail,
|
||||
struct wordsplit_node *node,
|
||||
idx_t beg, idx_t len, int flg)
|
||||
idx_t beg, idx_t len, unsigned flg)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
struct wordsplit_node *newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
if (node->flags & _WSNF_WORD)
|
||||
{
|
||||
const char *str = wsnode_ptr (wsp, node);
|
||||
@@ -933,7 +916,7 @@ node_split_prefix (struct wordsplit *wsp,
|
||||
if (!newstr)
|
||||
return _wsplt_nomem (wsp);
|
||||
memcpy (newstr, str + beg, len);
|
||||
newstr[len] = 0;
|
||||
newstr[len] = '\0';
|
||||
newnode->flags = _WSNF_WORD;
|
||||
newnode->v.word = newstr;
|
||||
}
|
||||
@@ -947,7 +930,7 @@ node_split_prefix (struct wordsplit *wsp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
|
||||
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)
|
||||
{
|
||||
*poff = i;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1001,7 +984,7 @@ find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1132,7 +1115,7 @@ wsplt_assign_var (struct wordsplit *wsp, char const *name, idx_t namelen,
|
||||
if (!p)
|
||||
return _wsplt_nomem (wsp);
|
||||
memcpy (p, name, namelen);
|
||||
p[namelen] = 0;
|
||||
p[namelen] = '\0';
|
||||
|
||||
v = strdup (value);
|
||||
if (!v)
|
||||
@@ -1218,7 +1201,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_WORD | flg;
|
||||
newnode->v.word = malloc (3);
|
||||
@@ -1226,7 +1209,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
return _wsplt_nomem (wsp);
|
||||
newnode->v.word[0] = '$';
|
||||
newnode->v.word[1] = str[0];
|
||||
newnode->v.word[2] = 0;
|
||||
newnode->v.word[2] = '\0';
|
||||
*pend = str;
|
||||
return 0;
|
||||
}
|
||||
@@ -1261,7 +1244,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
rc = WRDSE_UNDEF;
|
||||
|
||||
if (rc == WRDSE_OK
|
||||
&& (!value || value[0] == 0)
|
||||
&& !(value && *value)
|
||||
&& defstr && defstr[-1] == ':')
|
||||
{
|
||||
free (value);
|
||||
@@ -1279,7 +1262,8 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
|
||||
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
|
||||
(wsp->ws_flags &
|
||||
(WRDSF_NOVAR | WRDSF_NOCMD)), 1);
|
||||
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
||||
true);
|
||||
if (rc)
|
||||
return rc;
|
||||
free (value);
|
||||
@@ -1301,7 +1285,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
|
||||
(wsp->ws_flags &
|
||||
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
||||
1);
|
||||
true);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -1327,7 +1311,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
WRDSF_QUOTE |
|
||||
(wsp->ws_flags &
|
||||
(WRDSF_NOVAR | WRDSF_NOCMD)),
|
||||
1);
|
||||
true);
|
||||
if (rc == 0)
|
||||
wsp->ws_error ("%.*s%s: %s",
|
||||
printflen (i), str, printfdots (i),
|
||||
@@ -1387,19 +1371,19 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
free (value);
|
||||
return 1;
|
||||
}
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
||||
newnode->v.word = value;
|
||||
}
|
||||
else if (*value == 0)
|
||||
else if (!*value)
|
||||
{
|
||||
free (value);
|
||||
/* Empty string is a special case */
|
||||
newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_NULL;
|
||||
}
|
||||
@@ -1409,10 +1393,10 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
int rc;
|
||||
|
||||
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
|
||||
WRDSF_NOVAR | WRDSF_NOCMD |
|
||||
WRDSF_QUOTE
|
||||
| (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) ,
|
||||
0);
|
||||
(WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE
|
||||
| (WSP_RETURN_DELIMS (wsp)
|
||||
? WRDSF_RETURN_DELIMS : 0)),
|
||||
false);
|
||||
free (value);
|
||||
if (rc)
|
||||
{
|
||||
@@ -1420,7 +1404,7 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
wordsplit_free (&ws);
|
||||
return 1;
|
||||
}
|
||||
wsnode_insert (wsp, ws.ws_head, *ptail, 0);
|
||||
wsnode_insert (wsp, ws.ws_head, *ptail);
|
||||
*ptail = ws.ws_tail;
|
||||
ws.ws_head = ws.ws_tail = NULL;
|
||||
wordsplit_free (&ws);
|
||||
@@ -1433,36 +1417,36 @@ expvar (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
||||
newnode->v.word = malloc (size + 1);
|
||||
if (!newnode->v.word)
|
||||
return _wsplt_nomem (wsp);
|
||||
memcpy (newnode->v.word, start, size);
|
||||
newnode->v.word[size] = 0;
|
||||
newnode->v.word[size] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
begin_var_p (int c)
|
||||
static bool
|
||||
begin_var_p (char c)
|
||||
{
|
||||
return c == '{' || ISVARBEG (c);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
|
||||
int (*beg_p) (int),
|
||||
bool (*beg_p) (char),
|
||||
int (*ws_exp_fn) (struct wordsplit *wsp,
|
||||
char const *str, idx_t len,
|
||||
struct wordsplit_node **ptail,
|
||||
@@ -1490,11 +1474,11 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
|
||||
if (tail != node)
|
||||
tail->flags |= _WSNF_JOIN;
|
||||
if (node_split_prefix (wsp, &tail, node, off, n, _WSNF_JOIN))
|
||||
return 1;
|
||||
return false;
|
||||
p++;
|
||||
if (ws_exp_fn (wsp, p, slen - n, &tail, &p,
|
||||
node->flags & (_WSNF_JOIN | _WSNF_QUOTE)))
|
||||
return 1;
|
||||
return false;
|
||||
off += p - str + 1;
|
||||
str = p + 1;
|
||||
}
|
||||
@@ -1505,14 +1489,14 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
|
||||
tail->flags |= _WSNF_JOIN;
|
||||
if (node_split_prefix (wsp, &tail, node, off, p - str,
|
||||
node->flags & (_WSNF_JOIN|_WSNF_QUOTE)))
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
if (tail != node)
|
||||
{
|
||||
wsnode_remove (wsp, node);
|
||||
wsnode_free (node);
|
||||
}
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Remove NULL nodes from the list */
|
||||
@@ -1544,7 +1528,7 @@ wordsplit_varexp (struct wordsplit *wsp)
|
||||
{
|
||||
struct wordsplit_node *next = p->next;
|
||||
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;
|
||||
p = next;
|
||||
}
|
||||
@@ -1553,8 +1537,8 @@ wordsplit_varexp (struct wordsplit *wsp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
begin_cmd_p (int c)
|
||||
static bool
|
||||
begin_cmd_p (char c)
|
||||
{
|
||||
return c == '(';
|
||||
}
|
||||
@@ -1582,7 +1566,7 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
{
|
||||
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)
|
||||
{
|
||||
_wsplt_seterr_sub (wsp, &ws);
|
||||
@@ -1616,19 +1600,19 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
|
||||
newnode->v.word = value;
|
||||
}
|
||||
else if (*value == 0)
|
||||
else if (!*value)
|
||||
{
|
||||
free (value);
|
||||
/* Empty string is a special case */
|
||||
newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_NULL;
|
||||
}
|
||||
@@ -1638,10 +1622,11 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
int rc;
|
||||
|
||||
rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
|
||||
WRDSF_NOVAR | WRDSF_NOCMD
|
||||
| WRDSF_WS | WRDSF_QUOTE
|
||||
| (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0),
|
||||
0);
|
||||
(WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_WS
|
||||
| WRDSF_QUOTE
|
||||
| (WSP_RETURN_DELIMS (wsp)
|
||||
? WRDSF_RETURN_DELIMS : 0)),
|
||||
false);
|
||||
free (value);
|
||||
if (rc)
|
||||
{
|
||||
@@ -1649,7 +1634,7 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
wordsplit_free (&ws);
|
||||
return 1;
|
||||
}
|
||||
wsnode_insert (wsp, ws.ws_head, *ptail, 0);
|
||||
wsnode_insert (wsp, ws.ws_head, *ptail);
|
||||
*ptail = ws.ws_tail;
|
||||
ws.ws_head = ws.ws_tail = NULL;
|
||||
wordsplit_free (&ws);
|
||||
@@ -1660,7 +1645,7 @@ expcmd (struct wordsplit *wsp, char const *str, idx_t len,
|
||||
newnode = wsnode_new (wsp);
|
||||
if (!newnode)
|
||||
return 1;
|
||||
wsnode_insert (wsp, newnode, *ptail, 0);
|
||||
wsnode_insert (wsp, newnode, *ptail);
|
||||
*ptail = newnode;
|
||||
newnode->flags = _WSNF_NULL;
|
||||
}
|
||||
@@ -1676,7 +1661,7 @@ wordsplit_cmdexp (struct wordsplit *wsp)
|
||||
{
|
||||
struct wordsplit_node *next = p->next;
|
||||
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;
|
||||
p = next;
|
||||
}
|
||||
@@ -1765,7 +1750,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
|
||||
}
|
||||
--i;
|
||||
memcpy (uname, str + 1, i);
|
||||
uname[i] = 0;
|
||||
uname[i] = '\0';
|
||||
pw = getpwnam (uname);
|
||||
}
|
||||
else
|
||||
@@ -1786,7 +1771,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
|
||||
|
||||
memcpy (newstr, pw->pw_dir, dlen);
|
||||
memcpy (newstr + dlen, str + i + 1, slen - i - 1);
|
||||
newstr[size] = 0;
|
||||
newstr[size] = '\0';
|
||||
if (p->flags & _WSNF_WORD)
|
||||
free (p->v.word);
|
||||
p->v.word = newstr;
|
||||
@@ -1844,7 +1829,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
|
||||
if (!pattern)
|
||||
return _wsplt_nomem (wsp);
|
||||
memcpy (pattern, str, slen);
|
||||
pattern[slen] = 0;
|
||||
pattern[slen] = '\0';
|
||||
|
||||
switch (glob (pattern, flags, NULL, &g))
|
||||
{
|
||||
@@ -1900,7 +1885,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
|
||||
}
|
||||
newnode->v.word = newstr;
|
||||
newnode->flags |= _WSNF_WORD|_WSNF_QUOTE;
|
||||
wsnode_insert (wsp, newnode, prev, 0);
|
||||
wsnode_insert (wsp, newnode, prev);
|
||||
prev = newnode;
|
||||
}
|
||||
globfree (&g);
|
||||
@@ -1919,7 +1904,7 @@ skip_sed_expr (char const *command, idx_t i, idx_t len)
|
||||
|
||||
do
|
||||
{
|
||||
int delim;
|
||||
char delim;
|
||||
|
||||
if (command[i] == ';')
|
||||
i++;
|
||||
@@ -1969,7 +1954,7 @@ skip_delim_real (struct wordsplit *wsp)
|
||||
#define _WRDS_OK 1
|
||||
#define _WRDS_ERR 2
|
||||
|
||||
static int
|
||||
static bool
|
||||
scan_qstring (struct wordsplit *wsp, idx_t start, idx_t *end)
|
||||
{
|
||||
idx_t j;
|
||||
@@ -1985,26 +1970,26 @@ scan_qstring (struct wordsplit *wsp, idx_t start, idx_t *end)
|
||||
unsigned flags = _WSNF_QUOTE | _WSNF_EMPTYOK;
|
||||
if (q == '\'')
|
||||
flags |= _WSNF_NOEXPAND;
|
||||
if (wordsplit_add_segm (wsp, start + 1, j, flags))
|
||||
return _WRDS_ERR;
|
||||
if (!wordsplit_add_segm (wsp, start + 1, j, flags))
|
||||
return false;
|
||||
*end = j;
|
||||
}
|
||||
else
|
||||
{
|
||||
wsp->ws_endp = start;
|
||||
_wsplt_seterr (wsp, WRDSE_QUOTE);
|
||||
return _WRDS_ERR;
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
const char *command = wsp->ws_input;
|
||||
const char *comment = wsp->ws_comment;
|
||||
int join = 0;
|
||||
bool join = false;
|
||||
unsigned flags = 0;
|
||||
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;
|
||||
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;
|
||||
wsp->ws_endp = j;
|
||||
return _WRDS_OK;
|
||||
@@ -2054,12 +2039,12 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
||||
{
|
||||
if (join && wsp->ws_tail)
|
||||
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;
|
||||
if (scan_qstring (wsp, i, &i))
|
||||
if (!scan_qstring (wsp, i, &i))
|
||||
return _WRDS_ERR;
|
||||
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)
|
||||
&& command[i+1] == '{'
|
||||
&& find_closing_paren (command, i + 2, len, &i, "{}") == 0)
|
||||
&& !find_closing_paren (command, i + 2, len, &i, "{}"))
|
||||
continue;
|
||||
if (!(wsp->ws_flags & WRDSF_NOCMD)
|
||||
&& command[i+1] == '('
|
||||
&& find_closing_paren (command, i + 2, len, &i, "()") == 0)
|
||||
&& !find_closing_paren (command, i + 2, len, &i, "()"))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2091,7 +2076,7 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
||||
|
||||
if (join && i > start && wsp->ws_tail)
|
||||
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;
|
||||
wsp->ws_endp = i;
|
||||
if (wsp->ws_flags & WRDSF_INCREMENTAL)
|
||||
@@ -2112,11 +2097,17 @@ scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
|
||||
}
|
||||
|
||||
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 digit;
|
||||
@@ -2137,15 +2128,15 @@ xtonum (int *pval, const char *src, int base, int cnt)
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
*quote = 0;
|
||||
*quote = false;
|
||||
for (; *str; str++)
|
||||
{
|
||||
if (strchr (" \"", *str))
|
||||
*quote = 1;
|
||||
*quote = true;
|
||||
|
||||
if (*str == ' ')
|
||||
len++;
|
||||
@@ -2166,8 +2157,8 @@ wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote)
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
wsplt_unquote_char (const char *transtab, int c)
|
||||
static char
|
||||
wsplt_unquote_char (const char *transtab, char c)
|
||||
{
|
||||
while (*transtab && transtab[1])
|
||||
{
|
||||
@@ -2175,44 +2166,41 @@ wsplt_unquote_char (const char *transtab, int c)
|
||||
return *transtab;
|
||||
++transtab;
|
||||
}
|
||||
return 0;
|
||||
return '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
wsplt_quote_char (const char *transtab, int c)
|
||||
static char
|
||||
wsplt_quote_char (const char *transtab, char c)
|
||||
{
|
||||
for (; *transtab && transtab[1]; transtab += 2)
|
||||
{
|
||||
if (transtab[1] == c)
|
||||
return *transtab;
|
||||
}
|
||||
return 0;
|
||||
return '\0';
|
||||
}
|
||||
|
||||
int
|
||||
wordsplit_c_unquote_char (int c)
|
||||
char
|
||||
wordsplit_c_unquote_char (char c)
|
||||
{
|
||||
return wsplt_unquote_char (wordsplit_c_escape_tab, c);
|
||||
}
|
||||
|
||||
int
|
||||
wordsplit_c_quote_char (int c)
|
||||
char
|
||||
wordsplit_c_quote_char (char c)
|
||||
{
|
||||
return wsplt_quote_char (wordsplit_c_escape_tab, c);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
idx_t i = 0;
|
||||
int c;
|
||||
|
||||
inquote = !!inquote;
|
||||
while (i < n)
|
||||
for (idx_t i = 0; i < n; )
|
||||
{
|
||||
if (src[i] == '\\')
|
||||
{
|
||||
char c;
|
||||
++i;
|
||||
if (WRDSO_ESC_TEST (ws, inquote, WRDSO_XESC)
|
||||
&& (src[i] == 'x' || src[i] == 'X'))
|
||||
@@ -2224,8 +2212,7 @@ wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
|
||||
}
|
||||
else
|
||||
{
|
||||
int off = xtonum (&c, src + i + 1,
|
||||
16, 2);
|
||||
int off = xtonum (&c, src + i + 1, 16, 2);
|
||||
if (off == 0)
|
||||
{
|
||||
*dst++ = '\\';
|
||||
@@ -2276,11 +2263,11 @@ wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
|
||||
else
|
||||
*dst++ = src[i++];
|
||||
}
|
||||
*dst = 0;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
@@ -2304,7 +2291,7 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
|
||||
}
|
||||
else
|
||||
{
|
||||
int c = wordsplit_c_quote_char (*src);
|
||||
char c = wordsplit_c_quote_char (*src);
|
||||
*dst++ = '\\';
|
||||
if (c)
|
||||
*dst++ = c;
|
||||
@@ -2360,7 +2347,7 @@ static struct exptab exptab[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
static bool
|
||||
exptab_matches (struct exptab *p, struct wordsplit *wsp)
|
||||
{
|
||||
int result;
|
||||
@@ -2371,7 +2358,7 @@ exptab_matches (struct exptab *p, struct wordsplit *wsp)
|
||||
if (p->opt & EXPOPT_NEG)
|
||||
result = !result;
|
||||
|
||||
return result;
|
||||
return !!result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2389,14 +2376,14 @@ wordsplit_process_list (struct wordsplit *wsp, idx_t start)
|
||||
&& wsp->ws_wordi + 1 == wsp->ws_maxwords))
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
int rc;
|
||||
|
||||
while ((rc = scan_word (wsp, start, 0)) == _WRDS_OK)
|
||||
while ((rc = scan_word (wsp, start, false)) == _WRDS_OK)
|
||||
start = skip_delim (wsp);
|
||||
/* Make sure tail element is not joinable */
|
||||
if (wsp->ws_tail)
|
||||
|
||||
@@ -101,7 +101,8 @@ struct wordsplit
|
||||
idx_t ws_len; /* Length of ws_input. */
|
||||
idx_t ws_endp; /* Points past the last processed byte in
|
||||
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
|
||||
the error, if ws_errno is WRDSE_USERERR. Must
|
||||
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) */
|
||||
#define WRDSO_ESC_TEST(ws,q,f) ((ws)->ws_options & ((f) << 4*(q)))
|
||||
|
||||
/* Error codes. */
|
||||
#define WRDSE_OK 0
|
||||
#define WRDSE_EOF WRDSE_OK
|
||||
#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_c_unquote_char (int c);
|
||||
int wordsplit_c_quote_char (int c);
|
||||
idx_t wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote);
|
||||
void wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex);
|
||||
char wordsplit_c_unquote_char (char c);
|
||||
char wordsplit_c_quote_char (char c);
|
||||
idx_t wordsplit_c_quoted_length (const char *str, bool quote_hex, bool *quote);
|
||||
void wordsplit_c_quote_copy (char *dst, const char *src, bool quote_hex);
|
||||
|
||||
void wordsplit_perror (wordsplit_t *ws);
|
||||
const char *wordsplit_strerror (wordsplit_t *ws);
|
||||
|
||||
Reference in New Issue
Block a user