Prefer idx_t to size_t in wordsplit

* gnulib.modules: Add ialloc.
* lib/wordsplit.c: Include ialloc.h.
(PRINTMAX): New constant.
(printflen, printfdots): New functions.
(wordsplit_dump_nodes, expvar, wordsplit_process_list): Use them.
(_wsplt_subsplit, wordsplit_string_unquote_copy):
Don’t limit lengths to INT_MAX.
(wordsplit_run): Remove.  All callers changed to use wordsplit_len.
(wordsplit_perror): Don’t limit lengths to ULONG_MAX.
* lib/wordsplit.c (wordsplit_init, alloc_space, struct wordsplit_node)
(wsnode_len, wordsplit_add_segm, coalesce_segment, wsnode_quoteremoval)
(wordsplit_finish, wordsplit_append, node_split_prefix)
(find_closing_paren, wordsplit_find_env, wsplt_assign_var)
(expvar, node_expand, expcmd, wordsplit_trimws)
(wordsplit_tildexpand, isglob, wordsplit_pathexpand)
(skip_sed_expr, skip_delim_internal, skip_delim)
(skip_delim_real, scan_qstring, scan_word)
(wordsplit_c_quoted_length, wordsplit_process_list)
(wordsplit_len, wordsplit_free_words, wordsplit_get_words):
* lib/wordsplit.h (struct wordsplit):
Prefer idx_t to size_t for indexes.
* lib/wordsplit.h: Include idx.h.
This commit is contained in:
Paul Eggert
2024-08-03 11:47:13 -07:00
parent cc691f8272
commit 7cda31b1e0
5 changed files with 162 additions and 142 deletions

View File

@@ -62,6 +62,7 @@ gettime
gitlog-to-changelog
hash
human
ialloc
idx
intprops
inttostr

View File

@@ -31,6 +31,7 @@
#include <unistd.h>
#include <c-ctype.h>
#include <ialloc.h>
#if ENABLE_NLS
# include <gettext.h>
@@ -49,6 +50,27 @@
#define WSP_RETURN_DELIMS(wsp) \
((wsp)->ws_flags & WRDSF_RETURN_DELIMS || ((wsp)->ws_options & WRDSO_MAXWORDS))
/* When printing diagnostics with %.*s, output at most this many bytes.
Users typically don't want super-long strings in diagnostics,
and anyway printf fails if it outputs more than INT_MAX bytes.
printflen (LEN) returns LEN as an int, but at most PRINTMAX;
printfdots (LEN) returns "..." if LEN exceeds PRINTMAX, "" otherwise. */
enum { PRINTMAX = 10 * 1024 };
static int
printflen (idx_t len)
{
return len <= PRINTMAX ? len : PRINTMAX;
}
static char const *
printfdots (idx_t len)
{
return &"..."[3 * (len <= PRINTMAX)];
}
static void
_wsplt_alloc_die (struct wordsplit *wsp)
{
@@ -93,18 +115,14 @@ _wsplt_nomem (struct wordsplit *wsp)
return wsp->ws_errno;
}
static int wordsplit_run (const char *command, size_t length,
struct wordsplit *wsp,
unsigned flags, int lvl);
static int wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
unsigned flags);
static int wordsplit_process_list (struct wordsplit *wsp, size_t start);
static int wordsplit_init (struct wordsplit *wsp, char const *input,
idx_t len, unsigned flags);
static int wordsplit_process_list (struct wordsplit *wsp, idx_t start);
static int wordsplit_finish (struct wordsplit *wsp);
static int
_wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
char const *str, int len,
char const *str, idx_t len,
unsigned flags, int finalize)
{
int rc;
@@ -142,7 +160,7 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
rc = wordsplit_init (wss, str, len, flags);
if (rc)
return rc;
wss->ws_lvl = wsp->ws_lvl + 1;
wss->ws_lvl++;
rc = wordsplit_process_list (wss, 0);
if (rc)
{
@@ -193,7 +211,7 @@ wordsplit_init0 (struct wordsplit *wsp)
static char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
static int
wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
wordsplit_init (struct wordsplit *wsp, char const *input, idx_t len,
unsigned flags)
{
wsp->ws_flags = flags;
@@ -288,14 +306,14 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
}
static int
alloc_space (struct wordsplit *wsp, size_t count)
alloc_space (struct wordsplit *wsp, idx_t count)
{
size_t offs_plus_count;
idx_t offs_plus_count;
if (ckd_add (&offs_plus_count, count,
wsp->ws_flags & WRDSF_DOOFFS ? wsp->ws_offs : 0))
return _wsplt_nomem (wsp);
size_t wordn;
idx_t wordn;
char **wordv;
if (!wsp->ws_wordv)
@@ -311,14 +329,14 @@ alloc_space (struct wordsplit *wsp, size_t count)
}
else
{
size_t wordroom = wsp->ws_wordn - wsp->ws_wordc;
idx_t wordroom = wsp->ws_wordn - wsp->ws_wordc;
if (offs_plus_count <= wordroom)
return 0;
/* Grow the allocation by at least MININCR. To avoid quadratic
behavior, also grow it by at least 50% if possible. */
size_t minincr = offs_plus_count - wordroom;
size_t halfn = wsp->ws_wordn >> 1;
idx_t minincr = offs_plus_count - wordroom;
idx_t halfn = wsp->ws_wordn >> 1;
wordv = (halfn <= minincr || ckd_add (&wordn, wsp->ws_wordn, halfn)
? nullptr
: reallocarray (wsp->ws_wordv, wordn, sizeof *wordv));
@@ -358,8 +376,8 @@ struct wordsplit_node
{
struct
{
size_t beg; /* Start of word in ws_input */
size_t end; /* End of word in ws_input */
idx_t beg; /* Start of word in ws_input */
idx_t end; /* End of word in ws_input */
} segm;
char *word;
} v;
@@ -412,7 +430,7 @@ wsnode_ptr (struct wordsplit *wsp, struct wordsplit_node *p)
return wsp->ws_input + p->v.segm.beg;
}
static size_t
static idx_t
wsnode_len (struct wordsplit_node *p)
{
if (p->flags & _WSNF_NULL)
@@ -523,7 +541,7 @@ wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
}
static int
wordsplit_add_segm (struct wordsplit *wsp, size_t beg, size_t end, int flg)
wordsplit_add_segm (struct wordsplit *wsp, idx_t beg, idx_t end, int flg)
{
if (end == beg && !(flg & _WSNF_EMPTYOK))
return 0;
@@ -555,20 +573,23 @@ static void
wordsplit_dump_nodes (struct wordsplit *wsp)
{
struct wordsplit_node *p;
int n = 0;
intmax_t n = 0;
for (p = wsp->ws_head, n = 0; p; p = p->next, n++)
{
if (p->flags & _WSNF_WORD)
wsp->ws_debug ("(%02d) %4d: %p: %#04x (%s):%s;",
wsp->ws_debug ("(%02td) %4jd: %p: %#04x (%s):%s;",
wsp->ws_lvl,
n, p, p->flags, wsnode_flagstr (p->flags), p->v.word);
else
wsp->ws_debug ("(%02d) %4d: %p: %#04x (%s):%.*s;",
wsp->ws_lvl,
n, p, p->flags, wsnode_flagstr (p->flags),
(int) (p->v.segm.end - p->v.segm.beg),
wsp->ws_input + p->v.segm.beg);
{
idx_t seglen = p->v.segm.end - p->v.segm.beg;
wsp->ws_debug ("(%02td) %4jd: %p: %#04x (%s):%.*s%s;",
wsp->ws_lvl,
n, p, p->flags, wsnode_flagstr (p->flags),
printflen (seglen), wsp->ws_input + p->v.segm.beg,
printfdots (seglen));
}
}
}
@@ -576,7 +597,7 @@ static int
coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
{
struct wordsplit_node *p, *end;
size_t len = 0;
idx_t len = 0;
char *buf, *cur;
if (!(node->flags & _WSNF_JOIN))
@@ -590,7 +611,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
len += wsnode_len (p);
end = p;
buf = malloc (len + 1);
buf = imalloc (len + 1);
if (!buf)
return _wsplt_nomem (wsp);
cur = buf;
@@ -600,7 +621,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
{
struct wordsplit_node *next = p->next;
const char *str = wsnode_ptr (wsp, p);
size_t slen = wsnode_len (p);
idx_t slen = wsnode_len (p);
memcpy (cur, str, slen);
cur += slen;
@@ -633,7 +654,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
static void wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
char *dst, const char *src,
size_t n);
idx_t n);
static int
wsnode_quoteremoval (struct wordsplit *wsp)
@@ -643,7 +664,7 @@ wsnode_quoteremoval (struct wordsplit *wsp)
for (p = wsp->ws_head; p; p = p->next)
{
const char *str = wsnode_ptr (wsp, p);
size_t slen = wsnode_len (p);
idx_t slen = wsnode_len (p);
int unquote;
if (wsp->ws_flags & WRDSF_QUOTE)
@@ -655,7 +676,7 @@ wsnode_quoteremoval (struct wordsplit *wsp)
{
if (!(p->flags & _WSNF_WORD))
{
char *newstr = malloc (slen + 1);
char *newstr = imalloc (slen + 1);
if (!newstr)
return _wsplt_nomem (wsp);
memcpy (newstr, str, slen);
@@ -702,13 +723,13 @@ wsnode_tail_coalesce (struct wordsplit *wsp, struct wordsplit_node *p)
return 0;
}
static size_t skip_delim (struct wordsplit *wsp);
static idx_t skip_delim (struct wordsplit *wsp);
static int
wordsplit_finish (struct wordsplit *wsp)
{
struct wordsplit_node *p;
size_t n;
idx_t n;
int delim;
/* Postprocess delimiters. It would be rather simple, if it weren't for
@@ -839,8 +860,8 @@ wordsplit_finish (struct wordsplit *wsp)
while (wsp->ws_head)
{
const char *str = wsnode_ptr (wsp, wsp->ws_head);
size_t slen = wsnode_len (wsp->ws_head);
char *newstr = malloc (slen + 1);
idx_t slen = wsnode_len (wsp->ws_head);
char *newstr = imalloc (slen + 1);
/* Assign newstr first, even if it is NULL. This way
wordsplit_free will work even if we return
@@ -867,7 +888,7 @@ int
wordsplit_append (wordsplit_t *wsp, int argc, char **argv)
{
int rc;
size_t i;
idx_t i;
rc = alloc_space (wsp, wsp->ws_wordc + argc + 1);
if (rc)
@@ -897,9 +918,8 @@ static int
node_split_prefix (struct wordsplit *wsp,
struct wordsplit_node **ptail,
struct wordsplit_node *node,
size_t beg, size_t len, int flg)
idx_t beg, idx_t len, int flg)
{
if (len == 0)
return 0;
struct wordsplit_node *newnode = wsnode_new (wsp);
@@ -909,7 +929,7 @@ node_split_prefix (struct wordsplit *wsp,
if (node->flags & _WSNF_WORD)
{
const char *str = wsnode_ptr (wsp, node);
char *newstr = malloc (len + 1);
char *newstr = imalloc (len + 1);
if (!newstr)
return _wsplt_nomem (wsp);
memcpy (newstr, str + beg, len);
@@ -928,11 +948,11 @@ node_split_prefix (struct wordsplit *wsp,
}
static int
find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
find_closing_paren (char const *str, idx_t i, idx_t len, idx_t *poff,
char const *paren)
{
enum { st_init, st_squote, st_dquote } state = st_init;
size_t level = 1;
idx_t level = 1;
for (; i < len; i++)
{
@@ -985,10 +1005,10 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
}
static int
wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
wordsplit_find_env (struct wordsplit *wsp, char const *name, idx_t len,
char const **ret)
{
size_t i;
idx_t i;
if (!(wsp->ws_flags & WRDSF_ENV))
return WRDSE_UNDEF;
@@ -998,7 +1018,7 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
/* A key-value pair environment */
for (i = 0; wsp->ws_env[i]; i++)
{
size_t elen = strlen (wsp->ws_env[i]);
idx_t elen = strlen (wsp->ws_env[i]);
if (elen == len && memcmp (wsp->ws_env[i], name, elen) == 0)
{
*ret = wsp->ws_env[i + 1];
@@ -1015,7 +1035,7 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
/* Usual (A=B) environment. */
for (i = 0; wsp->ws_env[i]; i++)
{
size_t j;
idx_t j;
const char *var = wsp->ws_env[i];
for (j = 0; j < len; j++)
@@ -1032,7 +1052,7 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
}
static int
wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
wsplt_assign_var (struct wordsplit *wsp, char const *name, idx_t namelen,
char *value)
{
int n = (wsp->ws_flags & WRDSF_ENV_KV) ? 2 : 1;
@@ -1040,14 +1060,14 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
if (wsp->ws_envidx + n >= wsp->ws_envsiz)
{
size_t sz;
idx_t sz;
char **newenv;
if (!wsp->ws_envbuf)
{
if (wsp->ws_flags & WRDSF_ENV)
{
size_t i = 0, j;
idx_t i = 0, j;
if (wsp->ws_env)
{
@@ -1108,7 +1128,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
if (wsp->ws_flags & WRDSF_ENV_KV)
{
/* A key-value pair environment */
char *p = malloc (namelen + 1);
char *p = imalloc (namelen + 1);
if (!p)
return _wsplt_nomem (wsp);
memcpy (p, name, namelen);
@@ -1125,7 +1145,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
}
else
{
v = malloc (namelen + strlen (value) + 2);
v = imalloc (namelen + strlen (value) + 2);
if (!v)
return _wsplt_nomem (wsp);
memcpy (v, name, namelen);
@@ -1138,10 +1158,10 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
}
static int
expvar (struct wordsplit *wsp, const char *str, size_t len,
expvar (struct wordsplit *wsp, char const *str, idx_t len,
struct wordsplit_node **ptail, const char **pend, unsigned flg)
{
size_t i = 0;
idx_t i = 0;
const char *defstr = NULL;
char *value;
const char *vptr;
@@ -1165,7 +1185,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
{
if (str[i] == ':')
{
size_t j;
idx_t j;
defstr = str + i + 1;
if (find_closing_paren (str, i + 1, len, &j, "{}"))
@@ -1181,7 +1201,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else if (str[i] && strchr ("-+?=", str[i]))
{
size_t j;
idx_t j;
defstr = str + i;
if (find_closing_paren (str, i, len, &j, "{}"))
@@ -1254,7 +1274,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
case WRDSE_OK:
if (defstr && *defstr == '+')
{
size_t size = *pend - ++defstr;
idx_t size = *pend - ++defstr;
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
@@ -1272,7 +1292,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
case WRDSE_UNDEF:
if (defstr)
{
size_t size;
idx_t size;
if (*defstr == '-' || *defstr == '=')
{
size = *pend - ++defstr;
@@ -1298,8 +1318,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
{
size = *pend - ++defstr;
if (size == 0)
wsp->ws_error (_("%.*s: variable null or not set"),
(int) i, str);
wsp->ws_error (_("%.*s%s: variable null or not set"),
printflen (i), str, printfdots (i));
else
{
rc = _wsplt_subsplit (wsp, &ws, defstr, size,
@@ -1309,11 +1329,14 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
(WRDSF_NOVAR | WRDSF_NOCMD)),
1);
if (rc == 0)
wsp->ws_error ("%.*s: %s",
(int) i, str, ws.ws_wordv[0]);
wsp->ws_error ("%.*s%s: %s",
printflen (i), str, printfdots (i),
ws.ws_wordv[0]);
else
wsp->ws_error ("%.*s: %.*s",
(int) i, str, (int) size, defstr);
wsp->ws_error ("%.*s%s: %.*s%s",
printflen (i), str, printfdots (i),
printflen (size), defstr,
printfdots (size));
wordsplit_free (&ws);
}
}
@@ -1328,8 +1351,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
else
{
if (wsp->ws_flags & WRDSF_WARNUNDEF)
wsp->ws_error (_("warning: undefined variable `%.*s'"),
(int) i, str);
wsp->ws_error (_("warning: undefined variable '%.*s%s'"),
printflen (i), str, printfdots (i));
if (wsp->ws_flags & WRDSF_KEEPUNDEF)
value = NULL;
else
@@ -1405,7 +1428,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else if (wsp->ws_flags & WRDSF_KEEPUNDEF)
{
size_t size = *pend - start + 1;
idx_t size = *pend - start + 1;
newnode = wsnode_new (wsp);
if (!newnode)
@@ -1441,16 +1464,16 @@ static int
node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
int (*beg_p) (int),
int (*ws_exp_fn) (struct wordsplit *wsp,
const char *str, size_t len,
char const *str, idx_t len,
struct wordsplit_node **ptail,
const char **pend,
unsigned flg))
{
const char *str = wsnode_ptr (wsp, node);
size_t slen = wsnode_len (node);
idx_t slen = wsnode_len (node);
const char *end = str + slen;
const char *p;
size_t off = 0;
idx_t off = 0;
struct wordsplit_node *tail = node;
for (p = str; p < end; p++)
@@ -1462,7 +1485,7 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
}
if (*p == '$' && beg_p (p[1]))
{
size_t n = p - str;
idx_t n = p - str;
if (tail != node)
tail->flags |= _WSNF_JOIN;
@@ -1537,11 +1560,11 @@ begin_cmd_p (int c)
}
static int
expcmd (struct wordsplit *wsp, const char *str, size_t len,
expcmd (struct wordsplit *wsp, char const *str, idx_t len,
struct wordsplit_node **ptail, const char **pend, unsigned flg)
{
int rc;
size_t j;
idx_t j;
char *value;
struct wordsplit_node *newnode;
@@ -1672,7 +1695,7 @@ wordsplit_trimws (struct wordsplit *wsp)
for (p = wsp->ws_head; p; p = p->next)
{
size_t n;
idx_t n;
if (!(p->flags & _WSNF_QUOTE))
{
@@ -1706,7 +1729,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
{
struct wordsplit_node *p;
char *uname = NULL;
size_t usize = 0;
idx_t usize = 0;
for (p = wsp->ws_head; p; p = p->next)
{
@@ -1718,8 +1741,8 @@ wordsplit_tildexpand (struct wordsplit *wsp)
str = wsnode_ptr (wsp, p);
if (str[0] == '~')
{
size_t i, size, dlen;
size_t slen = wsnode_len (p);
idx_t i, size, dlen;
idx_t slen = wsnode_len (p);
struct passwd *pw;
char *newstr;
@@ -1775,9 +1798,9 @@ wordsplit_tildexpand (struct wordsplit *wsp)
}
static bool
isglob (char const *s, size_t l)
isglob (char const *s, idx_t l)
{
while (l--)
for (ptrdiff_t i = l; i--; )
{
char c = *s++;
if (c && strchr ("*?[", c))
@@ -1790,7 +1813,7 @@ static int
wordsplit_pathexpand (struct wordsplit *wsp)
{
struct wordsplit_node *p, *next;
size_t slen;
idx_t slen;
int flags = 0;
#ifdef GLOB_PERIOD
@@ -1890,7 +1913,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
}
static int
skip_sed_expr (const char *command, size_t i, size_t len)
skip_sed_expr (char const *command, idx_t i, idx_t len)
{
int state;
@@ -1924,22 +1947,22 @@ skip_sed_expr (const char *command, size_t i, size_t len)
/* wsp->ws_endp points to a delimiter character. If RETURN_DELIMS
is true, return its value, otherwise return the index past it. */
static size_t
skip_delim_internal (struct wordsplit *wsp, int return_delims)
static idx_t
skip_delim_internal (struct wordsplit *wsp, bool return_delims)
{
return return_delims ? wsp->ws_endp : wsp->ws_endp + 1;
return wsp->ws_endp + !return_delims;
}
static size_t
static idx_t
skip_delim (struct wordsplit *wsp)
{
return skip_delim_internal (wsp, WSP_RETURN_DELIMS (wsp));
}
static size_t
static idx_t
skip_delim_real (struct wordsplit *wsp)
{
return skip_delim_internal (wsp, wsp->ws_flags & WRDSF_RETURN_DELIMS);
return skip_delim_internal (wsp, !!(wsp->ws_flags & WRDSF_RETURN_DELIMS));
}
#define _WRDS_EOF 0
@@ -1947,11 +1970,11 @@ skip_delim_real (struct wordsplit *wsp)
#define _WRDS_ERR 2
static int
scan_qstring (struct wordsplit *wsp, size_t start, size_t *end)
scan_qstring (struct wordsplit *wsp, idx_t start, idx_t *end)
{
size_t j;
idx_t j;
const char *command = wsp->ws_input;
size_t len = wsp->ws_len;
idx_t len = wsp->ws_len;
char q = command[start];
for (j = start + 1; j < len && command[j] != q; j++)
@@ -1976,16 +1999,16 @@ scan_qstring (struct wordsplit *wsp, size_t start, size_t *end)
}
static int
scan_word (struct wordsplit *wsp, size_t start, int consume_all)
scan_word (struct wordsplit *wsp, idx_t start, int consume_all)
{
size_t len = wsp->ws_len;
idx_t len = wsp->ws_len;
const char *command = wsp->ws_input;
const char *comment = wsp->ws_comment;
int join = 0;
unsigned flags = 0;
struct wordsplit_node *np = wsp->ws_tail;
size_t i = start;
idx_t i = start;
if (i >= len)
{
@@ -2007,7 +2030,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all)
{
if (comment && command[i] && strchr (comment, command[i]) != NULL)
{
size_t j;
idx_t j;
for (j = i + 1; j < len && command[j] != '\n'; j++)
;
if (wordsplit_add_segm (wsp, start, i, 0))
@@ -2113,10 +2136,10 @@ xtonum (int *pval, const char *src, int base, int cnt)
return i;
}
size_t
idx_t
wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote)
{
size_t len = 0;
idx_t len = 0;
*quote = 0;
for (; *str; str++)
@@ -2180,9 +2203,9 @@ wordsplit_c_quote_char (int c)
void
wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
char *dst, const char *src, size_t n)
char *dst, char const *src, idx_t n)
{
int i = 0;
idx_t i = 0;
int c;
inquote = !!inquote;
@@ -2274,7 +2297,8 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
if (quote_hex)
{
snprintf (tmp, sizeof tmp, "%%%02X", *(unsigned char *) src);
unsigned char c = *src;
snprintf (tmp, sizeof tmp, "%%%02X", c);
memcpy (dst, tmp, 3);
dst += 3;
}
@@ -2286,7 +2310,8 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
*dst++ = c;
else
{
snprintf (tmp, sizeof tmp, "%03o", *(unsigned char *) src);
unsigned char ch = *src;
snprintf (tmp, sizeof tmp, "%03o", ch);
memcpy (dst, tmp, 3);
dst += 3;
}
@@ -2350,13 +2375,14 @@ exptab_matches (struct exptab *p, struct wordsplit *wsp)
}
static int
wordsplit_process_list (struct wordsplit *wsp, size_t start)
wordsplit_process_list (struct wordsplit *wsp, idx_t start)
{
struct exptab *p;
if (wsp->ws_flags & WRDSF_SHOWDBG)
wsp->ws_debug (_("(%02d) Input:%.*s;"),
wsp->ws_lvl, (int) wsp->ws_len, wsp->ws_input);
wsp->ws_debug (_("(%02td) Input:%.*s%s;"),
wsp->ws_lvl, printflen (wsp->ws_len), wsp->ws_input,
printfdots (wsp->ws_len));
if ((wsp->ws_flags & WRDSF_NOSPLIT)
|| ((wsp->ws_options & WRDSO_MAXWORDS)
@@ -2381,7 +2407,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("(%02d) %s", wsp->ws_lvl, _("Initial list:"));
wsp->ws_debug ("(%02td) %s", wsp->ws_lvl, _("Initial list:"));
wordsplit_dump_nodes (wsp);
}
@@ -2395,7 +2421,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
break;
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("(%02d) %s", wsp->ws_lvl,
wsp->ws_debug ("(%02td) %s", wsp->ws_lvl,
_("Coalesced list:"));
wordsplit_dump_nodes (wsp);
}
@@ -2406,7 +2432,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
break;
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("(%02d) %s", wsp->ws_lvl, _(p->descr));
wsp->ws_debug ("(%02td) %s", wsp->ws_lvl, _(p->descr));
wordsplit_dump_nodes (wsp);
}
}
@@ -2415,12 +2441,12 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
return wsp->ws_errno;
}
static int
wordsplit_run (const char *command, size_t length, struct wordsplit *wsp,
unsigned flags, int lvl)
int
wordsplit_len (char const *command, idx_t length, struct wordsplit *wsp,
unsigned flags)
{
int rc;
size_t start;
idx_t start;
if (!command)
{
@@ -2443,7 +2469,7 @@ wordsplit_run (const char *command, size_t length, struct wordsplit *wsp,
rc = wordsplit_init (wsp, command, length, flags);
if (rc)
return rc;
wsp->ws_lvl = lvl;
wsp->ws_lvl = 0;
}
rc = wordsplit_process_list (wsp, start);
@@ -2452,13 +2478,6 @@ wordsplit_run (const char *command, size_t length, struct wordsplit *wsp,
return wordsplit_finish (wsp);
}
int
wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
unsigned flags)
{
return wordsplit_run (command, length, wsp, flags, 0);
}
int
wordsplit (const char *command, struct wordsplit *ws, unsigned flags)
{
@@ -2468,7 +2487,7 @@ wordsplit (const char *command, struct wordsplit *ws, unsigned flags)
void
wordsplit_free_words (struct wordsplit *ws)
{
size_t i;
idx_t i;
for (i = 0; i < ws->ws_wordc; i++)
{
@@ -2489,7 +2508,7 @@ wordsplit_free_envbuf (struct wordsplit *ws)
return;
if (ws->ws_envbuf)
{
size_t i;
idx_t i;
for (i = 0; ws->ws_envbuf[i]; i++)
free (ws->ws_envbuf[i]);
@@ -2519,7 +2538,7 @@ wordsplit_free (struct wordsplit *ws)
}
int
wordsplit_get_words (struct wordsplit *ws, size_t *wordc, char ***wordv)
wordsplit_get_words (struct wordsplit *ws, idx_t *wordc, char ***wordv)
{
/* Tell the memory manager that ws->ws_wordv can be shrunk. */
char **p = realloc (ws->ws_wordv,
@@ -2565,9 +2584,9 @@ wordsplit_perror (struct wordsplit *wsp)
switch (wsp->ws_errno)
{
case WRDSE_QUOTE:
wsp->ws_error (_("missing closing %c (start near #%lu)"),
wsp->ws_error (_("missing closing %c (start near #%td)"),
wsp->ws_input[wsp->ws_endp],
(unsigned long) wsp->ws_endp);
wsp->ws_endp);
break;
default:

View File

@@ -19,6 +19,7 @@
#include <stddef.h>
#include <attribute.h>
#include <idx.h>
typedef struct wordsplit wordsplit_t;
@@ -36,17 +37,17 @@ typedef struct wordsplit wordsplit_t;
default value upon entry to wordsplit(). */
struct wordsplit
{
size_t ws_wordc; /* [Output] Number of words in ws_wordv. */
idx_t ws_wordc; /* [Output] Number of words in ws_wordv. */
char **ws_wordv; /* [Output] Array of parsed out words. */
size_t ws_offs; /* [Input] (WRDSF_DOOFFS) Number of initial
idx_t ws_offs; /* [Input] (WRDSF_DOOFFS) Number of initial
elements in ws_wordv to fill with NULLs. */
size_t ws_wordn; /* Number of elements ws_wordv can accommodate. */
idx_t ws_wordn; /* Number of elements ws_wordv can accommodate. */
unsigned ws_flags; /* [Input] Flags passed to wordsplit. */
unsigned ws_options; /* [Input] (WRDSF_OPTIONS)
Additional options. */
size_t ws_maxwords; /* [Input] (WRDSO_MAXWORDS) Return at most that
idx_t ws_maxwords; /* [Input] (WRDSO_MAXWORDS) Return at most that
many words */
size_t ws_wordi; /* [Output] (WRDSF_INCREMENTAL) Total number of
idx_t ws_wordi; /* [Output] (WRDSF_INCREMENTAL) Total number of
words returned so far */
const char *ws_delim; /* [Input] (WRDSF_DELIM) Word delimiters. */
@@ -68,10 +69,10 @@ struct wordsplit
environment variables. */
char **ws_envbuf;
size_t ws_envidx;
size_t ws_envsiz;
idx_t ws_envidx;
idx_t ws_envsiz;
int (*ws_getvar) (char **ret, const char *var, size_t len, void *clos);
int (*ws_getvar) (char **ret, const char *var, idx_t len, void *clos);
/* [Input] (WRDSF_GETVAR, !WRDSF_NOVAR) Looks up
the name VAR (LEN bytes long) in the table of
variables and if found returns in memory
@@ -85,7 +86,7 @@ struct wordsplit
using malloc(3). */
void *ws_closure; /* [Input] (WRDSF_CLOSURE) Passed as the CLOS
argument to ws_getvar and ws_command. */
int (*ws_command) (char **ret, const char *cmd, size_t len, char **argv,
int (*ws_command) (char **ret, const char *cmd, idx_t len, char **argv,
void *clos);
/* [Input] (!WRDSF_NOCMD) Returns in the memory
location pointed to by RET the expansion of
@@ -97,8 +98,8 @@ struct wordsplit
return values. */
const char *ws_input; /* Input string (the S argument to wordsplit. */
size_t ws_len; /* Length of ws_input. */
size_t ws_endp; /* Points past the last processed byte in
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. */
char *ws_usererr; /* Points to textual description of
@@ -106,7 +107,7 @@ struct wordsplit
be allocated with malloc(3). */
struct wordsplit_node *ws_head, *ws_tail;
/* Doubly-linked list of parsed out nodes. */
int ws_lvl; /* Invocation nesting level. */
idx_t ws_lvl; /* Invocation nesting level. */
};
/* Initial size for ws_env, if allocated automatically */
@@ -242,17 +243,17 @@ struct wordsplit
#define WRDSE_USERERR 9
int wordsplit (const char *s, wordsplit_t *ws, unsigned flags);
int wordsplit_len (const char *s, size_t len, wordsplit_t *ws, unsigned flags);
int wordsplit_len (const char *s, idx_t len, wordsplit_t *ws, unsigned flags);
void wordsplit_free (wordsplit_t *ws);
void wordsplit_free_words (wordsplit_t *ws);
void wordsplit_free_envbuf (wordsplit_t *ws);
int wordsplit_get_words (wordsplit_t *ws, size_t *wordc, char ***wordv);
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);
size_t wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote);
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);
void wordsplit_perror (wordsplit_t *ws);

View File

@@ -204,13 +204,12 @@ cvs_addfn (struct exclude *ex, char const *pattern, int options,
MAYBE_UNUSED void *data)
{
struct wordsplit ws;
size_t i;
options |= EXCLUDE_ALLOC;
if (wordsplit (pattern, &ws,
WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS))
return;
for (i = 0; i < ws.ws_wordc; i++)
for (idx_t i = 0; i < ws.ws_wordc; i++)
add_exclude (ex, ws.ws_wordv[i], options);
wordsplit_free (&ws);
}

View File

@@ -526,8 +526,8 @@ run_decompress_program (void)
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
p, wordsplit_strerror (&ws)));
wsflags |= WRDSF_REUSE;
memmove(ws.ws_wordv, ws.ws_wordv + ws.ws_offs,
sizeof(ws.ws_wordv[0])*ws.ws_wordc);
memmove (ws.ws_wordv, ws.ws_wordv + ws.ws_offs,
ws.ws_wordc * sizeof *ws.ws_wordv);
ws.ws_wordv[ws.ws_wordc] = (char *) "-d";
prog = p;
execvp (ws.ws_wordv[0], ws.ws_wordv);