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 #include <ccan/opt/helpers.c>
23 #include <ccan/opt/opt.c>
24 #include <ccan/opt/usage.c>
26 static void reset_options(void)
30 opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0;
33 static char *output = NULL;
35 static int saved_vprintf(const char *fmt, va_list ap)
38 int ret = vasprintf(&p, fmt, ap);
41 output = realloc(output, strlen(output) + strlen(p) + 1);
49 static int saved_printf(const char *fmt, ...)
55 ret = saved_vprintf(fmt, ap);
60 static int saved_fprintf(FILE *ignored, const char *fmt, ...)
66 ret = saved_vprintf(fmt, ap);
72 int main(int argc, char *argv[])
80 opt_register_noarg("-a", opt_set_bool, &arg, "");
81 ok1(parse_args(&argc, &argv, "-a", NULL));
83 opt_register_arg("-b", opt_set_bool_arg, NULL, &arg, "");
84 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
86 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
88 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
90 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
92 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
94 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
100 opt_register_noarg("-a", opt_set_invbool, &arg, "");
101 ok1(parse_args(&argc, &argv, "-a", NULL));
103 opt_register_arg("-b", opt_set_invbool_arg, NULL,
105 ok1(parse_args(&argc, &argv, "-b", "no", NULL));
107 ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
109 ok1(parse_args(&argc, &argv, "-b", "false", NULL));
111 ok1(parse_args(&argc, &argv, "-b", "true", NULL));
113 ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
115 ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
119 char *arg = (char *)"wrong";
121 opt_register_arg("-a", opt_set_charp, NULL, &arg, "All");
122 ok1(parse_args(&argc, &argv, "-a", "string", NULL));
123 ok1(strcmp(arg, "string") == 0);
129 opt_register_arg("-a", opt_set_intval, NULL, &arg, "All");
130 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
132 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
134 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
136 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
137 if (sizeof(int) == 4)
138 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
140 fail("Handle other int sizes");
142 /* opt_set_uintval */
144 unsigned int arg = 1000;
146 opt_register_arg("-a", opt_set_uintval, NULL, &arg, "All");
147 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
149 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
150 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
152 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
153 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
154 if (ULONG_MAX == UINT_MAX) {
155 pass("Can't test overflow");
156 pass("Can't test error message");
159 sprintf(buf, "%lu", ULONG_MAX);
160 ok1(!parse_args(&argc, &argv, "-a", buf, NULL));
161 ok1(strstr(err_output, ": -a: value '")
162 && strstr(err_output, buf)
163 && strstr(err_output, "' does not fit into an integer"));
166 /* opt_set_longval */
170 opt_register_arg("-a", opt_set_longval, NULL, &arg, "All");
171 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
173 ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
175 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
177 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
178 if (sizeof(long) == 4)
179 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
180 else if (sizeof(long)== 8)
181 ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
183 fail("FIXME: Handle other long sizes");
185 /* opt_set_ulongval */
187 unsigned long int arg = 1000;
189 opt_register_arg("-a", opt_set_ulongval, NULL, &arg, "All");
190 ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
192 ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
193 ok1(parse_args(&argc, &argv, "-a", "0", NULL));
195 ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
196 if (sizeof(long) == 4)
197 ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
198 else if (sizeof(long)== 8)
199 ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
201 fail("FIXME: Handle other long sizes");
207 opt_register_noarg("-a", opt_inc_intval, &arg, "");
208 ok1(parse_args(&argc, &argv, "-a", NULL));
210 ok1(parse_args(&argc, &argv, "-a", "-a", NULL));
212 ok1(parse_args(&argc, &argv, "-aa", NULL));
216 /* opt_show_version_and_exit. */
220 opt_register_noarg("-a",
221 opt_version_and_exit, "1.2.3", "");
222 exitval = setjmp(exited);
224 parse_args(&argc, &argv, "-a", NULL);
225 fail("opt_show_version_and_exit returned?");
227 ok1(exitval - 1 == 0);
229 ok1(strcmp(output, "1.2.3\n") == 0);
234 /* opt_usage_and_exit. */
238 opt_register_noarg("-a",
239 opt_usage_and_exit, "[args]", "");
240 exitval = setjmp(exited);
242 parse_args(&argc, &argv, "-a", NULL);
243 fail("opt_usage_and_exit returned?");
245 ok1(exitval - 1 == 0);
247 ok1(strstr(output, "[args]"));
248 ok1(strstr(output, argv[0]));
249 ok1(strstr(output, "[-a]"));
257 char buf[OPT_SHOW_LEN+2] = { 0 };
258 buf[OPT_SHOW_LEN] = '!';
261 opt_show_bool(buf, &b);
262 ok1(strcmp(buf, "true") == 0);
263 ok1(buf[OPT_SHOW_LEN] == '!');
266 opt_show_bool(buf, &b);
267 ok1(strcmp(buf, "false") == 0);
268 ok1(buf[OPT_SHOW_LEN] == '!');
271 /* opt_show_invbool */
274 char buf[OPT_SHOW_LEN+2] = { 0 };
275 buf[OPT_SHOW_LEN] = '!';
278 opt_show_invbool(buf, &b);
279 ok1(strcmp(buf, "false") == 0);
280 ok1(buf[OPT_SHOW_LEN] == '!');
283 opt_show_invbool(buf, &b);
284 ok1(strcmp(buf, "true") == 0);
285 ok1(buf[OPT_SHOW_LEN] == '!');
290 char str[OPT_SHOW_LEN*2], *p;
291 char buf[OPT_SHOW_LEN+2] = { 0 };
292 buf[OPT_SHOW_LEN] = '!';
297 opt_show_charp(buf, &p);
298 ok1(strcmp(buf, "\"short\"") == 0);
299 ok1(buf[OPT_SHOW_LEN] == '!');
302 memset(p, 'x', OPT_SHOW_LEN*2);
303 p[OPT_SHOW_LEN*2-1] = '\0';
304 opt_show_charp(buf, &p);
306 ok1(buf[OPT_SHOW_LEN-1] == '"');
307 ok1(buf[OPT_SHOW_LEN] == '!');
308 ok1(strspn(buf+1, "x") == OPT_SHOW_LEN-2);
311 /* opt_show_intval */
314 char buf[OPT_SHOW_LEN+2] = { 0 };
315 buf[OPT_SHOW_LEN] = '!';
318 opt_show_intval(buf, &i);
319 ok1(strcmp(buf, "-77") == 0);
320 ok1(buf[OPT_SHOW_LEN] == '!');
323 opt_show_intval(buf, &i);
324 ok1(strcmp(buf, "77") == 0);
325 ok1(buf[OPT_SHOW_LEN] == '!');
328 /* opt_show_uintval */
331 char buf[OPT_SHOW_LEN+2] = { 0 };
332 buf[OPT_SHOW_LEN] = '!';
335 opt_show_uintval(buf, &ui);
336 ok1(strcmp(buf, "4294967295") == 0);
337 ok1(buf[OPT_SHOW_LEN] == '!');
340 /* opt_show_longval */
343 char buf[OPT_SHOW_LEN+2] = { 0 };
344 buf[OPT_SHOW_LEN] = '!';
347 opt_show_longval(buf, &l);
348 ok1(strcmp(buf, "1234567890") == 0);
349 ok1(buf[OPT_SHOW_LEN] == '!');
352 /* opt_show_ulongval */
355 char buf[OPT_SHOW_LEN+2] = { 0 };
356 buf[OPT_SHOW_LEN] = '!';
359 opt_show_ulongval(buf, &ul);
360 ok1(strcmp(buf, "4294967295") == 0);
361 ok1(buf[OPT_SHOW_LEN] == '!');
364 /* opt_log_stderr. */
367 opt_register_noarg("-a",
368 opt_usage_and_exit, "[args]", "");
371 argv = malloc(sizeof(argv[0]) * 3);
372 argv[0] = "thisprog";
373 argv[1] = "--garbage";
375 ok1(!opt_parse(&argc, argv, opt_log_stderr));
377 "thisprog: --garbage: unrecognized option\n"));
382 /* opt_log_stderr_exit. */
386 opt_register_noarg("-a",
387 opt_usage_and_exit, "[args]", "");
388 exitval = setjmp(exited);
391 argv = malloc(sizeof(argv[0]) * 3);
392 argv[0] = "thisprog";
393 argv[1] = "--garbage";
395 opt_parse(&argc, argv, opt_log_stderr_exit);
396 fail("opt_log_stderr_exit returned?");
398 ok1(exitval - 1 == 1);
401 "thisprog: --garbage: unrecognized option\n"));
406 return exit_status();