aboutsummaryrefslogtreecommitdiff
path: root/tests/wsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/wsp.c')
-rw-r--r--tests/wsp.c832
1 files changed, 444 insertions, 388 deletions
diff --git a/tests/wsp.c b/tests/wsp.c
index bd13e63..958d01f 100644
--- a/tests/wsp.c
+++ b/tests/wsp.c
@@ -1,5 +1,5 @@
/* grecs - Gray's Extensible Configuration System
- Copyright (C) 2014-2016 Sergey Poznyakoff
+ Copyright (C) 2014-2019 Sergey Poznyakoff
Grecs is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -29,99 +29,408 @@ extern char **environ;
char *progname;
-struct kwd
+/* Global options */
+enum
+ {
+ TRIMNL_OPTION = 0x01, /* Remove trailing newline */
+ PLAINTEXT_OPTION = 0x02 /* Print intput verbatim (no escapes) */
+ };
+
+/* Environment types */
+enum env_type
+ {
+ env_none, /* No environment */
+ env_null, /* Null environment */
+ env_sys /* Use system environment */
+ };
+
+struct wsclosure
{
- const char *name;
- int tok;
+ int options; /* Global options */
+ struct wordsplit ws; /* The wordsplit structure */
+ int wsflags; /* Wordsplit flags */
+ enum env_type env_type; /* Environment type */
+ int offarg; /* Index of the first of the initial words in
+ the argv array. The ws.ws_dooffs field gives
+ the number of such variables. Forces the
+ WRDSF_DOOFFS flag. */
+ char **fenvbase; /* Environment for testing the ws_getenv function */
+ int fenvidx; /* Number of variables in fenvbase */
+ int fenvmax; /* Size of fenbase (entries) */
+ int append_start; /* First argument to append (index in argv) */
+ int append_count; /* Number of arguments to append */
};
-struct kwd bool_keytab[] = {
- { "append", WRDSF_APPEND },
- /*{ "reuse", WRDSF_REUSE },*/
- { "undef", WRDSF_UNDEF },
- { "novar", WRDSF_NOVAR },
- { "nocmd", WRDSF_NOCMD },
- { "ws", WRDSF_WS },
- { "quote", WRDSF_QUOTE },
- { "squote", WRDSF_SQUOTE },
- { "dquote", WRDSF_DQUOTE },
- { "squeeze_delims", WRDSF_SQUEEZE_DELIMS },
- { "return_delims", WRDSF_RETURN_DELIMS },
- { "sed", WRDSF_SED_EXPR },
- { "debug", WRDSF_SHOWDBG },
- { "nosplit", WRDSF_NOSPLIT },
- { "keepundef", WRDSF_KEEPUNDEF },
- { "warnundef", WRDSF_WARNUNDEF },
- { "cescapes", WRDSF_CESCAPES },
- { "default", WRDSF_DEFFLAGS },
- { "env_kv", WRDSF_ENV_KV },
- { "incremental", WRDSF_INCREMENTAL },
- { "pathexpand", WRDSF_PATHEXPAND },
- { NULL, 0 }
-};
+/* Command line option types */
+enum
+ {
+ ws_no_argument, /* Option requires no arguments */
+ ws_boolean, /* Option is boolean (can be prefixed with -no) */
+ ws_required_argument, /* Option requires one argument */
+ ws_multiple_arguments /* Option takes multiple arguments, terminated with
+ "--" or end of argument list */
+ };
-struct kwd opt_keytab[] = {
- { "nullglob", WRDSO_NULLGLOB },
- { "failglob", WRDSO_FAILGLOB },
- { "dotglob", WRDSO_DOTGLOB },
- { "bskeep_words", WRDSO_BSKEEP_WORD },
- { "bskeep_quote", WRDSO_BSKEEP_QUOTE },
- { "bskeep", WRDSO_BSKEEP_WORD|WRDSO_BSKEEP_QUOTE },
- { "novarsplit", WRDSO_NOVARSPLIT },
- { "nocmdsplit", WRDSO_NOCMDSPLIT },
- { NULL, 0 }
+/* Structure describing a single command-line option */
+struct wsopt
+{
+ const char *name; /* Option name */
+ int tok; /* Corresponding flag */
+ int arg; /* Option type (see the enum above) */
+ void (*setfn) (int tok, int neg, char *arg, struct wsclosure *wsc);
+ /* Setter function */
};
-struct kwd string_keytab[] = {
- { "delim", WRDSF_DELIM },
- { "comment", WRDSF_COMMENT },
- { "escape", WRDSF_ESCAPE },
- { NULL, 0 }
-};
+/* Index of the next argument in the argv */
+static int wsoptind = -1;
+/* Parse next argument from the command line. Return EOF on end of arguments
+ or when the "--" argument is seen. */
static int
-kwxlat (struct kwd *kwp, const char *str, int *res)
+getwsopt (int argc, char **argv, struct wsopt *wso, struct wsclosure *wsc)
{
- for (; kwp->name; kwp++)
- if (strcmp (kwp->name, str) == 0)
- {
- *res = kwp->tok;
- return 0;
- }
- return -1;
+ int negate = 0;
+ char *opt;
+
+ if (wsoptind == -1)
+ wsoptind = 1;
+ if (wsoptind == argc)
+ return EOF;
+
+ opt = argv[wsoptind++];
+ if (strcmp (opt, "--") == 0)
+ return EOF;
+ if (*opt != '-')
+ {
+ if (strchr (opt, '='))
+ {
+ assert (wsc->fenvidx < wsc->fenvmax - 1);
+ wsc->fenvbase[wsc->fenvidx++] = opt;
+ return 0;
+ }
+ wsoptind--;
+ return EOF;
+ }
+ opt++; /* skip past initial dash */
+ if (strncmp (opt, "no-", 3) == 0)
+ {
+ negate = 1;
+ opt += 3;
+ }
+ else if (strncmp (opt, "no", 2) == 0)
+ {
+ negate = 1;
+ opt += 2;
+ }
+
+ for (; wso->name; wso++)
+ {
+ if (wso->arg == ws_boolean && wso->name[0] == 'n' && wso->name[1] == 'o'
+ && strcmp (wso->name + 2, opt) == 0)
+ {
+ negate ^= 1;
+ break;
+ }
+ if (strcmp (wso->name, opt) == 0)
+ break;
+ }
+
+ if (wso->name)
+ {
+ char *arg;
+ if (wso->arg == ws_multiple_arguments)
+ {
+ while (1)
+ {
+ if (wsoptind == argc)
+ break;
+ arg = argv[wsoptind++];
+ if (strcmp (arg, "--") == 0)
+ break;
+ wso->setfn (wso->tok, negate, arg, wsc);
+ }
+ }
+ else
+ {
+ if (wso->arg == ws_required_argument)
+ {
+ if (wsoptind == argc)
+ {
+ fprintf (stderr, "%s: missing arguments for -%s\n",
+ progname, opt);
+ exit (1);
+ }
+ arg = argv[wsoptind++];
+ }
+ wso->setfn (wso->tok, negate, arg, wsc);
+ }
+ return 0;
+ }
+
+ fprintf (stderr, "%s: unrecognized option: -%s\n",
+ progname, opt);
+ fprintf (stderr, "%s: try %s -help for more detail\n",
+ progname, progname);
+ exit (1);
+}
+
+/* Setter functions for various options */
+
+static void
+setfn_flag (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ if (neg)
+ wsc->wsflags &= ~flag;
+ else
+ wsc->wsflags |= flag;
+}
+
+static void
+setfn_option (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ wsc->wsflags |= WRDSF_OPTIONS;
+ if (neg)
+ wsc->ws.ws_options &= ~flag;
+ else
+ wsc->ws.ws_options |= flag;
+}
+
+static void
+setfn_delim (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ wsc->wsflags |= flag;
+ wsc->ws.ws_delim = arg;
+}
+
+static void
+setfn_comment (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ wsc->wsflags |= flag;
+ wsc->ws.ws_comment = arg;
}
static void
-help ()
+set_escape_string (wordsplit_t *ws, int *wsflags, int q, const char *str)
+{
+ if (*str == ':')
+ {
+ while (*++str != ':')
+ {
+ int f;
+ switch (*str)
+ {
+ case '+':
+ f = WRDSO_BSKEEP;
+ break;
+
+ case '0':
+ f = WRDSO_OESC;
+ break;
+
+ case 'x':
+ f = WRDSO_XESC;
+ break;
+
+ default:
+ fprintf (stderr, "%s: invalid escape flag near %s\n",
+ progname, str);
+ abort ();
+ }
+ WRDSO_ESC_SET (ws, q, f);
+ }
+ *wsflags |= WRDSF_OPTIONS;
+ ++str;
+ }
+ ws->ws_escape[q] = str;
+}
+
+static void
+setfn_escape (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ wsc->wsflags |= flag;
+ set_escape_string (&wsc->ws, &wsc->wsflags, 0, arg);
+ set_escape_string (&wsc->ws, &wsc->wsflags, 1, arg);
+}
+
+static void
+setfn_escape_qw (char *arg, int quote, struct wsclosure *wsc)
+{
+ if (!(wsc->wsflags & WRDSF_ESCAPE))
+ {
+ wsc->wsflags |= WRDSF_ESCAPE;
+ wsc->ws.ws_escape[!quote] = NULL;
+ }
+ set_escape_string (&wsc->ws, &wsc->wsflags, quote, arg);
+}
+
+static void
+setfn_escape_word (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ setfn_escape_qw (arg, 0, wsc);
+}
+
+static void
+setfn_escape_quote (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ setfn_escape_qw (arg, 1, wsc);
+}
+
+static void
+setfn_maxwords (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ char *p;
+
+ wsc->wsflags |= WRDSF_OPTIONS;
+ wsc->ws.ws_options |= WRDSO_MAXWORDS;
+
+ wsc->ws.ws_maxwords = strtoul (arg, &p, 10);
+ if (*p)
+ {
+ fprintf (stderr, "%s: invalid number: %s\n", progname, arg);
+ exit (1);
+ }
+}
+
+static void
+setfn_global (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ if (neg)
+ wsc->options &= ~flag;
+ else
+ wsc->options |= flag;
+}
+
+static void
+setfn_env (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ if (strcmp (arg, "none") == 0)
+ wsc->env_type = env_none;
+ else if (strcmp (arg, "null") == 0)
+ wsc->env_type = env_null;
+ else if (strcmp (arg, "sys") == 0)
+ wsc->env_type = env_sys;
+ else
+ {
+ fprintf (stderr, "%s: environment flag: %s\n", progname, arg);
+ exit (1);
+ }
+}
+
+static void
+setfn_dooffs (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ if (!(wsc->wsflags & flag))
+ {
+ wsc->wsflags |= flag;
+ wsc->offarg = wsoptind - 1;
+ wsc->ws.ws_offs = 0;
+ }
+ wsc->ws.ws_offs++;
+}
+
+static void
+setfn_append (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ if (wsc->append_count == 0)
+ wsc->append_start = wsoptind - 1;
+ wsc->append_count++;
+}
+
+static void help (void);
+
+static void
+setfn_help (int flag, int neg, char *arg, struct wsclosure *wsc)
+{
+ help ();
+ exit (0);
+}
+
+/* Available options: */
+struct wsopt opttab[] = {
+ /* Global options */
+ { "trimnl", TRIMNL_OPTION, ws_boolean, setfn_global },
+ { "plaintext", PLAINTEXT_OPTION, ws_boolean, setfn_global },
+ { "env", 0, ws_required_argument, setfn_env },
+
+ /* Wordsplit flags */
+ { "append", WRDSF_APPEND, ws_boolean, setfn_flag },
+ /*{ "reuse", WRDSF_REUSE, ws_boolean, setfn_flag },*/
+ { "undef", WRDSF_UNDEF, ws_boolean, setfn_flag },
+ { "novar", WRDSF_NOVAR, ws_boolean, setfn_flag },
+ { "nocmd", WRDSF_NOCMD, ws_boolean, setfn_flag },
+ { "ws", WRDSF_WS, ws_boolean, setfn_flag },
+ { "quote", WRDSF_QUOTE, ws_boolean, setfn_flag },
+ { "squote", WRDSF_SQUOTE, ws_boolean, setfn_flag },
+ { "dquote", WRDSF_DQUOTE, ws_boolean, setfn_flag },
+ { "squeeze_delims", WRDSF_SQUEEZE_DELIMS, ws_boolean, setfn_flag },
+ { "return_delims", WRDSF_RETURN_DELIMS, ws_boolean, setfn_flag },
+ { "sed", WRDSF_SED_EXPR, ws_boolean, setfn_flag },
+ { "debug", WRDSF_SHOWDBG, ws_boolean, setfn_flag },
+ { "nosplit", WRDSF_NOSPLIT, ws_boolean, setfn_flag },
+ { "keepundef", WRDSF_KEEPUNDEF, ws_boolean, setfn_flag },
+ { "warnundef", WRDSF_WARNUNDEF, ws_boolean, setfn_flag },
+ { "cescapes", WRDSF_CESCAPES, ws_boolean, setfn_flag },
+ { "default", WRDSF_DEFFLAGS, ws_boolean, setfn_flag },
+ { "env_kv", WRDSF_ENV_KV, ws_boolean, setfn_flag },
+ { "incremental", WRDSF_INCREMENTAL, ws_boolean, setfn_flag },
+ { "pathexpand", WRDSF_PATHEXPAND, ws_boolean, setfn_flag },
+ { "default", WRDSF_DEFFLAGS, ws_boolean, setfn_flag },
+ /* Wordsplit options */
+ { "nullglob", WRDSO_NULLGLOB, ws_boolean, setfn_option },
+ { "failglob", WRDSO_FAILGLOB, ws_boolean, setfn_option },
+ { "dotglob", WRDSO_DOTGLOB, ws_boolean, setfn_option },
+ { "bskeep_words", WRDSO_BSKEEP_WORD, ws_boolean, setfn_option },
+ { "bskeep_quote", WRDSO_BSKEEP_QUOTE, ws_boolean, setfn_option },
+ { "bskeep", WRDSO_BSKEEP_WORD|WRDSO_BSKEEP_QUOTE,
+ ws_boolean, setfn_option },
+ { "novarsplit", WRDSO_NOVARSPLIT, ws_boolean, setfn_option },
+ { "nocmdsplit", WRDSO_NOCMDSPLIT, ws_boolean, setfn_option },
+ { "maxwords", WRDSO_MAXWORDS, ws_required_argument, setfn_maxwords },
+ /* String options */
+ { "delim", WRDSF_DELIM, ws_required_argument, setfn_delim },
+ { "comment", WRDSF_COMMENT,ws_required_argument, setfn_comment },
+ { "escape", WRDSF_ESCAPE, ws_required_argument, setfn_escape },
+ { "escape-word", WRDSF_ESCAPE, ws_required_argument, setfn_escape_word },
+ { "escape-quote", WRDSF_ESCAPE, ws_required_argument, setfn_escape_quote },
+
+ { "dooffs", WRDSF_DOOFFS, ws_multiple_arguments, setfn_dooffs },
+ { "append-args", 0, ws_multiple_arguments, setfn_append },
+
+ { "help", 0, ws_no_argument, setfn_help },
+
+ { NULL, 0 }
+};
+
+static void
+help (void)
{
size_t i;
printf ("usage: %s [options] [VAR=VALUE...] [-- EXTRA...]\n", progname);
printf ("options are:\n");
- printf (" [-]trimnl\n");
- printf (" [-]plaintext\n");
- printf (" -env\n");
- printf (" env sys|none|null\n");
- putchar ('\n');
- for (i = 0; bool_keytab[i].name; i++)
- printf (" [-]%s\n", bool_keytab[i].name);
- putchar ('\n');
- for (i = 0; string_keytab[i].name; i++)
+ for (i = 0; opttab[i].name; i++)
{
- printf (" -%s\n", string_keytab[i].name);
- printf (" %s ARG\n", string_keytab[i].name);
- }
- printf (" escape-word ARG\n");
- printf (" escape-quote ARG\n");
- putchar ('\n');
- for (i = 0; opt_keytab[i].name; i++)
- {
- printf (" [-]%s\n", opt_keytab[i].name);
+ printf (" -");
+ if (opttab[i].arg == ws_boolean)
+ printf ("[no]");
+ if (strncmp (opttab[i].name, "no", 2) == 0)
+ printf ("%s", opttab[i].name + 2);
+ else
+ printf ("%s", opttab[i].name);
+ switch (opttab[i].arg)
+ {
+ case ws_no_argument:
+ case ws_boolean:
+ break;
+ case ws_required_argument:
+ printf(" ARG");
+ break;
+ case ws_multiple_arguments:
+ printf(" ARGS... --");
+ }
+ putchar ('\n');
}
putchar ('\n');
- printf (" -dooffs\n");
- printf (" dooffs COUNT ARGS...\n");
- exit (0);
}
void
@@ -299,326 +608,71 @@ wsp_runcmd (char **ret, const char *str, size_t len, char **argv, void *closure)
return WRDSE_USERERR;
}
-enum env_type
- {
- env_none,
- env_null,
- env_sys
- };
-
-struct kwd env_keytab[] = {
- { "none", env_none },
- { "null", env_null },
- { "sys", env_sys },
- { NULL }
-};
-
-static void
-set_escape_string (wordsplit_t *ws, int *wsflags, int q, const char *str)
-{
- if (*str == ':')
- {
- while (*++str != ':')
- {
- int f;
- switch (*str)
- {
- case '+':
- f = WRDSO_BSKEEP;
- break;
-
- case '0':
- f = WRDSO_OESC;
- break;
-
- case 'x':
- f = WRDSO_XESC;
- break;
-
- default:
- fprintf (stderr, "%s: invalid escape flag near %s\n",
- progname, str);
- abort ();
- }
- WRDSO_ESC_SET (ws, q, f);
- }
- *wsflags |= WRDSF_OPTIONS;
- ++str;
- }
- ws->ws_escape[q] = str;
-}
-
int
main (int argc, char **argv)
{
+ struct wsclosure wsc;
+ char *fenvbase[128];
char buf[1024], *ptr, *saved_ptr;
- int i, offarg = 0;
- int trimnl_option = 0;
- int plaintext_option = 0;
- int wsflags = (WRDSF_DEFFLAGS & ~WRDSF_NOVAR) |
+ int next_call = 0;
+
+ wsc.options = 0;
+ wsc.wsflags = 0;
+ wsc.env_type = env_sys;
+ wsc.offarg = 0;
+ wsc.fenvbase = fenvbase;
+ wsc.fenvmax = sizeof (fenvbase) / sizeof (fenvbase[0]);
+ wsc.fenvidx = 0;
+ wsc.ws.ws_options = 0;
+ wsc.wsflags = (WRDSF_DEFFLAGS & ~WRDSF_NOVAR) |
WRDSF_ENOMEMABRT |
WRDSF_SHOWERR;
- wordsplit_t ws;
- int next_call = 0;
- char *fenvbase[128];
- size_t fenvidx = 0;
- size_t fenvmax = sizeof (fenvbase) / sizeof (fenvbase[0]);
- int use_env = env_sys;
- int appendc = 0;
- char **appendv = NULL;
+ wsc.append_count = 0;
progname = argv[0];
+ while (getwsopt (argc, argv, opttab, &wsc) != EOF)
+ ;
- ws.ws_options = 0;
- for (i = 1; i < argc; i++)
+ if (wsc.fenvidx > 0)
{
- char *opt = argv[i];
- int negate;
- int flag;
-
- if (opt[0] == '-')
- {
- if (opt[1] == '-' && opt[2] == 0)
- {
- appendc = argc - i - 1;
- appendv = argv + i + 1;
- break;
- }
- negate = 1;
- opt++;
- }
- else if (opt[0] == '+')
- {
- negate = 0;
- opt++;
- }
- else
- negate = 0;
-
- if (strcmp (opt, "h") == 0 ||
- strcmp (opt, "help") == 0 ||
- strcmp (opt, "-help") == 0)
- {
- help ();
- }
-
- if (strcmp (opt, "trimnl") == 0)
- {
- trimnl_option = !negate;
- continue;
- }
-
- if (strcmp (opt, "plaintext") == 0)
- {
- plaintext_option = !negate;
- continue;
- }
-
- if (strcmp (opt, "env") == 0)
- {
- if (negate)
- use_env = env_none;
- else
- {
- i++;
- if (i == argc)
- {
- fprintf (stderr, "%s: missing argument for env\n",
- progname);
- exit (1);
- }
-
- if (kwxlat (env_keytab, argv[i], &use_env))
- {
- fprintf (stderr, "%s: invalid argument for env\n",
- progname);
- exit (1);
- }
- }
- continue;
- }
-
- if (kwxlat (bool_keytab, opt, &flag) == 0)
- {
- if (negate)
- wsflags &= ~flag;
- else
- wsflags |= flag;
- continue;
- }
-
- if (kwxlat (string_keytab, opt, &flag) == 0)
- {
- if (negate)
- wsflags &= ~flag;
- else
- {
- i++;
- if (i == argc)
- {
- fprintf (stderr, "%s: missing argument for %s\n",
- progname, opt);
- exit (1);
- }
-
- switch (flag)
- {
- case WRDSF_DELIM:
- ws.ws_delim = argv[i];
- break;
-
- case WRDSF_COMMENT:
- ws.ws_comment = argv[i];
- break;
-
- case WRDSF_ESCAPE:
- set_escape_string (&ws, &wsflags, 0, argv[i]);
- set_escape_string (&ws, &wsflags, 1, argv[i]);
- break;
- }
-
- wsflags |= flag;
- }
- continue;
- }
-
- if (strcmp (opt, "escape-word") == 0
- || strcmp (opt, "escape-quote") == 0)
- {
- int q = opt[7] == 'q';
-
- i++;
- if (i == argc)
- {
- fprintf (stderr, "%s: missing argument for %s\n",
- progname, opt);
- exit (1);
- }
- if (!(wsflags & WRDSF_ESCAPE))
- {
- wsflags |= WRDSF_ESCAPE;
- ws.ws_escape[!q] = NULL;
- }
- set_escape_string (&ws, &wsflags, q, argv[i]);
- continue;
- }
-
- if (strcmp (opt, "dooffs") == 0)
- {
- if (negate)
- wsflags &= ~WRDSF_DOOFFS;
- else
- {
- char *p;
-
- i++;
-
- if (i == argc)
- {
- fprintf (stderr, "%s: missing arguments for %s\n",
- progname, opt);
- exit (1);
- }
- ws.ws_offs = strtoul (argv[i], &p, 10);
- if (*p)
- {
- fprintf (stderr, "%s: invalid number: %s\n",
- progname, argv[i]);
- exit (1);
- }
-
- i++;
- if (i + ws.ws_offs > argc)
- {
- fprintf (stderr, "%s: not enough arguments for %s\n",
- progname, opt);
- exit (1);
- }
- offarg = i;
- i += ws.ws_offs - 1;
- wsflags |= WRDSF_DOOFFS;
- }
- continue;
- }
-
- if (kwxlat (opt_keytab, opt, &flag) == 0)
- {
- wsflags |= WRDSF_OPTIONS;
- if (negate)
- ws.ws_options &= ~flag;
- else
- ws.ws_options |= flag;
- continue;
- }
-
- if (strcmp (opt, "maxwords") == 0)
- {
- char *p;
- wsflags |= WRDSF_OPTIONS;
- ws.ws_options |= WRDSO_MAXWORDS;
-
- i++;
-
- if (i == argc)
- {
- fprintf (stderr, "%s: missing arguments for %s\n",
- progname, opt);
- exit (1);
- }
- ws.ws_maxwords = strtoul (argv[i], &p, 10);
- if (*p)
- {
- fprintf (stderr, "%s: invalid number: %s\n",
- progname, argv[i]);
- exit (1);
- }
- continue;
- }
-
- if (strchr (opt, '='))
- {
- assert (fenvidx < fenvmax - 1);
- fenvbase[fenvidx++] = opt;
- continue;
- }
-
- fprintf (stderr, "%s: unrecognized argument: %s\n",
- progname, opt);
- exit (1);
+ wsc.fenvbase[wsc.fenvidx] = NULL;
+ wsc.wsflags |= WRDSF_GETVAR | WRDSF_CLOSURE;
+ wsc.ws.ws_getvar = wsp_getvar;
+ wsc.ws.ws_closure = fenvbase;
}
- if (fenvidx)
+ if (wsoptind < argc)
{
- fenvbase[fenvidx] = NULL;
- wsflags |= WRDSF_GETVAR | WRDSF_CLOSURE;
- ws.ws_getvar = wsp_getvar;
- ws.ws_closure = fenvbase;
+ wsc.ws.ws_paramc = argc - wsoptind;
+ wsc.ws.ws_paramv = (char const **) (argv + wsoptind);
+ wsc.ws.ws_options |= WRDSO_PARAMV|WRDSO_PARAM_NEGIDX;
+ wsc.wsflags |= WRDSF_OPTIONS;
}
- switch (use_env)
+ switch (wsc.env_type)
{
case env_null:
- wsflags |= WRDSF_ENV;
- ws.ws_env = NULL;
+ wsc.wsflags |= WRDSF_ENV;
+ wsc.ws.ws_env = NULL;
break;
case env_none:
break;
case env_sys:
- wsflags |= WRDSF_ENV;
- if (wsflags & WRDSF_ENV_KV)
- ws.ws_env = (const char **) make_env_kv ();
+ wsc.wsflags |= WRDSF_ENV;
+ if (wsc.wsflags & WRDSF_ENV_KV)
+ wsc.ws.ws_env = (const char **) make_env_kv ();
else
- ws.ws_env = (const char **) environ;
+ wsc.ws.ws_env = (const char **) environ;
break;
}
- if (!(wsflags & WRDSF_NOCMD))
- ws.ws_command = wsp_runcmd;
+ if (!(wsc.wsflags & WRDSF_NOCMD))
+ wsc.ws.ws_command = wsp_runcmd;
- if (wsflags & WRDSF_INCREMENTAL)
- trimnl_option = 1;
+ if (wsc.wsflags & WRDSF_INCREMENTAL)
+ wsc.options |= TRIMNL_OPTION;
next_call = 0;
while ((ptr = fgets (buf, sizeof (buf), stdin)))
@@ -626,14 +680,14 @@ main (int argc, char **argv)
int rc;
size_t i;
- if (trimnl_option)
+ if (wsc.options & TRIMNL_OPTION)
{
size_t len = strlen (ptr);
if (len && ptr[len-1] == '\n')
ptr[len-1] = 0;
}
- if (wsflags & WRDSF_INCREMENTAL)
+ if (wsc.wsflags & WRDSF_INCREMENTAL)
{
if (next_call)
{
@@ -651,50 +705,52 @@ main (int argc, char **argv)
}
}
- rc = wordsplit (ptr, &ws, wsflags);
+ rc = wordsplit (ptr, &wsc.ws, wsc.wsflags);
if (rc)
{
- if (!(wsflags & WRDSF_SHOWERR))
- wordsplit_perror (&ws);
+ if (!(wsc.wsflags & WRDSF_SHOWERR))
+ wordsplit_perror (&wsc.ws);
continue;
}
- if (offarg)
+ if (wsc.offarg)
{
- for (i = 0; i < ws.ws_offs; i++)
- ws.ws_wordv[i] = argv[offarg + i];
- offarg = 0;
+ size_t i;
+ for (i = 0; i < wsc.ws.ws_offs; i++)
+ wsc.ws.ws_wordv[i] = argv[wsc.offarg + i];
+ wsc.offarg = 0;
}
- if (appendc)
+ if (wsc.append_count)
{
- rc = wordsplit_append (&ws, appendc, appendv);
+ rc = wordsplit_append (&wsc.ws, wsc.append_count,
+ argv + wsc.append_start);
if (rc)
{
- if (!(wsflags & WRDSF_SHOWERR))
- wordsplit_perror (&ws);
+ if (!(wsc.wsflags & WRDSF_SHOWERR))
+ wordsplit_perror (&wsc.ws);
continue;
}
}
- wsflags |= WRDSF_REUSE | (ws.ws_flags & WRDSF_ENV);
- printf ("NF: %lu", (unsigned long) ws.ws_wordc);
- if (wsflags & WRDSF_DOOFFS)
- printf (" (%lu)", (unsigned long) ws.ws_offs);
+ wsc.wsflags |= WRDSF_REUSE;
+ printf ("NF: %lu", (unsigned long) wsc.ws.ws_wordc);
+ if (wsc.wsflags & WRDSF_DOOFFS)
+ printf (" (%lu)", (unsigned long) wsc.ws.ws_offs);
putchar ('\n');
- for (i = 0; i < ws.ws_offs; i++)
+ for (i = 0; i < wsc.ws.ws_offs; i++)
{
printf ("(%lu): ", (unsigned long) i);
- print_qword (ws.ws_wordv[i], plaintext_option);
+ print_qword (wsc.ws.ws_wordv[i], wsc.options & PLAINTEXT_OPTION);
putchar ('\n');
}
- for (; i < ws.ws_offs + ws.ws_wordc; i++)
+ for (; i < wsc.ws.ws_offs + wsc.ws.ws_wordc; i++)
{
printf ("%lu: ", (unsigned long) i);
- print_qword (ws.ws_wordv[i], plaintext_option);
+ print_qword (wsc.ws.ws_wordv[i], wsc.options & PLAINTEXT_OPTION);
putchar ('\n');
}
- printf ("TOTAL: %lu\n", (unsigned long) ws.ws_wordi);
+ printf ("TOTAL: %lu\n", (unsigned long) wsc.ws.ws_wordi);
}
return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.