3 #include <ccan/tap/tap.h>
9 /* We don't actually want it to exit... */
10 static jmp_buf exited;
11 #define exit(status) longjmp(exited, (status) + 1)
13 #define printf saved_printf
14 static int saved_printf(const char *fmt, ...);
16 #define fprintf saved_fprintf
17 static int saved_fprintf(FILE *ignored, const char *fmt, ...);
19 #define vfprintf(f, fmt, ap) saved_vprintf(fmt, ap)
20 static int saved_vprintf(const char *fmt, va_list ap);
22 #define malloc(size) saved_malloc(size)
23 static void *saved_malloc(size_t size);
25 #include <ccan/opt/helpers.c>
26 #include <ccan/opt/opt.c>
27 #include <ccan/opt/usage.c>
28 #include <ccan/opt/parse.c>
30 static void reset_options(void)
34 opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0;
37 static char *output = NULL;
39 static int saved_vprintf(const char *fmt, va_list ap)
42 int ret = vasprintf(&p, fmt, ap);
45 output = realloc(output, strlen(output) + strlen(p) + 1);
53 static int saved_printf(const char *fmt, ...)
59 ret = saved_vprintf(fmt, ap);
64 static int saved_fprintf(FILE *ignored, const char *fmt, ...)
70 ret = saved_vprintf(fmt, ap);
76 static void *last_allocation;
77 static void *saved_malloc(size_t size)
79 return last_allocation = malloc(size);
83 int main(int argc, char *argv[])
91 opt_register_noarg("-a", opt_set_bool, &arg, "");
92 ok1(parse_args(&argc, &argv, "-a", NULL));
94 opt_register_arg("-b", opt_set_bool_arg, NULL, &arg, "");
95 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
97 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
99 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
101 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
103 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
105 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
107 /* opt_set_invbool */
111 opt_register_noarg("-a", opt_set_invbool, &arg, "");
112 ok1(parse_args(&argc, &argv, "-a", NULL));
114 opt_register_arg("-b", opt_set_invbool_arg, NULL,
116 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
118 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
120 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
122 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
124 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
126 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
130 char *arg = (char *)"wrong";
132 opt_register_arg("-a", opt_set_charp, NULL, &arg, "All");
133 ok1(parse_args(&argc, &argv, "-a", "string", NULL));
134 ok1(strcmp(arg, "string") == 0);
140 opt_register_arg("-a", opt_set_intval, NULL, &arg, "All");
141 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
143 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
145 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
147 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
148 if (sizeof(int) == 4)
149 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
151 fail("Handle other int sizes");
153 /* opt_set_uintval */
155 unsigned int arg = 1000;
157 opt_register_arg("-a", opt_set_uintval, NULL, &arg, "All");
158 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
160 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
161 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
163 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
164 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
165 if (ULONG_MAX == UINT_MAX) {
166 pass("Can't test overflow");
167 pass("Can't test error message");
170 sprintf(buf, "%lu", ULONG_MAX);
171 ok1(!parse_args(&argc, &argv, "-a", buf, NULL));
172 ok1(strstr(err_output, ": -a: value '")
173 && strstr(err_output, buf)
174 && strstr(err_output, "' does not fit into an integer"));
177 /* opt_set_longval */
181 opt_register_arg("-a", opt_set_longval, NULL, &arg, "All");
182 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
184 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
186 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
188 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
189 if (sizeof(long) == 4)
190 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
191 else if (sizeof(long)== 8)
192 ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
194 fail("FIXME: Handle other long sizes");
196 /* opt_set_ulongval */
198 unsigned long int arg = 1000;
200 opt_register_arg("-a", opt_set_ulongval, NULL, &arg, "All");
201 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
203 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
204 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
206 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
207 if (sizeof(long) == 4)
208 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
209 else if (sizeof(long)== 8)
210 ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
212 fail("FIXME: Handle other long sizes");
218 opt_register_noarg("-a", opt_inc_intval, &arg, "");
219 ok1(parse_args(&argc, &argv, "-a", NULL));
221 ok1(parse_args(&argc, &argv, "-a", "-a", NULL));
223 ok1(parse_args(&argc, &argv, "-aa", NULL));
227 /* opt_show_version_and_exit. */
231 opt_register_noarg("-a",
232 opt_version_and_exit, "1.2.3", "");
233 /* parse_args allocates argv */
237 argv = malloc(sizeof(argv[0]) * 3);
238 argv[0] = "thisprog";
242 exitval = setjmp(exited);
244 opt_parse(&argc, argv, save_err_output);
245 fail("opt_show_version_and_exit returned?");
247 ok1(exitval - 1 == 0);
249 ok1(strcmp(output, "1.2.3\n") == 0);
255 /* opt_usage_and_exit. */
259 opt_register_noarg("-a",
260 opt_usage_and_exit, "[args]", "");
263 argv = malloc(sizeof(argv[0]) * 3);
264 argv[0] = "thisprog";
268 exitval = setjmp(exited);
270 opt_parse(&argc, argv, save_err_output);
271 fail("opt_usage_and_exit returned?");
273 ok1(exitval - 1 == 0);
275 ok1(strstr(output, "[args]"));
276 ok1(strstr(output, argv[0]));
277 ok1(strstr(output, "[-a]"));
280 /* It exits without freeing usage string. */
281 free(last_allocation);
288 char buf[OPT_SHOW_LEN+2] = { 0 };
289 buf[OPT_SHOW_LEN] = '!';
292 opt_show_bool(buf, &b);
293 ok1(strcmp(buf, "true") == 0);
294 ok1(buf[OPT_SHOW_LEN] == '!');
297 opt_show_bool(buf, &b);
298 ok1(strcmp(buf, "false") == 0);
299 ok1(buf[OPT_SHOW_LEN] == '!');
302 /* opt_show_invbool */
305 char buf[OPT_SHOW_LEN+2] = { 0 };
306 buf[OPT_SHOW_LEN] = '!';
309 opt_show_invbool(buf, &b);
310 ok1(strcmp(buf, "false") == 0);
311 ok1(buf[OPT_SHOW_LEN] == '!');
314 opt_show_invbool(buf, &b);
315 ok1(strcmp(buf, "true") == 0);
316 ok1(buf[OPT_SHOW_LEN] == '!');
321 char str[OPT_SHOW_LEN*2], *p;
322 char buf[OPT_SHOW_LEN+2] = { 0 };
323 buf[OPT_SHOW_LEN] = '!';
328 opt_show_charp(buf, &p);
329 ok1(strcmp(buf, "\"short\"") == 0);
330 ok1(buf[OPT_SHOW_LEN] == '!');
333 memset(p, 'x', OPT_SHOW_LEN*2);
334 p[OPT_SHOW_LEN*2-1] = '\0';
335 opt_show_charp(buf, &p);
337 ok1(buf[OPT_SHOW_LEN-1] == '"');
338 ok1(buf[OPT_SHOW_LEN] == '!');
339 ok1(strspn(buf+1, "x") == OPT_SHOW_LEN-2);
342 /* opt_show_intval */
345 char buf[OPT_SHOW_LEN+2] = { 0 };
346 buf[OPT_SHOW_LEN] = '!';
349 opt_show_intval(buf, &i);
350 ok1(strcmp(buf, "-77") == 0);
351 ok1(buf[OPT_SHOW_LEN] == '!');
354 opt_show_intval(buf, &i);
355 ok1(strcmp(buf, "77") == 0);
356 ok1(buf[OPT_SHOW_LEN] == '!');
359 /* opt_show_uintval */
362 char buf[OPT_SHOW_LEN+2] = { 0 };
363 buf[OPT_SHOW_LEN] = '!';
366 opt_show_uintval(buf, &ui);
367 ok1(strcmp(buf, "4294967295") == 0);
368 ok1(buf[OPT_SHOW_LEN] == '!');
371 /* opt_show_longval */
374 char buf[OPT_SHOW_LEN+2] = { 0 };
375 buf[OPT_SHOW_LEN] = '!';
378 opt_show_longval(buf, &l);
379 ok1(strcmp(buf, "1234567890") == 0);
380 ok1(buf[OPT_SHOW_LEN] == '!');
383 /* opt_show_ulongval */
386 char buf[OPT_SHOW_LEN+2] = { 0 };
387 buf[OPT_SHOW_LEN] = '!';
390 opt_show_ulongval(buf, &ul);
391 ok1(strcmp(buf, "4294967295") == 0);
392 ok1(buf[OPT_SHOW_LEN] == '!');
395 /* opt_log_stderr. */
398 opt_register_noarg("-a",
399 opt_usage_and_exit, "[args]", "");
402 argv = malloc(sizeof(argv[0]) * 3);
403 argv[0] = "thisprog";
404 argv[1] = "--garbage";
406 ok1(!opt_parse(&argc, argv, opt_log_stderr));
408 "thisprog: --garbage: unrecognized option\n"));
414 /* opt_log_stderr_exit. */
418 opt_register_noarg("-a",
419 opt_usage_and_exit, "[args]", "");
421 argv = malloc(sizeof(argv[0]) * 3);
422 argv[0] = "thisprog";
423 argv[1] = "--garbage";
425 exitval = setjmp(exited);
427 opt_parse(&argc, argv, opt_log_stderr_exit);
428 fail("opt_log_stderr_exit returned?");
430 ok1(exitval - 1 == 1);
434 "thisprog: --garbage: unrecognized option\n"));
439 return exit_status();