Various improvements

* src/wordsplit.c (wordsplit_trimws): Retutn int.
(wordsplit_tildexpand,wordsplit_pathexpand): Add missing return.
(wordsplit_process_list): Rewrite in a table-driven fashion.
This commit is contained in:
Sergey Poznyakoff 2014-10-24 10:59:04 +03:00
parent 08d3154b58
commit 00301604fd

View file

@ -1183,7 +1183,7 @@ wordsplit_cmdexp (struct wordsplit *wsp)
/* Strip off any leading and trailing whitespace. This function is called
right after the initial scanning, therefore it assumes that every
node in the list is a text reference node. */
static void
static int
wordsplit_trimws (struct wordsplit *wsp)
{
struct wordsplit_node *p;
@ -1209,6 +1209,7 @@ wordsplit_trimws (struct wordsplit *wsp)
}
wsnode_nullelim (wsp);
return 0;
}
static int
@ -1230,7 +1231,6 @@ wordsplit_tildexpand (struct wordsplit *wsp)
{
size_t i, size, dlen;
size_t slen = wsnode_len (p);
char *dir;
struct passwd *pw;
char *newstr;
@ -1282,6 +1282,7 @@ wordsplit_tildexpand (struct wordsplit *wsp)
}
}
free (uname);
return 0;
}
static int
@ -1302,7 +1303,6 @@ wordsplit_pathexpand (struct wordsplit *wsp)
char *pattern = NULL;
size_t patsize = 0;
size_t slen;
char *str;
int flags = 0;
#ifdef GLOB_PERIOD
@ -1398,6 +1398,7 @@ wordsplit_pathexpand (struct wordsplit *wsp)
}
}
free (pattern);
return 0;
}
static int
@ -1805,9 +1806,37 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
}
}
struct exptab
{
char *descr;
int flag;
int opt;
int (*expansion) (struct wordsplit *wsp);
};
#define EXPOPT_NEG 0x01
#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_("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 },
{ NULL }
};
static int
wordsplit_process_list (struct wordsplit *wsp, size_t start)
{
struct exptab *p;
if (wsp->ws_flags & WRDSF_NOSPLIT)
{
/* Treat entire input as a quoted argument */
@ -1829,97 +1858,37 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("Initial list:");
wsp->ws_debug (_("Initial list:"));
wordsplit_dump_nodes (wsp);
}
if (wsp->ws_flags & WRDSF_WS)
for (p = exptab; p->descr; p++)
{
/* Trim leading and trailing whitespace */
wordsplit_trimws (wsp);
if (wsp->ws_flags & WRDSF_SHOWDBG)
if ((p->opt & EXPOPT_NEG)
? !(wsp->ws_flags & p->flag) : (wsp->ws_flags & p->flag))
{
wsp->ws_debug ("After WS trimming:");
wordsplit_dump_nodes (wsp);
if (p->opt & EXPOPT_COALESCE)
{
if (wsnode_coalesce (wsp))
break;
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug (_("Coalesced list:"));
wordsplit_dump_nodes (wsp);
}
}
if (p->expansion)
{
if (p->expansion (wsp))
break;
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("%s:", _(p->descr));
wordsplit_dump_nodes (wsp);
}
}
}
}
if (wsp->ws_flags & WRDSF_PATHEXPAND)
{
wordsplit_tildexpand (wsp);
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("After tilde expansion:");
wordsplit_dump_nodes (wsp);
}
}
/* Expand variables */
if (!(wsp->ws_flags & WRDSF_NOVAR))
{
if (wordsplit_varexp (wsp))
{
wordsplit_free_nodes (wsp);
return wsp->ws_errno;
}
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("After variable expansion:");
wordsplit_dump_nodes (wsp);
}
}
if (wsnode_quoteremoval (wsp))
return wsp->ws_errno;
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("After quote removal:");
wordsplit_dump_nodes (wsp);
}
/* Expand commands */
if (!(wsp->ws_flags & WRDSF_NOCMD))
{
if (wsnode_coalesce (wsp))
return wsp->ws_errno;
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("Coalesced list:");
wordsplit_dump_nodes (wsp);
}
if (wordsplit_cmdexp (wsp))
{
wordsplit_free_nodes (wsp);
return wsp->ws_errno;
}
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("After command expansion:");
wordsplit_dump_nodes (wsp);
}
}
if (wsnode_coalesce (wsp))
return wsp->ws_errno;
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("Coalesced list:");
wordsplit_dump_nodes (wsp);
}
if (wsp->ws_flags & WRDSF_PATHEXPAND)
{
wordsplit_pathexpand (wsp);
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
wsp->ws_debug ("After path expansion:");
wordsplit_dump_nodes (wsp);
}
}
return wsp->ws_errno;
}
@ -1957,7 +1926,7 @@ wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
}
if (wsp->ws_flags & WRDSF_SHOWDBG)
wsp->ws_debug ("Input:%.*s;", (int) cmdlen, cmdptr);
wsp->ws_debug (_("Input:%.*s;"), (int) cmdlen, cmdptr);
rc = wordsplit_process_list (wsp, start);
if (rc == 0 && (flags & WRDSF_INCREMENTAL))
@ -1969,7 +1938,7 @@ wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
{
cmdptr = wsp->ws_input + wsp->ws_endp;
cmdlen = wsp->ws_len - wsp->ws_endp;
wsp->ws_debug ("Restart:%.*s;", (int) cmdlen, cmdptr);
wsp->ws_debug (_("Restart:%.*s;"), (int) cmdlen, cmdptr);
}
rc = wordsplit_process_list (wsp, start);
if (rc)