123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- #include "config.h"
- #include <stdio.h>
- #include <ccan/tap/tap.h>
- #include <setjmp.h>
- #include <stdlib.h>
- #include <limits.h>
- #include "utils.h"
- /* We don't actually want it to exit... */
- static jmp_buf exited;
- #define exit(status) longjmp(exited, (status) + 1)
- #define printf saved_printf
- static int saved_printf(const char *fmt, ...);
- #define fprintf saved_fprintf
- static int saved_fprintf(FILE *ignored, const char *fmt, ...);
- #define vfprintf(f, fmt, ap) saved_vprintf(fmt, ap)
- static int saved_vprintf(const char *fmt, va_list ap);
- #define malloc(size) saved_malloc(size)
- static void *saved_malloc(size_t size);
- #include <ccan/opt/helpers.c>
- #include <ccan/opt/opt.c>
- #include <ccan/opt/usage.c>
- #include <ccan/opt/parse.c>
- static void reset_options(void)
- {
- free(opt_table);
- opt_table = NULL;
- opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0;
- }
- static char *output = NULL;
- static int saved_vprintf(const char *fmt, va_list ap)
- {
- char *p;
- int ret = vasprintf(&p, fmt, ap);
- if (output) {
- output = realloc(output, strlen(output) + strlen(p) + 1);
- strcat(output, p);
- free(p);
- } else
- output = p;
- return ret;
- }
- static int saved_printf(const char *fmt, ...)
- {
- va_list ap;
- int ret;
- va_start(ap, fmt);
- ret = saved_vprintf(fmt, ap);
- va_end(ap);
- return ret;
- }
- static int saved_fprintf(FILE *ignored, const char *fmt, ...)
- {
- va_list ap;
- int ret;
- va_start(ap, fmt);
- ret = saved_vprintf(fmt, ap);
- va_end(ap);
- return ret;
- }
- #undef malloc
- static void *last_allocation;
- static void *saved_malloc(size_t size)
- {
- return last_allocation = malloc(size);
- }
- /* Test helpers. */
- int main(int argc, char *argv[])
- {
- plan_tests(100);
- /* opt_set_bool */
- {
- bool arg = false;
- reset_options();
- opt_register_noarg("-a", opt_set_bool, &arg, "");
- ok1(parse_args(&argc, &argv, "-a", NULL));
- ok1(arg);
- opt_register_arg("-b", opt_set_bool_arg, NULL, &arg, "");
- ok1(parse_args(&argc, &argv, "-b", "no", NULL));
- ok1(!arg);
- ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
- ok1(arg);
- ok1(parse_args(&argc, &argv, "-b", "false", NULL));
- ok1(!arg);
- ok1(parse_args(&argc, &argv, "-b", "true", NULL));
- ok1(arg);
- ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
- ok1(arg);
- ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
- }
- /* opt_set_invbool */
- {
- bool arg = true;
- reset_options();
- opt_register_noarg("-a", opt_set_invbool, &arg, "");
- ok1(parse_args(&argc, &argv, "-a", NULL));
- ok1(!arg);
- opt_register_arg("-b", opt_set_invbool_arg, NULL,
- &arg, "");
- ok1(parse_args(&argc, &argv, "-b", "no", NULL));
- ok1(arg);
- ok1(parse_args(&argc, &argv, "-b", "yes", NULL));
- ok1(!arg);
- ok1(parse_args(&argc, &argv, "-b", "false", NULL));
- ok1(arg);
- ok1(parse_args(&argc, &argv, "-b", "true", NULL));
- ok1(!arg);
- ok1(!parse_args(&argc, &argv, "-b", "unknown", NULL));
- ok1(!arg);
- ok1(strstr(err_output, ": -b: Invalid argument 'unknown'"));
- }
- /* opt_set_charp */
- {
- char *arg = (char *)"wrong";
- reset_options();
- opt_register_arg("-a", opt_set_charp, NULL, &arg, "All");
- ok1(parse_args(&argc, &argv, "-a", "string", NULL));
- ok1(strcmp(arg, "string") == 0);
- }
- /* opt_set_intval */
- {
- int arg = 1000;
- reset_options();
- opt_register_arg("-a", opt_set_intval, NULL, &arg, "All");
- ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
- ok1(arg == 9999);
- ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
- ok1(arg == -9999);
- ok1(parse_args(&argc, &argv, "-a", "0", NULL));
- ok1(arg == 0);
- ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
- if (sizeof(int) == 4)
- ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
- else
- fail("Handle other int sizes");
- }
- /* opt_set_uintval */
- {
- unsigned int arg = 1000;
- reset_options();
- opt_register_arg("-a", opt_set_uintval, NULL, &arg, "All");
- ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
- ok1(arg == 9999);
- ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
- ok1(parse_args(&argc, &argv, "-a", "0", NULL));
- ok1(arg == 0);
- ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
- ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
- if (ULONG_MAX == UINT_MAX) {
- pass("Can't test overflow");
- pass("Can't test error message");
- } else {
- char buf[30];
- sprintf(buf, "%lu", ULONG_MAX);
- ok1(!parse_args(&argc, &argv, "-a", buf, NULL));
- ok1(strstr(err_output, ": -a: value '")
- && strstr(err_output, buf)
- && strstr(err_output, "' does not fit into an integer"));
- }
- }
- /* opt_set_longval */
- {
- long int arg = 1000;
- reset_options();
- opt_register_arg("-a", opt_set_longval, NULL, &arg, "All");
- ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
- ok1(arg == 9999);
- ok1(parse_args(&argc, &argv, "-a", "-9999", NULL));
- ok1(arg == -9999);
- ok1(parse_args(&argc, &argv, "-a", "0", NULL));
- ok1(arg == 0);
- ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
- if (sizeof(long) == 4)
- ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
- else if (sizeof(long)== 8)
- ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
- else
- fail("FIXME: Handle other long sizes");
- }
- /* opt_set_ulongval */
- {
- unsigned long int arg = 1000;
- reset_options();
- opt_register_arg("-a", opt_set_ulongval, NULL, &arg, "All");
- ok1(parse_args(&argc, &argv, "-a", "9999", NULL));
- ok1(arg == 9999);
- ok1(!parse_args(&argc, &argv, "-a", "-9999", NULL));
- ok1(parse_args(&argc, &argv, "-a", "0", NULL));
- ok1(arg == 0);
- ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL));
- if (sizeof(long) == 4)
- ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL));
- else if (sizeof(long)== 8)
- ok1(!parse_args(&argc, &argv, "-a", "18446744073709551616", NULL));
- else
- fail("FIXME: Handle other long sizes");
- }
- /* opt_inc_intval */
- {
- int arg = 1000;
- reset_options();
- opt_register_noarg("-a", opt_inc_intval, &arg, "");
- ok1(parse_args(&argc, &argv, "-a", NULL));
- ok1(arg == 1001);
- ok1(parse_args(&argc, &argv, "-a", "-a", NULL));
- ok1(arg == 1003);
- ok1(parse_args(&argc, &argv, "-aa", NULL));
- ok1(arg == 1005);
- }
- /* opt_show_version_and_exit. */
- {
- int exitval;
- reset_options();
- opt_register_noarg("-a",
- opt_version_and_exit, "1.2.3", "");
- /* parse_args allocates argv */
- free(argv);
- argc = 2;
- argv = malloc(sizeof(argv[0]) * 3);
- argv[0] = "thisprog";
- argv[1] = "-a";
- argv[2] = NULL;
- exitval = setjmp(exited);
- if (exitval == 0) {
- opt_parse(&argc, argv, save_err_output);
- fail("opt_show_version_and_exit returned?");
- } else {
- ok1(exitval - 1 == 0);
- }
- ok1(strcmp(output, "1.2.3\n") == 0);
- free(output);
- free(argv);
- output = NULL;
- }
- /* opt_usage_and_exit. */
- {
- int exitval;
- reset_options();
- opt_register_noarg("-a",
- opt_usage_and_exit, "[args]", "");
- argc = 2;
- argv = malloc(sizeof(argv[0]) * 3);
- argv[0] = "thisprog";
- argv[1] = "-a";
- argv[2] = NULL;
- exitval = setjmp(exited);
- if (exitval == 0) {
- opt_parse(&argc, argv, save_err_output);
- fail("opt_usage_and_exit returned?");
- } else {
- ok1(exitval - 1 == 0);
- }
- ok1(strstr(output, "[args]"));
- ok1(strstr(output, argv[0]));
- ok1(strstr(output, "[-a]"));
- free(output);
- free(argv);
- /* It exits without freeing usage string. */
- free(last_allocation);
- output = NULL;
- }
- /* opt_show_bool */
- {
- bool b;
- char buf[OPT_SHOW_LEN+2] = { 0 };
- buf[OPT_SHOW_LEN] = '!';
- b = true;
- opt_show_bool(buf, &b);
- ok1(strcmp(buf, "true") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- b = false;
- opt_show_bool(buf, &b);
- ok1(strcmp(buf, "false") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- }
- /* opt_show_invbool */
- {
- bool b;
- char buf[OPT_SHOW_LEN+2] = { 0 };
- buf[OPT_SHOW_LEN] = '!';
- b = true;
- opt_show_invbool(buf, &b);
- ok1(strcmp(buf, "false") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- b = false;
- opt_show_invbool(buf, &b);
- ok1(strcmp(buf, "true") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- }
- /* opt_show_charp */
- {
- char str[OPT_SHOW_LEN*2], *p;
- char buf[OPT_SHOW_LEN+2] = { 0 };
- buf[OPT_SHOW_LEN] = '!';
- /* Short test. */
- p = str;
- strcpy(p, "short");
- opt_show_charp(buf, &p);
- ok1(strcmp(buf, "\"short\"") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- /* Truncate test. */
- memset(p, 'x', OPT_SHOW_LEN*2);
- p[OPT_SHOW_LEN*2-1] = '\0';
- opt_show_charp(buf, &p);
- ok1(buf[0] == '"');
- ok1(buf[OPT_SHOW_LEN-1] == '"');
- ok1(buf[OPT_SHOW_LEN] == '!');
- ok1(strspn(buf+1, "x") == OPT_SHOW_LEN-2);
- }
- /* opt_show_intval */
- {
- int i;
- char buf[OPT_SHOW_LEN+2] = { 0 };
- buf[OPT_SHOW_LEN] = '!';
- i = -77;
- opt_show_intval(buf, &i);
- ok1(strcmp(buf, "-77") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- i = 77;
- opt_show_intval(buf, &i);
- ok1(strcmp(buf, "77") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- }
- /* opt_show_uintval */
- {
- unsigned int ui;
- char buf[OPT_SHOW_LEN+2] = { 0 };
- buf[OPT_SHOW_LEN] = '!';
- ui = 4294967295U;
- opt_show_uintval(buf, &ui);
- ok1(strcmp(buf, "4294967295") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- }
- /* opt_show_longval */
- {
- long l;
- char buf[OPT_SHOW_LEN+2] = { 0 };
- buf[OPT_SHOW_LEN] = '!';
- l = 1234567890L;
- opt_show_longval(buf, &l);
- ok1(strcmp(buf, "1234567890") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- }
- /* opt_show_ulongval */
- {
- unsigned long ul;
- char buf[OPT_SHOW_LEN+2] = { 0 };
- buf[OPT_SHOW_LEN] = '!';
- ul = 4294967295UL;
- opt_show_ulongval(buf, &ul);
- ok1(strcmp(buf, "4294967295") == 0);
- ok1(buf[OPT_SHOW_LEN] == '!');
- }
- /* opt_log_stderr. */
- {
- reset_options();
- opt_register_noarg("-a",
- opt_usage_and_exit, "[args]", "");
- argc = 2;
- argv = malloc(sizeof(argv[0]) * 3);
- argv[0] = "thisprog";
- argv[1] = "--garbage";
- argv[2] = NULL;
- ok1(!opt_parse(&argc, argv, opt_log_stderr));
- ok1(!strcmp(output,
- "thisprog: --garbage: unrecognized option\n"));
- free(output);
- free(argv);
- output = NULL;
- }
- /* opt_log_stderr_exit. */
- {
- int exitval;
- reset_options();
- opt_register_noarg("-a",
- opt_usage_and_exit, "[args]", "");
- argc = 2;
- argv = malloc(sizeof(argv[0]) * 3);
- argv[0] = "thisprog";
- argv[1] = "--garbage";
- argv[2] = NULL;
- exitval = setjmp(exited);
- if (exitval == 0) {
- opt_parse(&argc, argv, opt_log_stderr_exit);
- fail("opt_log_stderr_exit returned?");
- } else {
- ok1(exitval - 1 == 1);
- }
- free(argv);
- ok1(!strcmp(output,
- "thisprog: --garbage: unrecognized option\n"));
- free(output);
- output = NULL;
- }
- return exit_status();
- }
|