summaryrefslogtreecommitdiffabout
path: root/src
authorSergey Poznyakoff <gray@gnu.org.ua>2017-11-10 08:41:12 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2017-11-10 08:42:12 (GMT)
commit3299cf1ccb1c596969fcfd91253e10d5482eacf9 (patch) (unidiff)
tree871608720ac6050713cb2fecf5d3dcfd86aee938 /src
parentb1258b6d6e9e0482b37e86977ffc779e14c75b9f (diff)
downloadgrecs-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') (more/less context) (ignore whitespace changes)
-rw-r--r--src/wordsplit.c75
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
677int
678wordsplit_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 */
679static int 707static int
680node_split_prefix (struct wordsplit *wsp, 708node_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 */
2068struct exptab 2099struct 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
2079static struct exptab exptab[] = { 2115static 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
2285void 2327int
2286wordsplit_getwords (struct wordsplit *ws, size_t *wordc, char ***wordv) 2328wordsplit_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
2297const char *_wordsplit_errstr[] = { 2344const char *_wordsplit_errstr[] = {

Return to:

Send suggestions and report system problems to the System administrator.