summaryrefslogtreecommitdiff
path: root/src/tc-option.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2025-11-22 14:50:10 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2025-11-22 14:50:10 +0100
commit2e314136ed58b6860c667e379bef22190fe84aa2 (patch)
tree21f897804c03c3419a0c015ace3bf9fb9c1b8e52 /src/tc-option.c
parent50d223b12c1319b4b9c4a5b8e34866c46996cb36 (diff)
New upstream version 5.2upstream/5.2upstream
Diffstat (limited to 'src/tc-option.c')
-rw-r--r--src/tc-option.c207
1 files changed, 147 insertions, 60 deletions
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)
@@ -145,6 +226,12 @@ int main(int argc, char **argv)
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();
return ret;
}