diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-11-10 10:41:12 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-11-10 10:42:12 +0200 |
commit | 3299cf1ccb1c596969fcfd91253e10d5482eacf9 (patch) | |
tree | 871608720ac6050713cb2fecf5d3dcfd86aee938 /src | |
parent | b1258b6d6e9e0482b37e86977ffc779e14c75b9f (diff) | |
download | grecs-3299cf1ccb1c596969fcfd91253e10d5482eacf9.tar.gz grecs-3299cf1ccb1c596969fcfd91253e10d5482eacf9.tar.bz2 |
Pull fixes to wordsplit from mailutils
This includes the following commits pushed between
2015-09-19 and 2017-10-10:
090c7b9a Allow ws_getvar to set value to NULL and
return MU_WRDSE_OK.
The value is processed as if it were "", i.e.
MU_WRDSE_UNDEF is returned.
64313fdf Fix MU_WRDSF_INCREMENTAL | MU_WRDSF_NOSPLIT
46d7640f Add wordsplit_append function
151eb4b9 Fix nested expansions and command expansions
occurring after variable expansions.
ad3cc340 Replace void wordsplit_getwords with
int wordsplit_get_words.
* include/wordsplit.h (wordsplit_get_words): New function.
(wordsplit_getwords): Mark as deprecated.
(wordsplit_append): New function.
* src/wordsplit.c (wordsplit_append): New function. MU 46d7640f.
(expvar): Treat NULL value as "". MU 090c7b9a.
(expcmd): Allow command and variable expansions in subsplit.
(exptab): Change ordering of expansions so that command expansion
occurs first. This fixes nested expansions and command expansions
occurring after variable expansions. MU 151eb4b9.
(wordsplit_process_list): Update wsp->ws_endp in nosplit mode. This
fixes wordsplit MU_WRDSF_INCREMENTAL | MU_WRDSF_NOSPLIT. MU 64313fdf.
(wordsplit_get_words): New function. MU ad3cc340.
* tests/wordsplit.at: Test the above changes.
* tests/wsp.c: Accept extra arguments to append using wordsplit_append.
Diffstat (limited to 'src')
-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 @@ -674,6 +674,34 @@ wordsplit_finish (struct wordsplit *wsp) return 0; } +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 */ static int @@ -1015,7 +1043,9 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, else rc = WRDSE_UNDEF; - if (rc == WRDSE_OK && value[0] == 0 && defstr && defstr[-1] == ':') + if (rc == WRDSE_OK + && (!value || value[0] == 0) + && defstr && defstr[-1] == ':') { free (value); rc = WRDSE_UNDEF; @@ -1332,7 +1362,6 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, struct wordsplit ws; rc = _wsplt_subsplit (wsp, &ws, str, j, - WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_WS | WRDSF_QUOTE); if (rc) { @@ -2065,29 +2094,41 @@ 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 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, wordsplit_varexp }, { N_("quote removal"), 0, EXPOPT_NEG, 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 } }; @@ -2101,6 +2142,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start) /* Treat entire input as a quoted argument */ if (wordsplit_add_segm (wsp, start, wsp->ws_len, _WSNF_QUOTE)) return wsp->ws_errno; + wsp->ws_endp = wsp->ws_len; } else { @@ -2282,16 +2324,21 @@ wordsplit_free (struct wordsplit *ws) wordsplit_free_envbuf (ws); } -void -wordsplit_getwords (struct wordsplit *ws, size_t *wordc, char ***wordv) +int +wordsplit_get_words (struct wordsplit *ws, size_t *wordc, char ***wordv) { char **p = realloc (ws->ws_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; ws->ws_wordc = 0; ws->ws_wordn = 0; + + return 0; } const char *_wordsplit_errstr[] = { |