diff options
Diffstat (limited to 'src/wordsplit.c')
-rw-r--r-- | src/wordsplit.c | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index 9381ae7..4884a22 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -676,3 +676,31 @@ wordsplit_finish (struct wordsplit *wsp) +int +wordsplit_append (wordsplit_t *wsp, int argc, char **argv) +{ + int rc; + size_t i; + rc = alloc_space (wsp, wsp->ws_wordc + argc + 1); + if (rc) + return rc; + for (i = 0; i < argc; i++) + { + char *newstr = strdup (argv[i]); + if (!newstr) + { + while (i > 0) + { + free (wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i - 1]); + wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i - 1] = NULL; + i--; + } + return _wsplt_nomem (wsp); + } + wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i] = newstr; + } + wsp->ws_wordc += i; + wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL; + return 0; +} + /* Variable expansion */ @@ -1017,3 +1045,5 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, - if (rc == WRDSE_OK && value[0] == 0 && defstr && defstr[-1] == ':') + if (rc == WRDSE_OK + && (!value || value[0] == 0) + && defstr && defstr[-1] == ':') { @@ -1334,3 +1364,2 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, rc = _wsplt_subsplit (wsp, &ws, str, j, - WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_WS | WRDSF_QUOTE); @@ -2067,11 +2096,18 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex) + +/* This structure describes a single expansion phase */ struct exptab { - char *descr; - int flag; - int opt; - int (*expansion) (struct wordsplit *wsp); + char *descr; /* Textual description (for debugging) */ + int flag; /* WRDSF_ bit that controls this phase */ + int opt; /* Entry-specific options (see EXPOPT_ flags below */ + int (*expansion) (struct wordsplit *wsp); /* expansion function */ }; +/* The following options control expansions: */ +/* Normally the exptab entry is run if its flag bit is set in struct + wordsplit. The EXPOPT_NEG option negates this test so that expansion + is performed if its associated flag bit is not set in struct wordsplit. */ #define EXPOPT_NEG 0x01 +/* Coalesce the input list before running the expansion. */ #define EXPOPT_COALESCE 0x02 @@ -2079,4 +2115,10 @@ struct exptab static struct exptab exptab[] = { - { N_("WS trimming"), WRDSF_WS, 0, wordsplit_trimws }, - { N_("tilde expansion"), WRDSF_PATHEXPAND, 0, wordsplit_tildexpand }, + { N_("WS trimming"), WRDSF_WS, 0, + wordsplit_trimws }, + { N_("command substitution"), WRDSF_NOCMD, EXPOPT_NEG|EXPOPT_COALESCE, + wordsplit_cmdexp }, + { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE, + NULL }, + { N_("tilde expansion"), WRDSF_PATHEXPAND, 0, + wordsplit_tildexpand }, { N_("variable expansion"), WRDSF_NOVAR, EXPOPT_NEG, @@ -2085,7 +2127,6 @@ static struct exptab exptab[] = { wsnode_quoteremoval }, - { N_("command substitution"), WRDSF_NOCMD, EXPOPT_NEG|EXPOPT_COALESCE, - wordsplit_cmdexp }, { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE, NULL }, - { N_("path expansion"), WRDSF_PATHEXPAND, 0, wordsplit_pathexpand }, + { N_("path expansion"), WRDSF_PATHEXPAND, 0, + wordsplit_pathexpand }, { NULL } @@ -2103,2 +2144,3 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start) return wsp->ws_errno; + wsp->ws_endp = wsp->ws_len; } @@ -2284,4 +2326,4 @@ wordsplit_free (struct wordsplit *ws) -void -wordsplit_getwords (struct wordsplit *ws, size_t *wordc, char ***wordv) +int +wordsplit_get_words (struct wordsplit *ws, size_t *wordc, char ***wordv) { @@ -2289,4 +2331,7 @@ wordsplit_getwords (struct wordsplit *ws, size_t *wordc, char ***wordv) (ws->ws_wordc + 1) * sizeof (ws->ws_wordv[0])); - *wordv = p ? p : ws->ws_wordv; + if (!p) + return -1; + *wordv = p; *wordc = ws->ws_wordc; + ws->ws_wordv = NULL; @@ -2294,2 +2339,4 @@ wordsplit_getwords (struct wordsplit *ws, size_t *wordc, char ***wordv) ws->ws_wordn = 0; + + return 0; } |