From c36444e062622d97e4368670f5c50f0c482a3a95 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 4 Feb 2020 11:40:36 +1030 Subject: [PATCH] opt: add opt_unregister. Sometimes we all make mistakes. Signed-off-by: Rusty Russell --- ccan/opt/opt.c | 17 +++++++++++++ ccan/opt/opt.h | 9 +++++++ ccan/opt/test/run-unregister.c | 44 ++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 ccan/opt/test/run-unregister.c diff --git a/ccan/opt/opt.c b/ccan/opt/opt.c index 0514dc87..d4601dfb 100644 --- a/ccan/opt/opt.c +++ b/ccan/opt/opt.c @@ -176,6 +176,23 @@ void _opt_register(const char *names, enum opt_type type, add_opt(&opt); } +bool opt_unregister(const char *names) +{ + int found = -1, i; + + for (i = 0; i < opt_count; i++) { + if (opt_table[i].type == OPT_SUBTABLE) + continue; + if (strcmp(opt_table[i].names, names) == 0) + found = i; + } + if (found == -1) + return false; + opt_count--; + memmove(&opt_table[found], &opt_table[found+1], opt_count - found); + return true; +} + void opt_register_table(const struct opt_table entry[], const char *desc) { unsigned int i, start = opt_count; diff --git a/ccan/opt/opt.h b/ccan/opt/opt.h index c642ec6f..6f4b9dda 100644 --- a/ccan/opt/opt.h +++ b/ccan/opt/opt.h @@ -228,6 +228,15 @@ void opt_register_table(const struct opt_table *table, const char *desc); _opt_register((names), OPT_CB_ARG((cb), OPT_EARLY, (show),(arg)), \ (arg), (desc)) +/** + * opt_unregister - unregister an option. + * @names: the names it was registered with. + * + * This undoes opt_register[_early]_[no]arg. Returns true if the option was + * found, otherwise false. + */ +bool opt_unregister(const char *names); + /** * opt_parse - parse arguments. * @argc: pointer to argc diff --git a/ccan/opt/test/run-unregister.c b/ccan/opt/test/run-unregister.c new file mode 100644 index 00000000..06bf58a0 --- /dev/null +++ b/ccan/opt/test/run-unregister.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include +#include "utils.h" + +int main(int argc, char *argv[]) +{ + const char *myname = argv[0]; + + plan_tests(14); + + /* Simple short arg.*/ + opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll"); + opt_register_noarg("-b", test_noarg, NULL, "AAAAAAll"); + + /* We can't unregister wrong ones, but can unregister correct one */ + ok1(!opt_unregister("--aaa")); + ok1(!opt_unregister("-a")); + ok1(opt_unregister("--aaa|-a")); + + /* Arg parsing works as if we'd never registered it */ + ok1(parse_args(&argc, &argv, "-b", NULL)); + ok1(argc == 1); + ok1(argv[0] == myname); + ok1(argv[1] == NULL); + ok1(test_cb_called == 1); + + ok1(!parse_args(&argc, &argv, "--aaa", NULL)); + + /* We can still add another one OK. */ + opt_register_noarg("-c", test_noarg, NULL, "AAAAAAll"); + ok1(parse_args(&argc, &argv, "-c", NULL)); + ok1(argc == 1); + ok1(argv[0] == myname); + ok1(argv[1] == NULL); + ok1(test_cb_called == 2); + + /* parse_args allocates argv */ + free(argv); + return exit_status(); +} -- 2.39.2