]> git.ozlabs.org Git - ccan/commitdiff
opt: add opt_unregister.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 4 Feb 2020 01:10:36 +0000 (11:40 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 4 Feb 2020 01:10:36 +0000 (11:40 +1030)
Sometimes we all make mistakes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/opt/opt.c
ccan/opt/opt.h
ccan/opt/test/run-unregister.c [new file with mode: 0644]

index 0514dc8702dfc8ef2327d892f7cbd7606dec2b06..d4601dfbb230a3076edfa64d8b5232996f4d59d2 100644 (file)
@@ -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;
index c642ec6fafc85d1b87377458d69fa9e3d909101c..6f4b9dda8c85a4f33389863963b57f1a87214ea4 100644 (file)
@@ -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 (file)
index 0000000..06bf58a
--- /dev/null
@@ -0,0 +1,44 @@
+#include <ccan/tap/tap.h>
+#include <stdlib.h>
+#include <ccan/opt/opt.c>
+#include <ccan/opt/usage.c>
+#include <ccan/opt/helpers.c>
+#include <ccan/opt/parse.c>
+#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();
+}