1 #include <ccan/tap/tap.h>
4 /* Make sure we override these! */
5 static void *no_malloc(size_t size)
9 static void *no_realloc(void *p, size_t size)
13 static void no_free(void *p)
17 #define malloc no_malloc
18 #define realloc no_realloc
21 #include <ccan/opt/opt.c>
22 #include <ccan/opt/usage.c>
23 #include <ccan/opt/helpers.c>
24 #include <ccan/opt/parse.c>
31 static unsigned int alloc_count, realloc_count, free_count;
32 static void *ptrs[100];
34 static void **find_ptr(void *p)
38 for (i = 0; i < 100; i++)
44 static void *allocfn(size_t size)
47 return *find_ptr(NULL) = malloc(size);
50 static void *reallocfn(void *ptr, size_t size)
56 return *find_ptr(ptr) = realloc(ptr, size);
59 static void freefn(void *ptr)
63 *find_ptr(ptr) = NULL;
66 int main(int argc, char *argv[])
68 const char *myname = argv[0];
72 opt_set_alloc(allocfn, reallocfn, freefn);
74 /* Simple short arg.*/
75 opt_register_noarg("-a", test_noarg, NULL, "All");
76 ok1(parse_args(&argc, &argv, "-a", NULL));
78 ok1(argv[0] == myname);
80 ok1(test_cb_called == 1);
82 /* Simple long arg. */
83 opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
84 ok1(parse_args(&argc, &argv, "--aaa", NULL));
86 ok1(argv[0] == myname);
88 ok1(test_cb_called == 2);
90 /* Both long and short args. */
91 opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll");
92 ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL));
94 ok1(argv[0] == myname);
96 ok1(test_cb_called == 4);
98 /* Extra arguments preserved. */
99 ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
101 ok1(argv[0] == myname);
102 ok1(strcmp(argv[1], "extra") == 0);
103 ok1(strcmp(argv[2], "args") == 0);
104 ok1(test_cb_called == 6);
106 /* Malformed versions. */
107 ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL));
108 ok1(strstr(err_output, ": --aaa: doesn't allow an argument"));
109 ok1(!parse_args(&argc, &argv, "--aa", NULL));
110 ok1(strstr(err_output, ": --aa: unrecognized option"));
111 ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
112 ok1(strstr(err_output, ": --aaargh: unrecognized option"));
114 /* Argument variants. */
117 opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
118 ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
120 ok1(argv[0] == myname);
121 ok1(test_cb_called == 1);
123 ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
125 ok1(argv[0] == myname);
126 ok1(test_cb_called == 2);
128 ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
130 ok1(argv[0] == myname);
131 ok1(test_cb_called == 3);
133 /* Malformed versions. */
134 ok1(!parse_args(&argc, &argv, "-a", NULL));
135 ok1(strstr(err_output, ": -a: requires an argument"));
136 ok1(!parse_args(&argc, &argv, "--aaa", NULL));
137 ok1(strstr(err_output, ": --aaa: requires an argument"));
138 ok1(!parse_args(&argc, &argv, "--aa", NULL));
139 ok1(strstr(err_output, ": --aa: unrecognized option"));
140 ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
141 ok1(strstr(err_output, ": --aaargh: unrecognized option"));
147 opt_register_table(short_table, NULL);
148 ok1(parse_args(&argc, &argv, "-a", NULL));
150 ok1(argv[0] == myname);
151 ok1(argv[1] == NULL);
152 ok1(test_cb_called == 1);
153 /* This one needs an arg. */
154 ok1(parse_args(&argc, &argv, "-b", NULL) == false);
155 ok1(test_cb_called == 1);
156 ok1(parse_args(&argc, &argv, "-b", "b", NULL));
158 ok1(argv[0] == myname);
159 ok1(argv[1] == NULL);
160 ok1(test_cb_called == 2);
165 opt_register_table(long_table, NULL);
166 ok1(parse_args(&argc, &argv, "--ddd", NULL));
168 ok1(argv[0] == myname);
169 ok1(argv[1] == NULL);
170 ok1(test_cb_called == 1);
171 /* This one needs an arg. */
172 ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
173 ok1(test_cb_called == 1);
174 ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
176 ok1(argv[0] == myname);
177 ok1(argv[1] == NULL);
178 ok1(test_cb_called == 2);
180 /* Short and long, both. */
183 opt_register_table(long_and_short_table, NULL);
184 ok1(parse_args(&argc, &argv, "-g", NULL));
186 ok1(argv[0] == myname);
187 ok1(argv[1] == NULL);
188 ok1(test_cb_called == 1);
189 ok1(parse_args(&argc, &argv, "--ggg", NULL));
191 ok1(argv[0] == myname);
192 ok1(argv[1] == NULL);
193 ok1(test_cb_called == 2);
194 /* This one needs an arg. */
195 ok1(parse_args(&argc, &argv, "-h", NULL) == false);
196 ok1(test_cb_called == 2);
197 ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
199 ok1(argv[0] == myname);
200 ok1(argv[1] == NULL);
201 ok1(test_cb_called == 3);
202 ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
203 ok1(test_cb_called == 3);
204 ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
206 ok1(argv[0] == myname);
207 ok1(argv[1] == NULL);
208 ok1(test_cb_called == 4);
210 /* Those will all work as tables. */
213 opt_register_table(subtables, NULL);
214 ok1(parse_args(&argc, &argv, "-a", NULL));
216 ok1(argv[0] == myname);
217 ok1(argv[1] == NULL);
218 ok1(test_cb_called == 1);
219 /* This one needs an arg. */
220 ok1(parse_args(&argc, &argv, "-b", NULL) == false);
221 ok1(test_cb_called == 1);
222 ok1(parse_args(&argc, &argv, "-b", "b", NULL));
224 ok1(argv[0] == myname);
225 ok1(argv[1] == NULL);
226 ok1(test_cb_called == 2);
228 ok1(parse_args(&argc, &argv, "--ddd", NULL));
230 ok1(argv[0] == myname);
231 ok1(argv[1] == NULL);
232 ok1(test_cb_called == 3);
233 /* This one needs an arg. */
234 ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
235 ok1(test_cb_called == 3);
236 ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
238 ok1(argv[0] == myname);
239 ok1(argv[1] == NULL);
240 ok1(test_cb_called == 4);
242 /* Short and long, both. */
243 ok1(parse_args(&argc, &argv, "-g", NULL));
245 ok1(argv[0] == myname);
246 ok1(argv[1] == NULL);
247 ok1(test_cb_called == 5);
248 ok1(parse_args(&argc, &argv, "--ggg", NULL));
250 ok1(argv[0] == myname);
251 ok1(argv[1] == NULL);
252 ok1(test_cb_called == 6);
253 /* This one needs an arg. */
254 ok1(parse_args(&argc, &argv, "-h", NULL) == false);
255 ok1(test_cb_called == 6);
256 ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
258 ok1(argv[0] == myname);
259 ok1(argv[1] == NULL);
260 ok1(test_cb_called == 7);
261 ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
262 ok1(test_cb_called == 7);
263 ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
265 ok1(argv[0] == myname);
266 ok1(argv[1] == NULL);
267 ok1(test_cb_called == 8);
269 /* Now the tricky one: -? must not be confused with an unknown option */
273 /* glibc's getopt does not handle ? with arguments. */
274 opt_register_noarg("-?", test_noarg, NULL, "Help");
275 ok1(parse_args(&argc, &argv, "-?", NULL));
276 ok1(test_cb_called == 1);
277 ok1(parse_args(&argc, &argv, "-a", NULL) == false);
278 ok1(test_cb_called == 1);
279 ok1(strstr(err_output, ": -a: unrecognized option"));
280 ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false);
281 ok1(test_cb_called == 1);
282 ok1(strstr(err_output, ": --aaaa: unrecognized option"));
287 /* Corner cases involving short arg parsing weirdness. */
288 opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
289 opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b");
290 opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c");
292 ok1(parse_args(&argc, &argv, "-aa", NULL));
293 ok1(test_cb_called == 2);
294 ok1(parse_args(&argc, &argv, "-aab", NULL) == false);
295 ok1(test_cb_called == 4);
296 ok1(strstr(err_output, ": -b: requires an argument"));
297 ok1(parse_args(&argc, &argv, "-bbbb", NULL));
298 ok1(test_cb_called == 5);
299 ok1(parse_args(&argc, &argv, "-aabbbb", NULL));
300 ok1(test_cb_called == 8);
301 ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL));
302 ok1(test_cb_called == 12);
303 ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL));
304 ok1(test_cb_called == 16);
305 ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL));
306 ok1(test_cb_called == 20);
307 ok1(parse_args(&argc, &argv, "-aacaaa", NULL));
308 ok1(test_cb_called == 23);
309 ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL));
310 ok1(test_cb_called == 27);
311 ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa",
313 ok1(test_cb_called == 34);
318 /* -- and POSIXLY_CORRECT */
319 opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
320 ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL));
321 ok1(test_cb_called == 1);
323 ok1(strcmp(argv[1], "-a") == 0);
326 unsetenv("POSIXLY_CORRECT");
327 ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
328 ok1(test_cb_called == 3);
330 ok1(strcmp(argv[1], "somearg") == 0);
331 ok1(strcmp(argv[2], "-a") == 0);
334 setenv("POSIXLY_CORRECT", "1", 1);
335 ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
336 ok1(test_cb_called == 4);
338 ok1(strcmp(argv[1], "somearg") == 0);
339 ok1(strcmp(argv[2], "-a") == 0);
340 ok1(strcmp(argv[3], "--") == 0);
341 ok1(strcmp(argv[4], "-a") == 0);
344 /* We should have tested each one at least once! */
349 ok1(free_count < alloc_count);
351 ok1(free_count == alloc_count);
353 /* parse_args allocates argv */
355 return exit_status();