#include <errno.h>
#include <glob.h>
+#include <limits.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdckdint.h>
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;
wordsplit_init0 (wsp);
- return 0;
+ return WRDSE_OK;
}
static int
{
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. */
return _wsplt_nomem (wsp);
wsp->ws_wordn = wordn;
wsp->ws_wordv = wordv;
- return 0;
+ return WRDSE_OK;
}
\f
*p++ = 'd';
else
*p++ = '-';
- *p = 0;
+ *p = '\0';
return retbuf;
}
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;
}
}
-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
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;",
char *buf, *cur;
if (!(node->flags & _WSNF_JOIN))
- return 0;
+ return WRDSE_OK;
for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next)
{
p = next;
}
- *cur = 0;
+ *cur = '\0';
node->flags &= ~_WSNF_JOIN;
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);
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;
{
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)
np = np->next;
}
if (coalesce_segment (wsp, p))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static idx_t skip_delim (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.
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 */
}
else
{
- delim = 0;
+ delim = '\0';
n++; /* Count this node; it will be returned */
}
}
/* 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)
{
if (!newstr)
return _wsplt_nomem (wsp);
memcpy (newstr, str, slen);
- newstr[slen] = 0;
+ newstr[slen] = '\0';
wsnode_remove (wsp, wsp->ws_head);
break;
}
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
- return 0;
+ return WRDSE_OK;
}
\f
int
}
wsp->ws_wordc += i;
wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
- return 0;
+ return WRDSE_OK;
}
\f
/* Variable expansion */
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);
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;
}
return 0;
}
-static int
+static bool
find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
char const *paren)
{
if (--level == 0)
{
*poff = i;
- return 0;
+ return false;
}
break;
}
break;
}
}
- return 1;
+ return true;
}
static int
if (!p)
return _wsplt_nomem (wsp);
memcpy (p, name, namelen);
- p[namelen] = 0;
+ p[namelen] = '\0';
v = strdup (value);
if (!v)
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);
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;
}
rc = WRDSE_UNDEF;
if (rc == WRDSE_OK
- && (!value || value[0] == 0)
+ && !(value && *value)
&& defstr && defstr[-1] == ':')
{
free (value);
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);
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
(wsp->ws_flags &
(WRDSF_NOVAR | WRDSF_NOCMD)),
- 1);
+ true);
if (rc)
return rc;
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),
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;
}
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)
{
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);
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,
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;
}
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 */
{
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;
}
return 0;
}
\f
-static int
-begin_cmd_p (int c)
+static bool
+begin_cmd_p (char c)
{
return c == '(';
}
{
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);
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;
}
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)
{
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);
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;
}
{
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;
}
}
--i;
memcpy (uname, str + 1, i);
- uname[i] = 0;
+ uname[i] = '\0';
pw = getpwnam (uname);
}
else
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;
if (!pattern)
return _wsplt_nomem (wsp);
memcpy (pattern, str, slen);
- pattern[slen] = 0;
+ pattern[slen] = '\0';
switch (glob (pattern, flags, NULL, &g))
{
}
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);
do
{
- int delim;
+ char delim;
if (command[i] == ';')
i++;
#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;
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;
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;
{
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;
}
}
{
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;
}
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)
}
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;
+
+ /* 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; i++)
+ for (i = 0; i < cnt && val <= max_prefix; i++)
{
unsigned char c = src[i];
unsigned char digit;
}
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++;
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])
{
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'))
}
else
{
- int off = xtonum (&c, src + i + 1,
- 16, 2);
+ int off = xtonum (&c, src + i + 1, 16, 2);
if (off == 0)
{
*dst++ = '\\';
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++)
{
}
else
{
- int c = wordsplit_c_quote_char (*src);
+ char c = wordsplit_c_quote_char (*src);
*dst++ = '\\';
if (c)
*dst++ = c;
{ NULL }
};
-static int
+static bool
exptab_matches (struct exptab *p, struct wordsplit *wsp)
{
int result;
if (p->opt & EXPOPT_NEG)
result = !result;
- return result;
+ return !!result;
}
static int
&& 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)