From 2e314136ed58b6860c667e379bef22190fe84aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sat, 22 Nov 2025 14:50:10 +0100 Subject: New upstream version 5.2 --- src/tc-option.c | 207 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 147 insertions(+), 60 deletions(-) (limited to 'src/tc-option.c') diff --git a/src/tc-option.c b/src/tc-option.c index 8e99b19..860f9d2 100644 --- a/src/tc-option.c +++ b/src/tc-option.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// SPDX-FileCopyrightText: 2022 Jan Engelhardt +// SPDX-FileCopyrightText: 2025 Jan Engelhardt /* * option parser test program */ @@ -14,17 +14,22 @@ #include "internal.h" static int opt_v = 0, opt_mask = 0; -static char *opt_kstr = NULL; +static char *opt_kstr, *opt_strp; static long opt_klong = 0; static double opt_kdbl = 0; static int opt_kflag = 0, opt_kint = 0; static int opt_dst = 0; static hxmc_t *opt_mcstr = NULL; +static inline const char *znul(const char *s) +{ + return s != nullptr ? s : "(null)"; +} + static void opt_cbf(const struct HXoptcb *cbi) { printf("cbf was called... with \"%s\"/'%c'\n", - cbi->current->ln, cbi->current->sh); + znul(cbi->current->ln), cbi->current->sh); } static const char *opt_eitheror[] = {"neither", "either", "or"}; @@ -59,83 +64,159 @@ static struct HXoption table[] = { .cb = opt_cbf, .help = "XOR mask test", .htyp = "value"}, {.sh = 'G', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf}, {.sh = 'H', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf}, - {.sh = 'I', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf}, + {.sh = 'I', .type = HXTYPE_NONE, .ptr = nullptr, .help = "Just a flag", .cb = opt_cbf}, HXOPT_AUTOHELP, {.sh = 'J', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf}, + {.ln = "strp", .sh = 'Z', .type = HXTYPE_STRP, .ptr = &opt_strp, + .help = "String pointer", .cb = opt_cbf}, HXOPT_TABLEEND, }; -static void dump_argv(char **v) +static int t_empty_argv(void) { - while (*v != NULL) - printf("[%s] ", *v++); - printf("\n"); -} + char *zero_argv[] = {nullptr}; + struct HXopt6_result result; -static int t_pthru(void) -{ - const char *argv[] = { - "ARGV0", "-Zomg", "-GZfoo", "bar", - "--unknown-f=13.37", "--unknown-a", - "foo", "bar", NULL - }; - char **nargv = nullptr; - int nargc = 0; - - printf("PTHRU test:\n"); - if (HX_getopt5(table, const_cast(char **, argv), &nargc, &nargv, - HXOPT_USAGEONERR | HXOPT_PTHRU) != HXOPT_ERR_SUCCESS) + printf("...with argv={NULL}\n"); + if (HX_getopt6(table, 0, zero_argv, &result, + HXOPT_USAGEONERR | HXOPT_ITER_OA | HXOPT_DUP_ARGS) != HXOPT_ERR_SUCCESS) return EXIT_FAILURE; - printf("argc = %d\n", nargc); - dump_argv(nargv); - printf("\n"); - HX_zvecfree(nargv); - return EXIT_SUCCESS; + bool ok = result.nopts == 0 && result.nargs == 0 && result.dup_argc == 0; + HX_getopt6_clean(&result); + free(opt_kstr); + opt_kstr = nullptr; + return ok ? EXIT_SUCCESS : EXIT_FAILURE; } -static int t_empty_argv(void) +static int runner(int argc, char **argv) { - char *zero_argv[] = {nullptr}; - char **new_argv = nullptr; + printf("== HX_getopt6 ==\n"); + int ret = HX_getopt6(table, argc, argv, nullptr, HXOPT_USAGEONERR); + printf("Return value of HX_getopt: %d\n", ret); + printf("Either-or is: %s\n", opt_eitheror[opt_dst]); + printf("values: D=%lf I=%d L=%ld S=%p/%s strp=%p/%s\n", + opt_kdbl, opt_kint, opt_klong, + opt_kstr, znul(opt_kstr), opt_strp, znul(opt_strp)); + printf("Verbosity level: %d\n", opt_v); + printf("Mask: 0x%08X\n", opt_mask); + printf("mcstr: >%s<\n", znul(opt_mcstr)); + free(opt_kstr); + opt_kstr = nullptr; - printf("Testing argv={NULL}\n"); - if (HX_getopt5(table, zero_argv, nullptr, &new_argv, - HXOPT_USAGEONERR) != HXOPT_ERR_SUCCESS) - return EXIT_FAILURE; - HX_zvecfree(new_argv); + ret = t_empty_argv(); + if (ret != EXIT_SUCCESS) + return ret; return EXIT_SUCCESS; } -static int t_keep_argv(void) +static int t_getopt6_aflags(int unused_argc, char **unused_argv) { - static const char *const one_argv[] = {"what", nullptr}; - const char **argv = const_cast2(const char **, one_argv); - if (HX_getopt(table, nullptr, &argv, HXOPT_KEEP_ARGV) != HXOPT_ERR_SUCCESS) + struct HXopt6_result result; + char *argv[] = {"./prog", "-q", "foo", "-qS", "quux", "bar", "--NIL", nullptr}; + + printf("== ANY_ORDER ==\n"); + int ret = HX_getopt6(table, 6, argv, &result, HXOPT_ANY_ORDER); + if (ret != HXOPT_ERR_SUCCESS || + result.uarg != nullptr || result.dup_argv != nullptr) + return EXIT_FAILURE; + HX_getopt6_clean(&result); + free(opt_kstr); + opt_kstr = nullptr; + + /* T: Asking for DUP should produce data */ + /* T: Limit strings -- NIL must not be processed */ + printf("== ANY_ORDER/DUP_ARGS ==\n"); + ret = HX_getopt6(table, 6, argv, &result, HXOPT_ANY_ORDER | HXOPT_DUP_ARGS); + if (ret != HXOPT_ERR_SUCCESS || + result.uarg != nullptr || + result.dup_argv == nullptr || result.dup_argc != 3) + return EXIT_FAILURE; + if (strcmp(result.dup_argv[0], argv[0]) != 0 || + strcmp(result.dup_argv[1], argv[2]) != 0 || + strcmp(result.dup_argv[2], argv[5]) != 0) + return EXIT_FAILURE; + for (int i = 0; i < result.dup_argc; ++i) + printf(" %s", result.dup_argv[i]); + printf("\n"); + HX_getopt6_clean(&result); + free(opt_kstr); + opt_kstr = nullptr; + + /* T: POSIX order */ + printf("== RQ_ORDER/DUP_ARGS ==\n"); + ret = HX_getopt6(table, 6, argv, &result, HXOPT_RQ_ORDER | HXOPT_DUP_ARGS); + if (ret != HXOPT_ERR_SUCCESS || + result.uarg != nullptr || + result.dup_argv == nullptr || result.dup_argc != 5) + return EXIT_FAILURE; + if (strcmp(result.dup_argv[0], argv[0]) != 0 || + strcmp(result.dup_argv[1], argv[2]) != 0 || + strcmp(result.dup_argv[2], argv[3]) != 0 || + strcmp(result.dup_argv[3], argv[4]) != 0 || + strcmp(result.dup_argv[4], argv[5]) != 0) return EXIT_FAILURE; - return argv == one_argv ? EXIT_SUCCESS : EXIT_FAILURE; + for (int i = 0; i < result.dup_argc; ++i) + printf(" %s", result.dup_argv[i]); + printf("\n"); + HX_getopt6_clean(&result); + free(opt_kstr); + opt_kstr = nullptr; + + /* T: Asking for ITER should produce data */ + printf("== ANY_ORDER/ITER_ARGS ==\n"); + ret = HX_getopt6(table, 6, argv, &result, HXOPT_ANY_ORDER | HXOPT_ITER_ARGS); + if (ret != HXOPT_ERR_SUCCESS || result.dup_argv != nullptr || + result.nargs != 2 || result.uarg == nullptr) + return EXIT_FAILURE; + if (strcmp(result.uarg[0], argv[2]) != 0 || + strcmp(result.uarg[1], argv[5]) != 0) + return EXIT_FAILURE; + for (int i = 0; i < result.nargs; ++i) + printf(" %s", result.uarg[i]); + printf("\n"); + HX_getopt6_clean(&result); + free(opt_kstr); + opt_kstr = nullptr; + + /* T: Asking for ITER should produce data */ + printf("== ANY_ORDER/ITER_OPTS ==\n"); + ret = HX_getopt6(table, 6, argv, &result, HXOPT_ANY_ORDER | HXOPT_ITER_OPTS); + if (ret != HXOPT_ERR_SUCCESS || result.nopts != 3 || + result.desc == nullptr || result.oarg == nullptr) + return EXIT_FAILURE; + if (result.desc[0]->sh != 'q' || result.oarg[0] != nullptr || + result.desc[1]->sh != 'q' || result.oarg[1] != nullptr || + result.desc[2]->sh != 'S' || result.oarg[2] == nullptr || + strcmp(result.oarg[2], argv[4]) != 0) + return EXIT_FAILURE; + printf(" %s", argv[0]); + for (int i = 0; i < result.nopts; ++i) { + printf(" -%c", result.desc[i]->sh); + if (result.oarg[i] != nullptr) + printf(" %s", result.oarg[i]); + } + printf("\n"); + HX_getopt6_clean(&result); + free(opt_kstr); + opt_kstr = nullptr; + return EXIT_SUCCESS; } -static int runner(int argc, char **argv) +static int t_getopt6_eq(void) { - char **nargv = nullptr; - int ret = HX_getopt5(table, argv, &argc, &nargv, HXOPT_USAGEONERR); - printf("Return value of HX_getopt: %d\n", ret); - if (ret == EXIT_SUCCESS) - HX_zvecfree(nargv); - ret = t_empty_argv(); - if (ret != EXIT_SUCCESS) - return ret; - ret = t_keep_argv(); - if (ret != EXIT_SUCCESS) - return ret; - - printf("Either-or is: %s\n", opt_eitheror[opt_dst]); - printf("values: D=%lf I=%d L=%ld S=%s\n", - opt_kdbl, opt_kint, opt_klong, opt_kstr); - printf("Verbosity level: %d\n", opt_v); - printf("Mask: 0x%08X\n", opt_mask); - printf("mcstr: >%s<\n", opt_mcstr); - return t_pthru(); + printf("== getopt6_eq ==\n"); + char *argv[] = {"./prog", "--strp", "bar", "--strp=bar"}; + struct HXopt6_result result; + int ret = HX_getopt6(table, ARRAY_SIZE(argv), argv, &result, + HXOPT_ITER_OPTS | HXOPT_USAGEONERR); + if (ret != HXOPT_ERR_SUCCESS || result.nopts != 2) + return EXIT_FAILURE; + if (strcmp(result.oarg[0], result.oarg[1]) != 0) + return EXIT_FAILURE; + HX_getopt6_clean(&result); + free(opt_kstr); + opt_kstr = nullptr; + return EXIT_SUCCESS; } int main(int argc, char **argv) @@ -143,6 +224,12 @@ int main(int argc, char **argv) if (HX_init() <= 0) return EXIT_FAILURE; int ret = runner(argc, argv); + if (ret != EXIT_SUCCESS) + printf("FAILED\n"); + ret = t_getopt6_aflags(argc, argv); + if (ret != EXIT_SUCCESS) + printf("FAILED\n"); + ret = t_getopt6_eq(); if (ret != EXIT_SUCCESS) printf("FAILED\n"); HX_exit(); -- cgit v1.2.3