aboutsummaryrefslogtreecommitdiff
path: root/cli/cli-test.c
diff options
context:
space:
mode:
authorYaroslav de la Peña Smirnov <yps@yaroslavps.com>2025-09-12 23:43:49 +0300
committerYaroslav de la Peña Smirnov <yps@yaroslavps.com>2025-09-12 23:43:49 +0300
commit0a8ee7a194e598d9c277b019503f7119b32bd17f (patch)
tree671a416c1fedec1235fa0fd8dce7fa6ed91095c3 /cli/cli-test.c
parent5a2a20eda7ca20bca2285e4940c4d1140301e8df (diff)
downloadc-wares-0a8ee7a194e598d9c277b019503f7119b32bd17f.tar.gz
c-wares-0a8ee7a194e598d9c277b019503f7119b32bd17f.zip
cli: make it possible to extend option types
Make it possible to extend options with custom value parsers by embeding `struct cli_opt` into a custom struct and setting the `set()` "method".
Diffstat (limited to 'cli/cli-test.c')
-rw-r--r--cli/cli-test.c244
1 files changed, 82 insertions, 162 deletions
diff --git a/cli/cli-test.c b/cli/cli-test.c
index 5af572c..c7a74e9 100644
--- a/cli/cli-test.c
+++ b/cli/cli-test.c
@@ -12,42 +12,49 @@
_s; \
})
+CLI_OPT_LONG(sopt, 's', "signed", NULL);
+CLI_OPT_ULONG(uopt, 'u', "unsigned", NULL);
+CLI_OPT_STRING(stropt, 'S', "string", NULL);
+CLI_OPT_FLAG(aopt, 'a', "flag-a", NULL);
+CLI_OPT_FLAG(bopt, 'b', "flag-b", NULL);
+CLI_OPT_FLAG(copt, 'c', "flag-c", NULL);
+
+struct expected {
+ long i;
+ unsigned long u;
+ const char *s;
+ bool a;
+ bool b;
+ bool c;
+};
+
+struct cli_opt *options[] = {
+ &sopt.opt,
+ &uopt.opt,
+ &stropt.opt,
+ &aopt.opt,
+ &bopt.opt,
+ &copt.opt,
+ NULL,
+};
+
+static void reset_opts(void)
+{
+ sopt.value = 0;
+ uopt.value = 0;
+ stropt.value = NULL;
+ aopt.value = 0;
+ bopt.value = 0;
+ copt.value = 0;
+}
+
TEST_BEGIN(test_parse_long)
{
- struct vars {
- long i;
- unsigned long u;
- const char *s;
- bool f;
- } vars;
- struct cli_opt options[] = {
- {
- .type = CLI_OT_INT,
- .lon = "signed",
- .value.i = &vars.i,
- },
- {
- .type = CLI_OT_FLAG,
- .lon = "flag",
- .value.f = &vars.f,
- },
- {
- .type = CLI_OT_UINT,
- .lon = "unsigned",
- .value.u = &vars.u,
- },
- {
- .type = CLI_OT_STRING,
- .lon = "string",
- .value.s = &vars.s,
- },
- {0},
- };
struct tcase {
- int argc;
- char *argv[2];
- struct vars expected_vars;
- enum cli_rc expected_rc;
+ int argc;
+ char *argv[2];
+ struct expected expected_vars;
+ enum cli_rc expected_rc;
} cases[] = {
{
.argc = 2,
@@ -61,7 +68,8 @@ TEST_BEGIN(test_parse_long)
.i = -2,
.u = 0,
.s = NULL,
- .f = 0,
+ .a = false,
+ 0,
},
.expected_rc = CLI_RC_OK,
},
@@ -69,7 +77,7 @@ TEST_BEGIN(test_parse_long)
.argc = 2,
.argv =
{
- MUTSTR("--flag"),
+ MUTSTR("--flag-a"),
MUTSTR("--unsigned=42"),
},
.expected_vars =
@@ -77,7 +85,8 @@ TEST_BEGIN(test_parse_long)
.i = 0,
.u = 0,
.s = NULL,
- .f = true,
+ .a = true,
+ 0,
},
.expected_rc = CLI_RC_OK,
},
@@ -92,7 +101,8 @@ TEST_BEGIN(test_parse_long)
.i = 0,
.u = 42,
.s = NULL,
- .f = false,
+ .a = false,
+ 0,
},
.expected_rc = CLI_RC_OK,
},
@@ -107,7 +117,8 @@ TEST_BEGIN(test_parse_long)
.i = 0xB00B,
.u = 0,
.s = NULL,
- .f = false,
+ .a = false,
+ 0,
},
.expected_rc = CLI_RC_OK,
},
@@ -123,7 +134,8 @@ TEST_BEGIN(test_parse_long)
.i = 0,
.u = 0,
.s = "wololo",
- .f = false,
+ .a = false,
+ 0,
},
.expected_rc = CLI_RC_OK,
},
@@ -138,7 +150,7 @@ TEST_BEGIN(test_parse_long)
},
};
for (size_t i = 0; i < ARRAY_SIZE(cases); i++) {
- vars = (struct vars){0};
+ reset_opts();
struct cli_ctx ctx = {
.opts = options,
.argc = cases[i].argc,
@@ -146,15 +158,15 @@ TEST_BEGIN(test_parse_long)
};
int rc = parse_long(&ctx);
asserteq(rc, cases[i].expected_rc);
- asserteq(vars.i, cases[i].expected_vars.i);
- asserteq(vars.u, cases[i].expected_vars.u);
+ asserteq(sopt.value, cases[i].expected_vars.i);
+ asserteq(uopt.value, cases[i].expected_vars.u);
if (cases[i].expected_vars.s) {
- assertneq(vars.s, NULL);
- asserteq(strcmp(vars.s, cases[i].expected_vars.s), 0);
+ assertneq(stropt.value, NULL);
+ asserteq(strcmp(stropt.value, cases[i].expected_vars.s), 0);
} else {
- asserteq(vars.s, NULL);
+ asserteq(stropt.value, NULL);
}
- asserteq(vars.f, cases[i].expected_vars.f);
+ asserteq(aopt.value, cases[i].expected_vars.a);
}
TEST_OUT
}
@@ -162,58 +174,17 @@ TEST_END
TEST_BEGIN(test_parse_short)
{
- struct vars {
- long i;
- unsigned long u;
- const char *s;
- bool a;
- bool b;
- bool c;
- } vars;
- struct cli_opt options[] = {
- {
- .type = CLI_OT_INT,
- .shor = 'i',
- .value.i = &vars.i,
- },
- {
- .type = CLI_OT_FLAG,
- .shor = 'a',
- .value.f = &vars.a,
- },
- {
- .type = CLI_OT_FLAG,
- .shor = 'b',
- .value.f = &vars.b,
- },
- {
- .type = CLI_OT_FLAG,
- .shor = 'c',
- .value.f = &vars.c,
- },
- {
- .type = CLI_OT_UINT,
- .shor = 'u',
- .value.u = &vars.u,
- },
- {
- .type = CLI_OT_STRING,
- .shor = 's',
- .value.s = &vars.s,
- },
- {0},
- };
struct tcase {
- int argc;
- char *argv[2];
- struct vars expected_vars;
- enum cli_rc expected_rc;
+ int argc;
+ char *argv[2];
+ struct expected expected_vars;
+ enum cli_rc expected_rc;
} cases[] = {
{
.argc = 2,
.argv =
{
- MUTSTR("-i-2"),
+ MUTSTR("-s-2"),
MUTSTR("-b"),
},
.expected_vars =
@@ -248,7 +219,7 @@ TEST_BEGIN(test_parse_short)
.argc = 1,
.argv =
{
- MUTSTR("-sab"),
+ MUTSTR("-Sab"),
},
.expected_vars =
{
@@ -299,7 +270,7 @@ TEST_BEGIN(test_parse_short)
},
};
for (size_t i = 0; i < ARRAY_SIZE(cases); i++) {
- vars = (struct vars){0};
+ reset_opts();
struct cli_ctx ctx = {
.opts = options,
.argc = cases[i].argc,
@@ -307,17 +278,15 @@ TEST_BEGIN(test_parse_short)
};
int rc = parse_short(&ctx);
asserteq(rc, cases[i].expected_rc);
- asserteq(vars.i, cases[i].expected_vars.i);
- asserteq(vars.u, cases[i].expected_vars.u);
+ asserteq(sopt.value, cases[i].expected_vars.i);
+ asserteq(uopt.value, cases[i].expected_vars.u);
if (cases[i].expected_vars.s) {
- assertneq(vars.s, NULL);
- asserteq(strcmp(vars.s, cases[i].expected_vars.s), 0);
+ assertneq(stropt.value, NULL);
+ asserteq(strcmp(stropt.value, cases[i].expected_vars.s), 0);
} else {
- asserteq(vars.s, NULL);
+ asserteq(stropt.value, NULL);
}
- asserteq(vars.a, cases[i].expected_vars.a);
- asserteq(vars.b, cases[i].expected_vars.b);
- asserteq(vars.c, cases[i].expected_vars.c);
+ asserteq(aopt.value, cases[i].expected_vars.a);
}
TEST_OUT
}
@@ -325,58 +294,11 @@ TEST_END
TEST_BEGIN(test_parse_options)
{
- struct vars {
- long i;
- unsigned long u;
- const char *s;
- bool a;
- bool b;
- bool c;
- } vars;
- struct cli_opt options[] = {
- {
- .type = CLI_OT_INT,
- .lon = "signed",
- .shor = 's',
- .value.i = &vars.i,
- },
- {
- .type = CLI_OT_FLAG,
- .lon = "flag-a",
- .shor = 'a',
- .value.f = &vars.a,
- },
- {
- .type = CLI_OT_FLAG,
- .lon = "flag-b",
- .shor = 'b',
- .value.f = &vars.b,
- },
- {
- .type = CLI_OT_FLAG,
- .lon = "flag-c",
- .shor = 'c',
- .value.f = &vars.c,
- },
- {
- .type = CLI_OT_UINT,
- .lon = "unsigned",
- .shor = 'u',
- .value.u = &vars.u,
- },
- {
- .type = CLI_OT_STRING,
- .lon = "string",
- .shor = 'S',
- .value.s = &vars.s,
- },
- {0},
- };
struct tcase {
- int argc;
- char *argv[8];
- struct vars expected_vars;
- enum cli_rc expected_rc;
+ int argc;
+ char *argv[8];
+ struct expected expected_vars;
+ enum cli_rc expected_rc;
} cases[] = {
{
.argc = 5,
@@ -497,7 +419,7 @@ TEST_BEGIN(test_parse_options)
},
};
for (size_t i = 0; i < ARRAY_SIZE(cases); i++) {
- vars = (struct vars){0};
+ reset_opts();
struct cli_ctx ctx = {
.opts = options,
.argc = cases[i].argc,
@@ -505,17 +427,15 @@ TEST_BEGIN(test_parse_options)
};
int rc = parse_options(&ctx);
asserteq(rc, cases[i].expected_rc);
- asserteq(vars.i, cases[i].expected_vars.i);
- asserteq(vars.u, cases[i].expected_vars.u);
+ asserteq(sopt.value, cases[i].expected_vars.i);
+ asserteq(uopt.value, cases[i].expected_vars.u);
if (cases[i].expected_vars.s) {
- assertneq(vars.s, NULL);
- asserteq(strcmp(vars.s, cases[i].expected_vars.s), 0);
+ assertneq(stropt.value, NULL);
+ asserteq(strcmp(stropt.value, cases[i].expected_vars.s), 0);
} else {
- asserteq(vars.s, NULL);
+ asserteq(stropt.value, NULL);
}
- asserteq(vars.a, cases[i].expected_vars.a);
- asserteq(vars.b, cases[i].expected_vars.b);
- asserteq(vars.c, cases[i].expected_vars.c);
+ asserteq(aopt.value, cases[i].expected_vars.a);
}
TEST_OUT
}