diff options
author | Yaroslav de la Peña Smirnov <yps@yaroslavps.com> | 2025-09-16 20:38:59 +0300 |
---|---|---|
committer | Yaroslav de la Peña Smirnov <yps@yaroslavps.com> | 2025-09-16 20:38:59 +0300 |
commit | 5556ee3afa4dc015a73bff7bcddd65d14c6a57c6 (patch) | |
tree | 0bad83a6eeeb621059e5506774e677953d19031c /cli | |
parent | 9e7132fff6d905e43955803892046e0a0b1dd8fb (diff) | |
download | c-wares-5556ee3afa4dc015a73bff7bcddd65d14c6a57c6.tar.gz c-wares-5556ee3afa4dc015a73bff7bcddd65d14c6a57c6.zip |
cli: make long and ulong options more strict
Also add unit tests for them.
Diffstat (limited to 'cli')
-rw-r--r-- | cli/cli-test.c | 51 | ||||
-rw-r--r-- | cli/cli.h | 10 |
2 files changed, 57 insertions, 4 deletions
diff --git a/cli/cli-test.c b/cli/cli-test.c index c1d7591..0a52782 100644 --- a/cli/cli-test.c +++ b/cli/cli-test.c @@ -76,6 +76,55 @@ TEST_BEGIN(test_cli_opt_data_size_set) } TEST_END +TEST_BEGIN(test_cli_opt_long_set) +{ + CLI_OPT_LONG(opt, 0, NULL, NULL); + struct tcase { + const char *input; + long expected_val; + enum cli_rc expected_rc; + } cases[] = { + {"420", 420, CLI_RC_OK}, + {"4K", 0, CLI_RC_BAD_ARGS}, + {"-6", -6, CLI_RC_OK}, + {"0.2", 0, CLI_RC_BAD_ARGS}, + }; + for (size_t i = 0; i < ARRAY_SIZE(cases); i++) { + opt.value = 0; + int rc = opt.opt.set(&opt.opt, cases[i].input); + asserteq(rc, cases[i].expected_rc); + if (rc == CLI_RC_OK) + asserteq(opt.value, cases[i].expected_val); + } + TEST_OUT +} +TEST_END + +TEST_BEGIN(test_cli_opt_ulong_set) +{ + CLI_OPT_ULONG(opt, 0, NULL, NULL); + struct tcase { + const char *input; + unsigned long expected_val; + enum cli_rc expected_rc; + } cases[] = { + {"420", 420, CLI_RC_OK}, + {"4K", 0, CLI_RC_BAD_ARGS}, + {"-6", -6, CLI_RC_OK}, // C typing discipline really is this bad + {"0.2", 0, CLI_RC_BAD_ARGS}, + {"0xB00B5", 0xB00B5, CLI_RC_OK}, + }; + for (size_t i = 0; i < ARRAY_SIZE(cases); i++) { + opt.value = 0; + int rc = opt.opt.set(&opt.opt, cases[i].input); + asserteq(rc, cases[i].expected_rc); + if (rc == CLI_RC_OK) + asserteq(opt.value, cases[i].expected_val); + } + TEST_OUT +} +TEST_END + TEST_BEGIN(test_parse_long) { struct tcase { @@ -470,6 +519,8 @@ TEST_BEGIN(test_parse_options) TEST_END RUN_TESTS(test_cli_opt_data_size_set, + test_cli_opt_long_set, + test_cli_opt_ulong_set, test_parse_long, test_parse_short, test_parse_options) @@ -104,8 +104,9 @@ int cli_opt_long_set(struct cli_opt *self, const char *val) struct cli_opt_long *opt = container_of(self, struct cli_opt_long, opt); errno = 0; - opt->value = strtol(val, NULL, 0); - if (errno != 0) + char *endptr; + opt->value = strtol(val, &endptr, 0); + if (errno != 0 || *endptr != '\0') return CLI_RC_BAD_ARGS; return CLI_RC_OK; @@ -133,8 +134,9 @@ int cli_opt_ulong_set(struct cli_opt *self, const char *val) struct cli_opt_ulong *opt = container_of(self, struct cli_opt_ulong, opt); errno = 0; - opt->value = strtoul(val, NULL, 0); - if (errno != 0) + char *endptr; + opt->value = strtoul(val, &endptr, 0); + if (errno != 0 || *endptr != '\0') return CLI_RC_BAD_ARGS; return CLI_RC_OK; |