aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2014-10-24 10:59:04 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-12-17 15:25:24 +0200
commitd72f0a0008697df2533aad69e9daddaa4ace10ca (patch)
tree4db7b31955d636126f55c5cb528952e0379ae22a
parent9dcef9e579d2e06f294dabe7918fe6753054e6cb (diff)
downloadgrecs-d72f0a0008697df2533aad69e9daddaa4ace10ca.tar.gz
grecs-d72f0a0008697df2533aad69e9daddaa4ace10ca.tar.bz2
Various improvements in wordsplit
* src/wordsplit.c (wordsplit_trimws): Retutn int. (wordsplit_tildexpand,wordsplit_pathexpand): Add missing return. (wordsplit_process_list): Rewrite in a table-driven fashion.
-rw-r--r--src/wordsplit.c147
1 files changed, 58 insertions, 89 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index 6b01887..403ffed 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -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)
- {
- /* Trim leading and trailing whitespace */
- wordsplit_trimws (wsp);
- if (wsp->ws_flags & WRDSF_SHOWDBG)
- {
- wsp->ws_debug ("After WS trimming:");
- wordsplit_dump_nodes (wsp);
- }
- }
-
- if (wsp->ws_flags & WRDSF_PATHEXPAND)
+ for (p = exptab; p->descr; p++)
{
- wordsplit_tildexpand (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 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 (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 (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)

Return to:

Send suggestions and report system problems to the System administrator.