]> git.ozlabs.org Git - ccan/blobdiff - ccan/opt/test/run.c
opt: wean off getopt_long, beef up tests.
[ccan] / ccan / opt / test / run.c
index 26c69dff628e918443296e34e5aac01896b01002..8982baa048de8cbed2c4de0f32a799b61388defb 100644 (file)
@@ -2,13 +2,15 @@
 #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"
 
 static void reset_options(void)
 {
        free(opt_table);
        opt_table = NULL;
-       opt_count = 0;
+       opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0;
        free(err_output);
        err_output = NULL;
 }
@@ -17,10 +19,10 @@ int main(int argc, char *argv[])
 {
        const char *myname = argv[0];
 
-       plan_tests(148);
+       plan_tests(215);
 
        /* Simple short arg.*/
-       opt_register_noarg(NULL, 'a', test_noarg, NULL, NULL);
+       opt_register_noarg("-a", test_noarg, NULL, "All");
        ok1(parse_args(&argc, &argv, "-a", NULL));
        ok1(argc == 1);
        ok1(argv[0] == myname);
@@ -28,7 +30,7 @@ int main(int argc, char *argv[])
        ok1(test_cb_called == 1);
 
        /* Simple long arg. */
-       opt_register_noarg("aaa", 0, test_noarg, NULL, NULL);
+       opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
        ok1(parse_args(&argc, &argv, "--aaa", NULL));
        ok1(argc == 1);
        ok1(argv[0] == myname);
@@ -36,7 +38,7 @@ int main(int argc, char *argv[])
        ok1(test_cb_called == 2);
 
        /* Both long and short args. */
-       opt_register_noarg("aaa", 'a', test_noarg, NULL, NULL);
+       opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll");
        ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL));
        ok1(argc == 1);
        ok1(argv[0] == myname);
@@ -51,10 +53,18 @@ int main(int argc, char *argv[])
        ok1(strcmp(argv[2], "args") == 0);
        ok1(test_cb_called == 6);
 
+       /* Malformed versions. */
+       ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL));
+       ok1(strstr(err_output, ": --aaa: doesn't allow an argument"));
+       ok1(!parse_args(&argc, &argv, "--aa", NULL));
+       ok1(strstr(err_output, ": --aa: unrecognized option"));
+       ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
+       ok1(strstr(err_output, ": --aaargh: unrecognized option"));
+
        /* Argument variants. */
        reset_options();
        test_cb_called = 0;
-       opt_register_arg("aaa", 'a', test_arg, NULL, "aaa", NULL);
+       opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
        ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
        ok1(argc == 1);
        ok1(argv[0] == myname);
@@ -70,6 +80,16 @@ int main(int argc, char *argv[])
        ok1(argv[0] == myname);
        ok1(test_cb_called == 3);
 
+       /* Malformed versions. */
+       ok1(!parse_args(&argc, &argv, "-a", NULL));
+       ok1(strstr(err_output, ": -a: requires an argument"));
+       ok1(!parse_args(&argc, &argv, "--aaa", NULL));
+       ok1(strstr(err_output, ": --aaa: requires an argument"));
+       ok1(!parse_args(&argc, &argv, "--aa", NULL));
+       ok1(strstr(err_output, ": --aa: unrecognized option"));
+       ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
+       ok1(strstr(err_output, ": --aaargh: unrecognized option"));
+
        /* Now, tables. */
        /* Short table: */
        reset_options();
@@ -201,7 +221,7 @@ int main(int argc, char *argv[])
        reset_options();
 
        /* glibc's getopt does not handle ? with arguments. */
-       opt_register_noarg(NULL, '?', test_noarg, NULL, NULL);
+       opt_register_noarg("-?", test_noarg, NULL, "Help");
        ok1(parse_args(&argc, &argv, "-?", NULL));
        ok1(test_cb_called == 1);
        ok1(parse_args(&argc, &argv, "-a", NULL) == false);
@@ -214,5 +234,62 @@ int main(int argc, char *argv[])
        test_cb_called = 0;
        reset_options();
 
+       /* Corner cases involving short arg parsing weirdness. */
+       opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
+       opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b");
+       opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c");
+       /* -aa == -a -a */
+       ok1(parse_args(&argc, &argv, "-aa", NULL));
+       ok1(test_cb_called == 2);
+       ok1(parse_args(&argc, &argv, "-aab", NULL) == false);
+       ok1(test_cb_called == 4);
+       ok1(strstr(err_output, ": -b: requires an argument"));
+       ok1(parse_args(&argc, &argv, "-bbbb", NULL));
+       ok1(test_cb_called == 5);
+       ok1(parse_args(&argc, &argv, "-aabbbb", NULL));
+       ok1(test_cb_called == 8);
+       ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL));
+       ok1(test_cb_called == 12);
+       ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL));
+       ok1(test_cb_called == 16);
+       ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL));
+       ok1(test_cb_called == 20);
+       ok1(parse_args(&argc, &argv, "-aacaaa", NULL));
+       ok1(test_cb_called == 23);
+       ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL));
+       ok1(test_cb_called == 27);
+       ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa",
+                      NULL));
+       ok1(test_cb_called == 34);
+
+       test_cb_called = 0;
+       reset_options();
+
+       /* -- and POSIXLY_CORRECT */
+       opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
+       ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL));
+       ok1(test_cb_called == 1);
+       ok1(argc == 2);
+       ok1(strcmp(argv[1], "-a") == 0);
+       ok1(!argv[2]);
+
+       unsetenv("POSIXLY_CORRECT");
+       ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
+       ok1(test_cb_called == 3);
+       ok1(argc == 3);
+       ok1(strcmp(argv[1], "somearg") == 0);
+       ok1(strcmp(argv[2], "-a") == 0);
+       ok1(!argv[3]);
+
+       setenv("POSIXLY_CORRECT", "1", 1);
+       ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
+       ok1(test_cb_called == 4);
+       ok1(argc == 5);
+       ok1(strcmp(argv[1], "somearg") == 0);
+       ok1(strcmp(argv[2], "-a") == 0);
+       ok1(strcmp(argv[3], "--") == 0);
+       ok1(strcmp(argv[4], "-a") == 0);
+       ok1(!argv[5]);
+
        return exit_status();
 }