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,3 +1,3 @@
1/* grecs - Gray's Extensible Configuration System 1/* grecs - Gray's Extensible Configuration System
2 Copyright (C) 2014-2016 Sergey Poznyakoff 2 Copyright (C) 2014-2019 Sergey Poznyakoff
3 3
@@ -31,62 +31,180 @@ char *progname;
31 31
32struct kwd 32/* Global options */
33enum
34 {
35 TRIMNL_OPTION = 0x01, /* Remove trailing newline */
36 PLAINTEXT_OPTION = 0x02 /* Print intput verbatim (no escapes) */
37 };
38
39/* Environment types */
40enum env_type
41 {
42 env_none, /* No environment */
43 env_null, /* Null environment */
44 env_sys /* Use system environment */
45 };
46
47struct wsclosure
33{ 48{
34 const char *name; 49 int options; /* Global options */
35 int tok; 50 struct wordsplit ws; /* The wordsplit structure */
51 int wsflags; /* Wordsplit flags */
52 enum env_type env_type; /* Environment type */
53 int offarg; /* Index of the first of the initial words in
54 the argv array. The ws.ws_dooffs field gives
55 the number of such variables. Forces the
56 WRDSF_DOOFFS flag. */
57 char **fenvbase; /* Environment for testing the ws_getenv function */
58 int fenvidx; /* Number of variables in fenvbase */
59 int fenvmax; /* Size of fenbase (entries) */
60 int append_start; /* First argument to append (index in argv) */
61 int append_count; /* Number of arguments to append */
36}; 62};
37 63
38struct kwd bool_keytab[] = { 64/* Command line option types */
39 { "append", WRDSF_APPEND }, 65enum
40 /*{ "reuse", WRDSF_REUSE },*/ 66 {
41 { "undef", WRDSF_UNDEF }, 67 ws_no_argument, /* Option requires no arguments */
42 { "novar", WRDSF_NOVAR }, 68 ws_boolean, /* Option is boolean (can be prefixed with -no) */
43 { "nocmd", WRDSF_NOCMD }, 69 ws_required_argument, /* Option requires one argument */
44 { "ws", WRDSF_WS }, 70 ws_multiple_arguments /* Option takes multiple arguments, terminated with
45 { "quote", WRDSF_QUOTE }, 71 "--" or end of argument list */
46 { "squote", WRDSF_SQUOTE }, 72 };
47 { "dquote", WRDSF_DQUOTE },
48 { "squeeze_delims", WRDSF_SQUEEZE_DELIMS },
49 { "return_delims", WRDSF_RETURN_DELIMS },
50 { "sed", WRDSF_SED_EXPR },
51 { "debug", WRDSF_SHOWDBG },
52 { "nosplit", WRDSF_NOSPLIT },
53 { "keepundef", WRDSF_KEEPUNDEF },
54 { "warnundef", WRDSF_WARNUNDEF },
55 { "cescapes", WRDSF_CESCAPES },
56 { "default", WRDSF_DEFFLAGS },
57 { "env_kv", WRDSF_ENV_KV },
58 { "incremental", WRDSF_INCREMENTAL },
59 { "pathexpand", WRDSF_PATHEXPAND },
60 { NULL, 0 }
61};
62 73
63struct kwd opt_keytab[] = { 74/* Structure describing a single command-line option */
64 { "nullglob", WRDSO_NULLGLOB }, 75struct wsopt
65 { "failglob", WRDSO_FAILGLOB }, 76{
66 { "dotglob", WRDSO_DOTGLOB }, 77 const char *name; /* Option name */
67 { "bskeep_words", WRDSO_BSKEEP_WORD }, 78 int tok; /* Corresponding flag */
68 { "bskeep_quote", WRDSO_BSKEEP_QUOTE }, 79 int arg; /* Option type (see the enum above) */
69 { "bskeep", WRDSO_BSKEEP_WORD|WRDSO_BSKEEP_QUOTE }, 80 void (*setfn) (int tok, int neg, char *arg, struct wsclosure *wsc);
70 { "novarsplit", WRDSO_NOVARSPLIT }, 81 /* Setter function */
71 { "nocmdsplit", WRDSO_NOCMDSPLIT },
72 { NULL, 0 }
73}; 82};
74 83
75struct kwd string_keytab[] = { 84/* Index of the next argument in the argv */
76 { "delim", WRDSF_DELIM }, 85static int wsoptind = -1;
77 { "comment", WRDSF_COMMENT },
78 { "escape", WRDSF_ESCAPE },
79 { NULL, 0 }
80};
81 86
87/* Parse next argument from the command line. Return EOF on end of arguments
88 or when the "--" argument is seen. */
82static int 89static int
83kwxlat (struct kwd *kwp, const char *str, int *res) 90getwsopt (int argc, char **argv, struct wsopt *wso, struct wsclosure *wsc)
84{ 91{
85 for (; kwp->name; kwp++) 92 int negate = 0;
86 if (strcmp (kwp->name, str) == 0) 93 char *opt;
87 { 94
88 *res = kwp->tok; 95 if (wsoptind == -1)
89 return 0; 96 wsoptind = 1;
90 } 97 if (wsoptind == argc)
91 return -1; 98 return EOF;
99
100 opt = argv[wsoptind++];
101 if (strcmp (opt, "--") == 0)
102 return EOF;
103 if (*opt != '-')
104 {
105 if (strchr (opt, '='))
106 {
107 assert (wsc->fenvidx < wsc->fenvmax - 1);
108 wsc->fenvbase[wsc->fenvidx++] = opt;
109 return 0;
110 }
111 wsoptind--;
112 return EOF;
113 }
114 opt++; /* skip past initial dash */
115 if (strncmp (opt, "no-", 3) == 0)
116 {
117 negate = 1;
118 opt += 3;
119 }
120 else if (strncmp (opt, "no", 2) == 0)
121 {
122 negate = 1;
123 opt += 2;
124 }
125
126 for (; wso->name; wso++)
127 {
128 if (wso->arg == ws_boolean && wso->name[0] == 'n' && wso->name[1] == 'o'
129 && strcmp (wso->name + 2, opt) == 0)
130 {
131 negate ^= 1;
132 break;
133 }
134 if (strcmp (wso->name, opt) == 0)
135 break;
136 }
137
138 if (wso->name)
139 {
140 char *arg;
141 if (wso->arg == ws_multiple_arguments)
142 {
143 while (1)
144 {
145 if (wsoptind == argc)
146 break;
147 arg = argv[wsoptind++];
148 if (strcmp (arg, "--") == 0)
149 break;
150 wso->setfn (wso->tok, negate, arg, wsc);
151 }
152 }
153 else
154 {
155 if (wso->arg == ws_required_argument)
156 {
157 if (wsoptind == argc)
158 {
159 fprintf (stderr, "%s: missing arguments for -%s\n",
160 progname, opt);
161 exit (1);
162 }
163 arg = argv[wsoptind++];
164 }
165 wso->setfn (wso->tok, negate, arg, wsc);
166 }
167 return 0;
168 }
169
170 fprintf (stderr, "%s: unrecognized option: -%s\n",
171 progname, opt);
172 fprintf (stderr, "%s: try %s -help for more detail\n",
173 progname, progname);
174 exit (1);
175}
176
177/* Setter functions for various options */
178
179static void
180setfn_flag (int flag, int neg, char *arg, struct wsclosure *wsc)
181{
182 if (neg)
183 wsc->wsflags &= ~flag;
184 else
185 wsc->wsflags |= flag;
186}
187
188static void
189setfn_option (int flag, int neg, char *arg, struct wsclosure *wsc)
190{
191 wsc->wsflags |= WRDSF_OPTIONS;
192 if (neg)
193 wsc->ws.ws_options &= ~flag;
194 else
195 wsc->ws.ws_options |= flag;
196}
197
198static void
199setfn_delim (int flag, int neg, char *arg, struct wsclosure *wsc)
200{
201 wsc->wsflags |= flag;
202 wsc->ws.ws_delim = arg;
203}
204
205static void
206setfn_comment (int flag, int neg, char *arg, struct wsclosure *wsc)
207{
208 wsc->wsflags |= flag;
209 wsc->ws.ws_comment = arg;
92} 210}
@@ -94,3 +212,195 @@ kwxlat (struct kwd *kwp, const char *str, int *res)
94static void 212static void
95help () 213set_escape_string (wordsplit_t *ws, int *wsflags, int q, const char *str)
214{
215 if (*str == ':')
216 {
217 while (*++str != ':')
218 {
219 int f;
220 switch (*str)
221 {
222 case '+':
223 f = WRDSO_BSKEEP;
224 break;
225
226 case '0':
227 f = WRDSO_OESC;
228 break;