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
@@ -1180,13 +1180,13 @@ wordsplit_cmdexp (struct wordsplit *wsp)
return 0;
}
/* 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;
for (p = wsp->ws_head; p; p = p->next)
{
@@ -1206,12 +1206,13 @@ wordsplit_trimws (struct wordsplit *wsp)
p->v.segm.end = n;
if (p->v.segm.beg == p->v.segm.end)
p->flags |= _WSNF_NULL;
}
wsnode_nullelim (wsp);
+ return 0;
}
static int
wordsplit_tildexpand (struct wordsplit *wsp)
{
struct wordsplit_node *p;
@@ -1227,13 +1228,12 @@ wordsplit_tildexpand (struct wordsplit *wsp)
str = wsnode_ptr (wsp, p);
if (str[0] == '~')
{
size_t i, size, dlen;
size_t slen = wsnode_len (p);
- char *dir;
struct passwd *pw;
char *newstr;
for (i = 1; i < slen && str[i] != '/'; i++)
;
if (i == slen)
@@ -1279,12 +1279,13 @@ wordsplit_tildexpand (struct wordsplit *wsp)
free (p->v.word);
p->v.word = newstr;
p->flags |= _WSNF_WORD;
}
}
free (uname);
+ return 0;
}
static int
isglob (const char *s, int l)
{
while (l--)
@@ -1299,13 +1300,12 @@ static int
wordsplit_pathexpand (struct wordsplit *wsp)
{
struct wordsplit_node *p, *next;
char *pattern = NULL;
size_t patsize = 0;
size_t slen;
- char *str;
int flags = 0;
#ifdef GLOB_PERIOD
if (wsp->ws_options & WRDSO_DOTGLOB)
flags = GLOB_PERIOD;
#endif
@@ -1395,12 +1395,13 @@ wordsplit_pathexpand (struct wordsplit *wsp)
wsnode_remove (wsp, p);
wsnode_free (p);
}
}
free (pattern);
+ return 0;
}
static int
skip_sed_expr (const char *command, size_t i, size_t len)
{
int state;
@@ -1802,15 +1803,43 @@ 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 */
if (wordsplit_add_segm (wsp, start, wsp->ws_len, _WSNF_QUOTE))
return wsp->ws_errno;
}
@@ -1826,103 +1855,43 @@ wordsplit_process_list (struct wordsplit *wsp, size_t start)
if (rc == _WRDS_ERR)
return wsp->ws_errno;
}
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;
}
int
wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
int flags)
@@ -1954,25 +1923,25 @@ wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
rc = wordsplit_init (wsp, cmdptr, cmdlen, flags);
if (rc)
return rc;
}
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))
{
while (!wsp->ws_head && wsp->ws_endp < wsp->ws_len)
{
start = skip_delim (wsp);
if (wsp->ws_flags & WRDSF_SHOWDBG)
{
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)
break;
}
}

Return to:

Send suggestions and report system problems to the System administrator.