X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fopt%2Ftest%2Frun-helpers.c;h=589962fe4d8fadaffe6dc4cafd2764b2b5838a22;hp=f8041ead39d1f73c3b095e0fb890db2ec886453a;hb=2d6e39ce1994c9537caf9a711b69a2c61f1ec35d;hpb=d89e5744f30b584ac4909ce1164af1289c41359b diff --git a/ccan/opt/test/run-helpers.c b/ccan/opt/test/run-helpers.c index f8041ead..589962fe 100644 --- a/ccan/opt/test/run-helpers.c +++ b/ccan/opt/test/run-helpers.c @@ -1,8 +1,9 @@ -#define _GNU_SOURCE +#include "config.h" #include #include #include #include +#include #include "utils.h" /* We don't actually want it to exit... */ @@ -12,28 +13,26 @@ static jmp_buf exited; #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 #include #include - -static void reset_options(void) -{ - free(opt_table); - opt_table = NULL; - opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0; -} +#include static char *output = NULL; -static int saved_printf(const char *fmt, ...) +static int saved_vprintf(const char *fmt, va_list ap) { - va_list ap; char *p; - int ret; - - va_start(ap, fmt); - ret = vasprintf(&p, fmt, ap); - va_end(ap); + int ret = vasprintf(&p, fmt, ap); if (output) { output = realloc(output, strlen(output) + strlen(p) + 1); @@ -41,23 +40,63 @@ static int saved_printf(const char *fmt, ...) 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); +} + +static void set_args(int *argc, char ***argv, ...) +{ + va_list ap; + *argv = malloc(sizeof(**argv) * 20); + + va_start(ap, argv); + for (*argc = 0; + ((*argv)[*argc] = va_arg(ap, char*)) != NULL; + (*argc)++); + va_end(ap); +} /* Test helpers. */ int main(int argc, char *argv[]) { - plan_tests(88); + plan_tests(452); /* opt_set_bool */ { bool arg = false; reset_options(); - opt_register_noarg("-a", opt_set_bool, &arg, NULL); + 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, NULL); + 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)); @@ -66,16 +105,19 @@ int main(int argc, char *argv[]) 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, NULL); + 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, NULL); + &arg, ""); ok1(parse_args(&argc, &argv, "-b", "no", NULL)); ok1(arg); ok1(parse_args(&argc, &argv, "-b", "yes", NULL)); @@ -84,12 +126,15 @@ int main(int argc, char *argv[]) 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, NULL); + opt_register_arg("-a", opt_set_charp, NULL, &arg, "All"); ok1(parse_args(&argc, &argv, "-a", "string", NULL)); ok1(strcmp(arg, "string") == 0); } @@ -97,7 +142,7 @@ int main(int argc, char *argv[]) { int arg = 1000; reset_options(); - opt_register_arg("-a", opt_set_intval, NULL, &arg, NULL); + 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)); @@ -114,7 +159,7 @@ int main(int argc, char *argv[]) { unsigned int arg = 1000; reset_options(); - opt_register_arg("-a", opt_set_uintval, NULL, &arg, NULL); + 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)); @@ -122,12 +167,23 @@ int main(int argc, char *argv[]) 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, NULL); + 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)); @@ -146,7 +202,7 @@ int main(int argc, char *argv[]) { unsigned long int arg = 1000; reset_options(); - opt_register_arg("-a", opt_set_ulongval, NULL, &arg, NULL); + 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)); @@ -160,11 +216,770 @@ int main(int argc, char *argv[]) else fail("FIXME: Handle other long sizes"); } + + { + const long long k = 1024; + const long long M = k * k; + const long long G = k * k * k; + const long long T = k * k * k * k; + const long long P = k * k * k * k * k; + const long long E = k * k * k * k * k * k; + + /* opt_set_uintval_bi */ + { + unsigned int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_uintval_bi, 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); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0k", NULL)); + ok1(arg == 0); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "30k", NULL)); + ok1(arg == 30 * k); + ok1(!parse_args(&argc, &argv, "-a", "-1K", NULL)); + } + + /* opt_set_intval_bi */ + { + int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_intval_bi, 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); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0k", NULL)); + ok1(arg == 0); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "30k", NULL)); + ok1(arg == 30 * k); + ok1(parse_args(&argc, &argv, "-a", "-1K", NULL)); + ok1(arg == -1 * k); + } + + + /* opt_set_ulongval_bi */ + { + unsigned long int arg = 1000; + + reset_options(); + opt_register_arg("-a", opt_set_ulongval_bi, 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); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100k", NULL)); + ok1(arg == 100 * k); + ok1(parse_args(&argc, &argv, "-a", "1K", NULL)); + ok1(arg == 1 * k); + ok1(parse_args(&argc, &argv, "-a", "99M", NULL)); + ok1(arg == 99 * M); + /*note, 2999M > max signed 32 bit long, 1 << 31*/ + ok1(parse_args(&argc, &argv, "-a", "2999m", NULL)); + ok1(arg == 2999 * M); + ok1(parse_args(&argc, &argv, "-a", "1G", NULL)); + ok1(arg == 1 * G); + ok1(!parse_args(&argc, &argv, "-a", "-1G", NULL)); + if (sizeof(long) == 4){ + ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1T", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1E", NULL)); + } + else if (sizeof(long) == 8){ + ok1(!parse_args(&argc, &argv, "-a", + "18446744073709551616", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "8E", NULL)); + ok1(parse_args(&argc, &argv, "-a", "3E", NULL)); + } + else + fail("FIXME: Handle other long sizes"); + } + + /* opt_set_longval_bi */ + { + long int arg = 1000; + + reset_options(); + opt_register_arg("-a", opt_set_longval_bi, 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", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100k", NULL)); + ok1(arg == 100 * k); + ok1(parse_args(&argc, &argv, "-a", "-100k", NULL)); + ok1(arg == -100 * k); + ok1(parse_args(&argc, &argv, "-a", "1K", NULL)); + ok1(arg == 1 * k); + ok1(parse_args(&argc, &argv, "-a", "99M", NULL)); + ok1(arg == 99 * M); + ok1(parse_args(&argc, &argv, "-a", "1G", NULL)); + ok1(arg == 1 * G); + ok1(parse_args(&argc, &argv, "-a", "-1G", NULL)); + ok1(arg == -1 * G); + if (sizeof(long) == 4){ + ok1(!parse_args(&argc, &argv, "-a", "2147483648", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "2G", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "2048m", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1T", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1E", NULL)); + } + else if (sizeof(long) == 8){ + ok1(!parse_args(&argc, &argv, "-a", + "9223372036854775808", NULL)); + ok1(parse_args(&argc, &argv, "-a", "3E", NULL)); + ok1(arg == 3 * E); + ok1(parse_args(&argc, &argv, "-a", "123T", NULL)); + ok1(arg == 123 * T); + } + else + fail("FIXME: Handle other long sizes"); + } + + + /* opt_set_longlongval_bi */ + { + long long int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_longlongval_bi, 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", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100k", NULL)); + ok1(arg == 100 * k); + ok1(parse_args(&argc, &argv, "-a", "-100k", NULL)); + ok1(arg == -100 * k); + ok1(parse_args(&argc, &argv, "-a", "1K", NULL)); + ok1(arg == 1 * k); + ok1(parse_args(&argc, &argv, "-a", "-333333M", NULL)); + ok1(arg == -333333 * M); + ok1(parse_args(&argc, &argv, "-a", "1G", NULL)); + ok1(arg == 1 * G); + ok1(parse_args(&argc, &argv, "-a", "1024t", NULL)); + ok1(arg == 1024 * T); + ok1(parse_args(&argc, &argv, "-a", "123P", NULL)); + ok1(arg == 123 * P); + ok1(parse_args(&argc, &argv, "-a", "-3E", NULL)); + ok1(arg == -3 * E); + + if (sizeof(long long) == 8){ + ok1(!parse_args(&argc, &argv, "-a", + "9223372036854775808", NULL)); + /*8E and 922337.. are both 1 << 63*/ + ok1(!parse_args(&argc, &argv, "-a", "8E", NULL)); + } + else + fail("FIXME: Handle other long long int" + " sizes (specifically %zu bytes)", + sizeof(long long)); + } + /* opt_set_ulonglongval_bi */ + { + unsigned long long int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_ulonglongval_bi, 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", "1Q", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100G", NULL)); + ok1(arg == 100 * G); + ok1(!parse_args(&argc, &argv, "-a", "-100G", NULL)); + ok1(parse_args(&argc, &argv, "-a", "8191P", NULL)); + ok1(arg == 8191 * P); + } + + /* opt_show_intval_bi */ + { + int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "-77") == 0); + i = 0; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1234 * k; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "-1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_longval_bi */ + { + long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "-77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1 * k; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "-1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_llongval_bi */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -7777; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "-7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 7777; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -10240000 * k; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "-10000M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * P; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "1E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_uintval_bi */ + { + unsigned int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1234 * k; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ulongval_bi */ + { + unsigned long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = k; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ullongval_bi */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 7777; + opt_show_ulonglongval_bi(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 10240000 * k; + opt_show_ulonglongval_bi(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "10000M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_ulonglongval_bi(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * P; + opt_show_ulonglongval_bi(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "1E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + } + + { + const long long k = 1000; + const long long M = k * k; + const long long G = k * k * k; + const long long T = k * k * k * k; + const long long P = k * k * k * k * k; + const long long E = k * k * k * k * k * k; + + /* opt_set_uintval_si */ + { + unsigned int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_uintval_si, 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); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0k", NULL)); + ok1(arg == 0); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "30k", NULL)); + ok1(arg == 30 * k); + ok1(!parse_args(&argc, &argv, "-a", "-1K", NULL)); + if (sizeof(unsigned int) < 8) + ok1(!parse_args(&argc, &argv, "-a", "1E", NULL)); + else + pass("can't test int truncation when int is so huge"); + } + + /* opt_set_intval_si */ + { + int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_intval_si, 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); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0k", NULL)); + ok1(arg == 0); + arg = 1; + ok1(parse_args(&argc, &argv, "-a", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "3Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "30k", NULL)); + ok1(arg == 30 * k); + ok1(parse_args(&argc, &argv, "-a", "-1K", NULL)); + ok1(arg == -1 * k); + if (sizeof(int) < 8) + ok1(!parse_args(&argc, &argv, "-a", "1E", NULL)); + else + pass("can't test int truncation when int is so huge"); + } + + + /* opt_set_ulongval_si */ + { + unsigned long int arg = 1000; + + reset_options(); + opt_register_arg("-a", opt_set_ulongval_si, 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", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100k", NULL)); + ok1(arg == 100 * k); + ok1(parse_args(&argc, &argv, "-a", "1K", NULL)); + ok1(arg == 1 * k); + ok1(parse_args(&argc, &argv, "-a", "99M", NULL)); + ok1(arg == 99 * M); + /*note, 2999M > max signed 32 bit long, 1 << 31*/ + ok1(parse_args(&argc, &argv, "-a", "2999m", NULL)); + ok1(arg == 2999 * M); + ok1(parse_args(&argc, &argv, "-a", "1G", NULL)); + ok1(arg == 1 * G); + ok1(!parse_args(&argc, &argv, "-a", "-1G", NULL)); + ok1(parse_args(&argc, &argv, "-a", "4G", NULL)); + ok1(arg == 4000000000U); + if (sizeof(long) == 4){ + ok1(!parse_args(&argc, &argv, "-a", "4294967296", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "4295M", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1T", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1E", NULL)); + } + else if (sizeof(long)== 8){ + ok1(!parse_args(&argc, &argv, "-a", + "18446744073709551616", NULL)); + ok1(parse_args(&argc, &argv, "-a", "9E", NULL)); + ok1(arg == 9000000000000000000ULL); + ok1(!parse_args(&argc, &argv, "-a", "19E", NULL)); + } + else + fail("FIXME: Handle other long sizes"); + } + + /* opt_set_longval_si */ + { + long int arg = 1000; + + reset_options(); + opt_register_arg("-a", opt_set_longval_si, 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", "0P", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100k", NULL)); + ok1(arg == 100 * k); + ok1(parse_args(&argc, &argv, "-a", "-100k", NULL)); + ok1(arg == -100 * k); + ok1(parse_args(&argc, &argv, "-a", "1K", NULL)); + ok1(arg == 1 * k); + ok1(parse_args(&argc, &argv, "-a", "99M", NULL)); + ok1(arg == 99 * M); + ok1(parse_args(&argc, &argv, "-a", "1G", NULL)); + ok1(arg == 1 * G); + ok1(parse_args(&argc, &argv, "-a", "-1G", NULL)); + ok1(arg == -1 * G); + if (sizeof(long) == 4){ + ok1(!parse_args(&argc, &argv, "-a", "2147483648", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "4G", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1T", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1E", NULL)); + ok1(parse_args(&argc, &argv, "-a", "1999m", NULL)); + ok1(arg == 1999 * M); + } + else if (sizeof(long)== 8){ + ok1(!parse_args(&argc, &argv, "-a", + "9223372036854775808", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "9224P", NULL)); + ok1(parse_args(&argc, &argv, "-a", "9E", NULL)); + ok1(arg == 9 * E); + ok1(parse_args(&argc, &argv, "-a", "123T", NULL)); + ok1(arg == 123 * T); + } + else + fail("FIXME: Handle other long sizes"); + } + + + /* opt_set_longlongval_si */ + { + long long int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_longlongval_si, 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", "0T", NULL)); + ok1(arg == 0); + ok1(!parse_args(&argc, &argv, "-a", "100crap", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1Q", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100k", NULL)); + ok1(arg == 100 * k); + ok1(parse_args(&argc, &argv, "-a", "-100k", NULL)); + ok1(arg == -100 * k); + ok1(parse_args(&argc, &argv, "-a", "1K", NULL)); + ok1(arg == 1 * k); + ok1(parse_args(&argc, &argv, "-a", "-333333M", NULL)); + ok1(arg == -333333 * M); + ok1(parse_args(&argc, &argv, "-a", "1G", NULL)); + ok1(arg == 1 * G); + ok1(parse_args(&argc, &argv, "-a", "1024t", NULL)); + ok1(arg == 1024 * T); + ok1(parse_args(&argc, &argv, "-a", "123P", NULL)); + ok1(arg == 123 * P); + ok1(parse_args(&argc, &argv, "-a", "-3E", NULL)); + ok1(arg == -3 * E); + ok1(parse_args(&argc, &argv, "-a", "8E", NULL)); + if (sizeof(long long) == 8){ + ok1(!parse_args(&argc, &argv, "-a", + "9223372036854775808", NULL)); + ok1(!parse_args(&argc, &argv, "-a", + "10E", NULL)); + } + else + fail("FIXME: Handle other long long int" + " sizes (specifically %zu bytes)", + sizeof(long long)); + + } + /* opt_set_ulonglongval_si */ + { + unsigned long long int arg = 1000; + reset_options(); + opt_register_arg("-a", opt_set_ulonglongval_si, 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", "1Q", NULL)); + ok1(!parse_args(&argc, &argv, "-a", "1kk", NULL)); + ok1(parse_args(&argc, &argv, "-a", "100G", NULL)); + ok1(arg == 100 * G); + ok1(!parse_args(&argc, &argv, "-a", "-100G", NULL)); + ok1(parse_args(&argc, &argv, "-a", "8E", NULL)); + } + /* opt_show_intval_si */ + { + int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "-77") == 0); + i = 0; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1234 * k; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "-1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * M; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_longval_si */ + { + long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "-77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1 * k; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "-1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * M; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_llongval_si */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -7777; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "-7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 7777; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -10240000 * k; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "-10240M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 2000 * P; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "2E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_uintval_si */ + { + unsigned int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1234 * k; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * M; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ulongval_si */ + { + unsigned long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = k; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "1024M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ullongval_si */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 7777; + opt_show_ulonglongval_si(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 10240000 * k; + opt_show_ulonglongval_si(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "10240M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_ulonglongval_si(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * P; + opt_show_ulonglongval_si(buf, (unsigned long long *)&i); + ok1(strcmp(buf, "1E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + } + + /* opt_inc_intval */ { int arg = 1000; reset_options(); - opt_register_noarg("-a", opt_inc_intval, &arg, NULL); + 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)); @@ -178,16 +993,22 @@ int main(int argc, char *argv[]) int exitval; reset_options(); opt_register_noarg("-a", - opt_version_and_exit, "1.2.3", NULL); + opt_version_and_exit, "1.2.3", ""); + /* parse_args allocates argv */ + free(argv); + + set_args(&argc, &argv, "thisprog", "-a", NULL); + exitval = setjmp(exited); if (exitval == 0) { - parse_args(&argc, &argv, "-a", NULL); + 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; } @@ -196,10 +1017,13 @@ int main(int argc, char *argv[]) int exitval; reset_options(); opt_register_noarg("-a", - opt_usage_and_exit, "[args]", NULL); + opt_usage_and_exit, "[args]", ""); + + set_args(&argc, &argv, "thisprog", "-a", NULL); + exitval = setjmp(exited); if (exitval == 0) { - parse_args(&argc, &argv, "-a", NULL); + opt_parse(&argc, argv, save_err_output); fail("opt_usage_and_exit returned?"); } else { ok1(exitval - 1 == 0); @@ -208,6 +1032,9 @@ int main(int argc, char *argv[]) ok1(strstr(output, argv[0])); ok1(strstr(output, "[-a]")); free(output); + free(argv); + /* It exits without freeing usage string. */ + free(last_allocation); output = NULL; } @@ -321,5 +1148,42 @@ int main(int argc, char *argv[]) ok1(buf[OPT_SHOW_LEN] == '!'); } + /* opt_log_stderr. */ + { + reset_options(); + opt_register_noarg("-a", + opt_usage_and_exit, "[args]", ""); + + set_args(&argc, &argv, "thisprog", "--garbage", 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]", ""); + set_args(&argc, &argv, "thisprog", "--garbage", 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; + } + + //diag("%s\n", err_output); return exit_status(); }