diff options
Diffstat (limited to 'lib/wordsplit.c')
-rw-r--r-- | lib/wordsplit.c | 141 |
1 files changed, 72 insertions, 69 deletions
diff --git a/lib/wordsplit.c b/lib/wordsplit.c index 661a4f8b..28390c5b 100644 --- a/lib/wordsplit.c +++ b/lib/wordsplit.c @@ -95,7 +95,7 @@ _wsplt_seterr (struct wordsplit *wsp, int ec) wordsplit_perror (wsp); return ec; } - + static int _wsplt_nomem (struct wordsplit *wsp) { @@ -126,7 +126,7 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss, unsigned flags, int finalize) { int rc; - + wss->ws_delim = wsp->ws_delim; wss->ws_debug = wsp->ws_debug; wss->ws_error = wsp->ws_error; @@ -150,7 +150,7 @@ _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss, } wss->ws_options = wsp->ws_options; - + flags |= WRDSF_DELIM | WRDSF_ALLOC_DIE | WRDSF_ERROR @@ -209,7 +209,7 @@ wordsplit_init0 (struct wordsplit *wsp) } 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, unsigned flags) @@ -282,7 +282,7 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, { wsp->ws_escape[WRDSX_WORD] = wordsplit_c_escape_tab; wsp->ws_escape[WRDSX_QUOTE] = wordsplit_c_escape_tab; - wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD + wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD | WRDSO_XESC_QUOTE | WRDSO_XESC_WORD; } else @@ -292,16 +292,16 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len, wsp->ws_options |= WRDSO_BSKEEP_QUOTE; } } - + wsp->ws_endp = 0; wsp->ws_wordi = 0; if (wsp->ws_flags & WRDSF_REUSE) wordsplit_free_nodes (wsp); wsp->ws_head = wsp->ws_tail = NULL; - + wordsplit_init0 (wsp); - + return 0; } @@ -424,14 +424,13 @@ wsnode_len (struct wordsplit_node *p) return p->v.segm.end - p->v.segm.beg; } -static int -wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode) +static struct wordsplit_node * +wsnode_new (struct wordsplit *wsp) { struct wordsplit_node *node = calloc (1, sizeof (*node)); if (!node) - return _wsplt_nomem (wsp); - *pnode = node; - return 0; + _wsplt_nomem (wsp); + return node; } static void @@ -527,14 +526,11 @@ 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) { - struct wordsplit_node *node; - int rc; - if (end == beg && !(flg & _WSNF_EMPTYOK)) return 0; - rc = wsnode_new (wsp, &node); - if (rc) - return rc; + struct wordsplit_node *node = wsnode_new (wsp); + if (!node) + return 1; node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK); node->v.segm.beg = beg; node->v.segm.end = end; @@ -587,7 +583,7 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node) if (!(node->flags & _WSNF_JOIN)) return 0; - + for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next) { len += wsnode_len (p); @@ -717,7 +713,7 @@ wordsplit_finish (struct wordsplit *wsp) Nodes of type _WSNF_DELIM get inserted to the node list if either WRDSF_RETURN_DELIMS flag or WRDSO_MAXWORDS option is set. - + The following cases should be distinguished: 1. If both WRDSF_SQUEEZE_DELIMS and WRDSF_RETURN_DELIMS are set, compress @@ -781,7 +777,7 @@ wordsplit_finish (struct wordsplit *wsp) continue; } } - else + else { if (delim) { @@ -900,11 +896,11 @@ node_split_prefix (struct wordsplit *wsp, struct wordsplit_node *node, size_t beg, size_t len, int flg) { - struct wordsplit_node *newnode; if (len == 0) return 0; - if (wsnode_new (wsp, &newnode)) + struct wordsplit_node *newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); if (node->flags & _WSNF_WORD) @@ -958,7 +954,7 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff, break; } break; - + case '"': state = st_dquote; break; @@ -1038,7 +1034,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, { int n = (wsp->ws_flags & WRDSF_ENV_KV) ? 2 : 1; char *v; - + if (wsp->ws_envidx + n >= wsp->ws_envsiz) { size_t sz; @@ -1055,7 +1051,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, for (; wsp->ws_env[i]; i++) ; } - + sz = i + n + 1; newenv = calloc (sz, sizeof(newenv[0])); @@ -1075,7 +1071,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, } } newenv[j] = NULL; - + wsp->ws_envbuf = newenv; wsp->ws_envidx = i; wsp->ws_envsiz = sz; @@ -1104,7 +1100,7 @@ wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, wsp->ws_env = (const char**) wsp->ws_envbuf; } } - + if (wsp->ws_flags & WRDSF_ENV_KV) { /* A key-value pair environment */ @@ -1149,7 +1145,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, const char *start = str - 1; int rc; struct wordsplit ws; - + if (ISVARBEG (str[0])) { for (i = 1; i < len; i++) @@ -1166,7 +1162,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, if (str[i] == ':') { size_t j; - + defstr = str + i + 1; if (find_closing_paren (str, i + 1, len, &j, "{}")) return _wsplt_seterr (wsp, WRDSE_CBRACE); @@ -1182,7 +1178,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, else if (strchr ("-+?=", str[i])) { size_t j; - + defstr = str + i; if (find_closing_paren (str, i, len, &j, "{}")) return _wsplt_seterr (wsp, WRDSE_CBRACE); @@ -1195,7 +1191,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, } else { - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); *ptail = newnode; @@ -1247,7 +1244,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, rc = WRDSE_UNDEF; } } - + switch (rc) { case WRDSE_OK: @@ -1267,7 +1264,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, wordsplit_free (&ws); } break; - + case WRDSE_UNDEF: if (defstr) { @@ -1287,11 +1284,11 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, value = ws.ws_wordv[0]; ws.ws_wordv[0] = NULL; wordsplit_free (&ws); - + if (defstr[-1] == '=') wsplt_assign_var (wsp, str, i, value); } - else + else { if (*defstr == '?') { @@ -1339,7 +1336,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, } } break; - + case WRDSE_NOSPACE: return _wsplt_nomem (wsp); @@ -1357,7 +1354,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, { if (flg & _WSNF_QUOTE) { - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) { free (value); return 1; @@ -1371,7 +1369,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, { free (value); /* Empty string is a special case */ - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); *ptail = newnode; @@ -1381,7 +1380,7 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, { struct wordsplit ws; int rc; - + rc = _wsplt_subsplit (wsp, &ws, value, strlen (value), WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_QUOTE @@ -1404,7 +1403,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, { size_t size = *pend - start + 1; - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); *ptail = newnode; @@ -1417,7 +1417,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, } else { - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); *ptail = newnode; @@ -1486,7 +1487,7 @@ node_expand (struct wordsplit *wsp, struct wordsplit_node *node, } return 0; } - + /* Remove NULL nodes from the list */ static void wsnode_nullelim (struct wordsplit *wsp) @@ -1539,7 +1540,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, size_t j; char *value; struct wordsplit_node *newnode; - + str++; len--; @@ -1566,7 +1567,7 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, } else rc = wsp->ws_command (&value, str, j, NULL, wsp->ws_closure); - + if (rc == WRDSE_NOSPACE) return _wsplt_nomem (wsp); else if (rc) @@ -1585,7 +1586,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, { if (flg & _WSNF_QUOTE) { - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); *ptail = newnode; @@ -1596,7 +1598,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, { free (value); /* Empty string is a special case */ - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); *ptail = newnode; @@ -1627,7 +1630,8 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, } else { - if (wsnode_new (wsp, &newnode)) + newnode = wsnode_new (wsp); + if (!newnode) return 1; wsnode_insert (wsp, newnode, *ptail, 0); *ptail = newnode; @@ -1674,13 +1678,13 @@ wordsplit_trimws (struct wordsplit *wsp) ; p->v.segm.beg = n; } - + while (p->next && (p->flags & _WSNF_JOIN)) p = p->next; - + if (p->flags & _WSNF_QUOTE) continue; - + /* Trim trailing whitespace */ for (n = p->v.segm.end; n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--); @@ -1699,7 +1703,7 @@ wordsplit_tildexpand (struct wordsplit *wsp) struct wordsplit_node *p; char *uname = NULL; size_t usize = 0; - + for (p = wsp->ws_head; p; p = p->next) { const char *str; @@ -1714,7 +1718,7 @@ wordsplit_tildexpand (struct wordsplit *wsp) size_t slen = wsnode_len (p); struct passwd *pw; char *newstr; - + for (i = 1; i < slen && str[i] != '/'; i++) ; if (i == slen) @@ -1788,7 +1792,7 @@ wordsplit_pathexpand (struct wordsplit *wsp) if (wsp->ws_options & WRDSO_DOTGLOB) flags = GLOB_PERIOD; #endif - + for (p = wsp->ws_head; p; p = next) { const char *str; @@ -1807,23 +1811,23 @@ wordsplit_pathexpand (struct wordsplit *wsp) glob_t g; struct wordsplit_node *prev; char *pattern; - + pattern = malloc (slen + 1); if (!pattern) return _wsplt_nomem (wsp); memcpy (pattern, str, slen); pattern[slen] = 0; - + switch (glob (pattern, flags, NULL, &g)) { case 0: free (pattern); break; - + case GLOB_NOSPACE: free (pattern); return _wsplt_nomem (wsp); - + case GLOB_NOMATCH: if (wsp->ws_options & WRDSO_NULLGLOB) { @@ -1846,7 +1850,7 @@ wordsplit_pathexpand (struct wordsplit *wsp) } free (pattern); continue; - + default: free (pattern); return _wsplt_seterr (wsp, WRDSE_GLOBERR); @@ -1855,10 +1859,10 @@ wordsplit_pathexpand (struct wordsplit *wsp) prev = p; for (i = 0; i < g.gl_pathc; i++) { - struct wordsplit_node *newnode; + struct wordsplit_node *newnode = wsnode_new (wsp); char *newstr; - - if (wsnode_new (wsp, &newnode)) + + if (!newnode) return 1; newstr = strdup (g.gl_pathv[i]); if (!newstr) @@ -1975,7 +1979,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all) int join = 0; unsigned flags = 0; struct wordsplit_node *np = wsp->ws_tail; - + size_t i = start; if (i >= len) @@ -2064,7 +2068,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all) wsp->ws_endp = i; if (wsp->ws_flags & WRDSF_INCREMENTAL) return _WRDS_EOF; - + if (consume_all) { if (!np) @@ -2075,7 +2079,7 @@ scan_word (struct wordsplit *wsp, size_t start, int consume_all) np = np->next; } } - + return _WRDS_OK; } @@ -2342,7 +2346,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start) if (wsp->ws_flags & WRDSF_SHOWDBG) wsp->ws_debug (_("(%02d) Input:%.*s;"), wsp->ws_lvl, (int) wsp->ws_len, wsp->ws_input); - + if ((wsp->ws_flags & WRDSF_NOSPLIT) || ((wsp->ws_options & WRDSO_MAXWORDS) && wsp->ws_wordi + 1 == wsp->ws_maxwords)) @@ -2438,7 +2442,7 @@ wordsplit_run (const char *command, size_t length, struct wordsplit *wsp, } int -wordsplit_len (const char *command, size_t length, struct wordsplit *wsp, +wordsplit_len (const char *command, size_t length, struct wordsplit *wsp, unsigned flags) { return wordsplit_run (command, length, wsp, flags, 0); @@ -2559,4 +2563,3 @@ wordsplit_perror (struct wordsplit *wsp) wsp->ws_error ("%s", wordsplit_strerror (wsp)); } } - |