From: Paul Eggert Date: Sat, 3 Aug 2024 21:53:39 +0000 (-0700) Subject: More wordsplit int cleanup X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0ab451a420bcdabb35b8dd3fd461fa540ff16309;p=thirdparty%2Ftar.git 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". --- diff --git a/lib/wordsplit.c b/lib/wordsplit.c index ae1781ea..d6b33af8 100644 --- a/lib/wordsplit.c +++ b/lib/wordsplit.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -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; + + /* 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; @@ -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) diff --git a/lib/wordsplit.h b/lib/wordsplit.h index fc6d2fda..4640d34c 100644 --- a/lib/wordsplit.h +++ b/lib/wordsplit.h @@ -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);