aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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)
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
node_split_prefix (struct wordsplit *wsp,
@@ -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[] = {

Return to:

Send suggestions and report system problems to the System administrator.