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,7 +674,35 @@ wordsplit_finish (struct wordsplit *wsp) | |||
674 | return 0; | 674 | return 0; |
675 | } | 675 | } |
676 | 676 | ||
677 | int | ||
678 | wordsplit_append (wordsplit_t *wsp, int argc, char **argv) | ||
679 | { | ||
680 | int rc; | ||
681 | size_t i; | ||
677 | 682 | ||
683 | rc = alloc_space (wsp, wsp->ws_wordc + argc + 1); | ||
684 | if (rc) | ||
685 | return rc; | ||
686 | for (i = 0; i < argc; i++) | ||
687 | { | ||
688 | char *newstr = strdup (argv[i]); | ||
689 | if (!newstr) | ||
690 | { | ||
691 | while (i > 0) | ||
692 | { | ||
693 | free (wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i - 1]); | ||
694 | wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i - 1] = NULL; | ||
695 | i--; | ||
696 | } | ||
697 | return _wsplt_nomem (wsp); | ||
698 | } | ||
699 | wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i] = newstr; | ||
700 | } | ||
701 | wsp->ws_wordc += i; | ||
702 | wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL; | ||
703 | return 0; | ||
704 | } | ||
705 | |||
678 | /* Variable expansion */ | 706 | /* Variable expansion */ |
679 | static int | 707 | static int |
680 | node_split_prefix (struct wordsplit *wsp, | 708 | node_split_prefix (struct wordsplit *wsp, |
@@ -1015,7 +1043,9 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, | |||
1015 | else | 1043 | else |
1016 | rc = WRDSE_UNDEF; | 1044 | rc = WRDSE_UNDEF; |
1017 | 1045 | ||
1018 | if (rc == WRDSE_OK && value[0] == 0 && defstr && defstr[-1] == ':') | 1046 | if (rc == WRDSE_OK |
1047 | && (!value || value[0] == 0) | ||
1048 | && defstr && defstr[-1] == ':') | ||
1019 | { | 1049 | { |
1020 | free (value); | 1050 | free (value); |
1021 | rc = WRDSE_UNDEF; | 1051 | rc = WRDSE_UNDEF; |
@@ -1332,7 +1362,6 @@ expcmd (struct wordsplit *wsp, const char *str, size_t len, | |||
1332 | struct wordsplit ws; | 1362 | struct wordsplit ws; |
1333 | 1363 | ||
1334 | rc = _wsplt_subsplit (wsp, &ws, str, j, | 1364 | rc = _wsplt_subsplit (wsp, &ws, str, j, |
1335 | WRDSF_NOVAR | WRDSF_NOCMD | | ||
1336 | WRDSF_WS | WRDSF_QUOTE); | 1365 | WRDSF_WS | WRDSF_QUOTE); |
1337 | if (rc) | 1366 | if (rc) |
1338 | { | 1367 | { |
@@ -2065,29 +2094,41 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex) | |||
2065 | } | 2094 | } |
2066 | } | 2095 | } |
2067 | 2096 | ||
2097 | |||
2098 | /* This structure describes a single expansion phase */ | ||
2068 | struct exptab | 2099 | struct exptab |
2069 | { | 2100 | { |
2070 | char *descr; | 2101 | char *descr; /* Textual description (for debugging) */ |
2071 | int flag; | 2102 | int flag; /* WRDSF_ bit that controls this phase */ |
2072 | int opt; | 2103 | int opt; /* Entry-specific options (see EXPOPT_ flags below */ |
2073 | int (*expansion) (struct wordsplit *wsp); | 2104 | int (*expansion) (struct wordsplit *wsp); /* expansion function */ |
2074 | }; | 2105 | }; |
2075 | 2106 | ||
2107 | /* The following options control expansions: */ | ||
2108 | /* Normally the exptab entry is run if its flag bit is set in struct | ||
2109 | wordsplit. The EXPOPT_NEG option negates this test so that expansion | ||
2110 | is performed if its associated flag bit is not set in struct wordsplit. */ | ||
2076 | #define EXPOPT_NEG 0x01 | 2111 | #define EXPOPT_NEG 0x01 |
2112 | /* Coalesce the input list before running the expansion. */ | ||
2077 | #define EXPOPT_COALESCE 0x02 | 2113 | #define EXPOPT_COALESCE 0x02 |
2078 | 2114 | ||
2079 | static struct exptab exptab[] = { | 2115 | static struct exptab exptab[] = { |
2080 | { N_("WS trimming"), WRDSF_WS, 0, wordsplit_trimws }, | 2116 | { N_("WS trimming"), WRDSF_WS, 0, |
2081 | { N_("tilde expansion"), WRDSF_PATHEXPAND, 0, wordsplit_tildexpand }, | 2117 | wordsplit_trimws }, |
2118 | { N_("command substitution"), WRDSF_NOCMD, EXPOPT_NEG|EXPOPT_COALESCE, | ||
2119 | wordsplit_cmdexp }, | ||
2120 | { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE, | ||
2121 | NULL }, | ||
2122 | { N_("tilde expansion"), WRDSF_PATHEXPAND, 0, | ||
2123 | wordsplit_tildexpand }, | ||
2082 | { N_("variable expansion"), WRDSF_NOVAR, EXPOPT_NEG, | 2124 | { N_("variable expansion"), WRDSF_NOVAR, EXPOPT_NEG, |
2083 | wordsplit_varexp }, | 2125 | wordsplit_varexp }, |
2084 | { N_("quote removal"), 0, EXPOPT_NEG, | 2126 | { N_("quote removal"), 0, EXPOPT_NEG, |
2085 | wsnode_quoteremoval }, | 2127 | wsnode_quoteremoval }, |
2086 | { N_("command substitution"), WRDSF_NOCMD, EXPOPT_NEG|EXPOPT_COALESCE, | ||
2087 | wordsplit_cmdexp }, | ||
2088 | { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE, | 2128 | { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE, |
2089 | NULL }, | 2129 | NULL }, |
2090 | { N_("path expansion"), WRDSF_PATHEXPAND, 0, wordsplit_pathexpand }, | 2130 | { N_("path expansion"), WRDSF_PATHEXPAND, 0, |
2131 | wordsplit_pathexpand }, | ||
2091 | { NULL } | 2132 | { NULL } |
2092 | }; | 2133 | }; |
2093 | 2134 | ||
@@ -2101,6 +2142,7 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start) | |||
2101 | /* Treat entire input as a quoted argument */ | 2142 | /* Treat entire input as a quoted argument */ |
2102 | if (wordsplit_add_segm (wsp, start, wsp->ws_len, _WSNF_QUOTE)) | 2143 | if (wordsplit_add_segm (wsp, start, wsp->ws_len, _WSNF_QUOTE)) |
2103 | return wsp->ws_errno; | 2144 | return wsp->ws_errno; |
2145 | wsp->ws_endp = wsp->ws_len; | ||
2104 | } | 2146 | } |
2105 | else | 2147 | else |
2106 | { | 2148 | { |
@@ -2282,16 +2324,21 @@ wordsplit_free (struct wordsplit *ws) | |||
2282 | wordsplit_free_envbuf (ws); | 2324 | wordsplit_free_envbuf (ws); |
2283 | } | 2325 | } |
2284 | 2326 | ||
2285 | void | 2327 | int |
2286 | wordsplit_getwords (struct wordsplit *ws, size_t *wordc, char ***wordv) | 2328 | wordsplit_get_words (struct wordsplit *ws, size_t *wordc, char ***wordv) |
2287 | { | 2329 | { |
2288 | char **p = realloc (ws->ws_wordv, | 2330 | char **p = realloc (ws->ws_wordv, |
2289 | (ws->ws_wordc + 1) * sizeof (ws->ws_wordv[0])); | 2331 | (ws->ws_wordc + 1) * sizeof (ws->ws_wordv[0])); |
2290 | *wordv = p ? p : ws->ws_wordv; | 2332 | if (!p) |
2333 | return -1; | ||
2334 | *wordv = p; | ||
2291 | *wordc = ws->ws_wordc; | 2335 | *wordc = ws->ws_wordc; |
2336 | |||
2292 | ws->ws_wordv = NULL; | 2337 | ws->ws_wordv = NULL; |
2293 | ws->ws_wordc = 0; | 2338 | ws->ws_wordc = 0; |
2294 | ws->ws_wordn = 0; | 2339 | ws->ws_wordn = 0; |
2340 | |||
2341 | return 0; | ||
2295 | } | 2342 | } |
2296 | 2343 | ||
2297 | const char *_wordsplit_errstr[] = { | 2344 | const char *_wordsplit_errstr[] = { |