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 | |
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.
-rw-r--r-- | include/wordsplit.h | 13 | ||||
-rw-r--r-- | src/wordsplit.c | 75 | ||||
-rw-r--r-- | tests/wordsplit.at | 69 | ||||
-rw-r--r-- | tests/wsp.c | 21 |
4 files changed, 155 insertions, 23 deletions
diff --git a/include/wordsplit.h b/include/wordsplit.h index a7f6dd5..eed88bc 100644 --- a/include/wordsplit.h +++ b/include/wordsplit.h @@ -237,3 +237,14 @@ void wordsplit_free_words (wordsplit_t *ws); void wordsplit_free_envbuf (wordsplit_t *ws); -void wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv); +int wordsplit_get_words (wordsplit_t *ws, size_t *wordc, char ***wordv); + +static inline void wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv) + __attribute__ ((deprecated)); + +static inline void +wordsplit_getwords (wordsplit_t *ws, size_t *wordc, char ***wordv) +{ + wordsplit_get_words (ws, wordc, wordv); +} + +int wordsplit_append (wordsplit_t *wsp, int argc, char **argv); 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; } diff --git a/tests/wordsplit.at b/tests/wordsplit.at index 895a392..49d47e9 100644 --- a/tests/wordsplit.at +++ b/tests/wordsplit.at @@ -639,2 +639,10 @@ NF: 1 +TESTWSP([incremental nosplit],[],[incremental nosplit], +[incremental "input test" line +], +[NF: 1 +0: "incremental \"input test\" line" +], +[input exhausted +]) @@ -719,3 +727,3 @@ mkdir dir DIR=dir wsp -nocmd -novar<<'EOT' -begin $(find $DIR) end +begin $DIR $(find $DIR) end EOT @@ -723,7 +731,8 @@ EOT [0], -[NF: 4 +[NF: 5 0: begin 1: dir -2: dir/file -3: end +2: dir +3: dir/file +4: end ]) @@ -737,4 +746,4 @@ mkdir dir -DIR=dir wsp -nocmd -novar<<'EOT' -"begin($(find $DIR))end" +DIR=dir BEGIN=begin wsp -nocmd -novar<<'EOT' +"${BEGIN}($(find $DIR))end" EOT @@ -746,3 +755,23 @@ EOT AT_CLEANUP - + +AT_SETUP([nested commands]) +AT_KEYWORDS([wordsplit wsp wsp-cmd]) +AT_CHECK([ +AT_DATA([input],[foo +bar +baz +]) +SUFFIX=put wsp -nocmd -novar <<'EOT' +$(echo output $(cat in$SUFFIX)) +EOT +], +[0], +[NF: 4 +0: output +1: foo +2: bar +3: baz +]) +AT_CLEANUP + AT_SETUP([pathname expansion]) @@ -822,2 +851,28 @@ AT_CLEANUP +TESTWSP([append],[],[-- extra arguments follow], +[some words and], +[NF: 6 +0: some +1: words +2: and +3: extra +4: arguments +5: follow +]) + +TESTWSP([append + dooffs + env],[], +[dooffs 2 preface words V=2 -- extra arguments follow], +[some words and var=$V], +[NF: 7 (2) +(0): preface +(1): words +2: some +3: words +4: and +5: var=2 +6: extra +7: arguments +8: follow +]) + m4_popdef([TESTWSP]) diff --git a/tests/wsp.c b/tests/wsp.c index e8eb9c6..84efc13 100644 --- a/tests/wsp.c +++ b/tests/wsp.c @@ -93,3 +93,3 @@ help () - printf ("usage: %s [options] [VAR=VALUE...]\n", progname); + printf ("usage: %s [options] [VAR=VALUE...] [-- EXTRA...]\n", progname); printf ("options are:\n"); @@ -336,2 +336,4 @@ main (int argc, char **argv) int use_env = env_sys; + int appendc = 0; + char **appendv = NULL; @@ -348,2 +350,8 @@ main (int argc, char **argv) { + if (opt[1] == '-' && opt[2] == 0) + { + appendc = argc - i - 1; + appendv = argv + i + 1; + break; + } negate = 1; @@ -606,2 +614,13 @@ main (int argc, char **argv) + if (appendc) + { + rc = wordsplit_append (&ws, appendc, appendv); + if (rc) + { + if (!(wsflags & WRDSF_SHOWERR)) + wordsplit_perror (&ws); + continue; + } + } + wsflags |= WRDSF_REUSE | (ws.ws_flags & WRDSF_ENV); |