From f77e5a5ec7f8b1373eeda0ea56f47137daf40330 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sat, 4 Jan 2025 17:57:28 -0800 Subject: args: Convert nng_opts_parse into a header only library using `nng_args_parse`. The API is identical, except that some names have changed, and this is now a header library in `nng/args.h` - so the core library does not need to carry this code in binaries. Being a header library also means it is not necessary to link against NNG, and it does not include any parts of NNG; it only depends on a standard C99 or C11 environment. --- src/supplemental/CMakeLists.txt | 1 - src/supplemental/util/CMakeLists.txt | 13 -- src/supplemental/util/options.c | 127 ------------- src/supplemental/util/options_test.c | 341 ----------------------------------- 4 files changed, 482 deletions(-) delete mode 100644 src/supplemental/util/CMakeLists.txt delete mode 100644 src/supplemental/util/options.c delete mode 100644 src/supplemental/util/options_test.c (limited to 'src/supplemental') diff --git a/src/supplemental/CMakeLists.txt b/src/supplemental/CMakeLists.txt index 9a54beea..fe808c8d 100644 --- a/src/supplemental/CMakeLists.txt +++ b/src/supplemental/CMakeLists.txt @@ -11,5 +11,4 @@ nng_directory(supplemental) add_subdirectory(http) add_subdirectory(tls) -add_subdirectory(util) add_subdirectory(websocket) diff --git a/src/supplemental/util/CMakeLists.txt b/src/supplemental/util/CMakeLists.txt deleted file mode 100644 index d7541363..00000000 --- a/src/supplemental/util/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright 2025 Staysail Systems, Inc. -# -# This software is supplied under the terms of the MIT License, a -# copy of which should be located in the distribution where this -# file was obtained (LICENSE.txt). A copy of the license may also be -# found online at https://opensource.org/licenses/MIT. -# - -nng_sources(options.c) -nng_headers( - nng/supplemental/util/options.h) -nng_test(options_test) diff --git a/src/supplemental/util/options.c b/src/supplemental/util/options.c deleted file mode 100644 index 961e0bb2..00000000 --- a/src/supplemental/util/options.c +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2018 Staysail Systems, Inc. -// Copyright 2018 Capitar IT Group BV -// -// This software is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -#include -#include - -#include -#include - -#include "core/nng_impl.h" - -// Call with optidx set to 1 to start parsing. -int -nng_opts_parse(int argc, char *const *argv, const nng_optspec *opts, int *val, - char **optarg, int *optidx) -{ - const nng_optspec *opt; - int matches; - bool shortopt; - size_t l; - char * arg; - int i; - - if ((i = *optidx) >= argc) { - return (-1); - } - arg = argv[*optidx]; - - if (arg[0] != '-') { - return (-1); - } - if (arg[1] == '\0') { - *optidx = i + 1; - return (-1); - } - - if ((arg[0] == '-') && (arg[1] == '-')) { - arg += 2; - shortopt = false; - for (l = 0; arg[l] != '\0'; l++) { - if ((arg[l] == '=') || (arg[l] == ':')) { - break; - } - } - } else { - arg++; - shortopt = true; - l = 1; - } - - matches = 0; - opt = NULL; - - for (int x = 0; opts[x].o_val != 0; x++) { - - if (shortopt) { - if (arg[0] == opts[x].o_short) { - matches = 1; - opt = &opts[x]; - break; - } - continue; - } - - if ((opts[x].o_name == NULL) || - (strncmp(arg, opts[x].o_name, l) != 0)) { - continue; - } - matches++; - opt = &opts[x]; - - if (strlen(opts[x].o_name) == l) { - // Perfect match. - matches = 1; - break; - } - } - - switch (matches) { - case 1: - // Exact match - break; - case 0: - // No such option - return (NNG_EINVAL); - break; - default: - // Ambiguous (not match) - return (NNG_EAMBIGUOUS); - break; - } - - if (!opt->o_arg) { - // No option clustering for short options yet. - if (arg[l] != '\0') { - return (NNG_EINVAL); - } - *val = opt->o_val; - *optidx = i + 1; - return (0); - } - - if (arg[l] != '\0') { - if (shortopt) { - *optarg = arg + l; - } else { - *optarg = arg + l + 1; - } - } else { - i++; - if (i >= argc) { - return (NNG_ENOARG); - } - *optarg = argv[i]; - } - *optidx = ++i; - *val = opt->o_val; - - return (0); -} diff --git a/src/supplemental/util/options_test.c b/src/supplemental/util/options_test.c deleted file mode 100644 index 036f2940..00000000 --- a/src/supplemental/util/options_test.c +++ /dev/null @@ -1,341 +0,0 @@ -// -// Copyright 2024 Staysail Systems, Inc. -// Copyright 2018 Capitar IT Group BV -// -// This software is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -#include "nng/nng.h" -#include - -#include - -static nng_optspec case1[] = { - // clang-format off - { "flag", 'f', 1, false }, - { "longflag", 0, 2, false }, - { "value", 'v', 3, true }, - { NULL, 'b', 4, false }, - { NULL, 0, 0, false }, - // clang-format on -}; - -void -test_simple_options(void) -{ - int opti = 1; - char *av[6]; - int ac = 5; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "-f"; - av[2] = "-v"; - av[3] = "123"; - av[4] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(v == 1); - NUTS_NULL(a); - NUTS_TRUE(opti == 2); - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 4); - NUTS_TRUE(v == 3); - NUTS_MATCH(a, "123"); - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 4); - NUTS_MATCH(av[opti], "456"); -} - -void -test_long_options(void) -{ - int opti = 1; - char *av[6]; - int ac = 5; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "--flag"; - av[2] = "--value"; - av[3] = "123"; - av[4] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(v == 1); - NUTS_NULL(a); - NUTS_TRUE(opti == 2); - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 4); - NUTS_TRUE(v == 3); - NUTS_MATCH(a, "123"); - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 4); - NUTS_MATCH(av[opti], "456"); -} - -void -test_attached_short(void) -{ - int opti = 1; - char *av[3]; - int ac = 3; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "-v123"; - av[2] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 2); - NUTS_TRUE(v == 3); - NUTS_MATCH(a, "123"); - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 2); - NUTS_MATCH(av[opti], "456"); -} - -void -test_attached_long_equals(void) -{ - int opti = 1; - char *av[3]; - int ac = 3; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "--value=123"; - av[2] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 2); - NUTS_TRUE(v == 3); - NUTS_MATCH(a, "123"); - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 2); - NUTS_MATCH(av[opti], "456"); -} - -void -test_attached_long_colon(void) -{ - int opti = 1; - char *av[3]; - int ac = 3; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "--value:123"; - av[2] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 2); - NUTS_TRUE(v == 3); - NUTS_MATCH(a, "123"); - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 2); - NUTS_MATCH(av[opti], "456"); -} - -void -test_negative_bad_short(void) -{ - int opti = 1; - char *av[3]; - int ac = 3; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "-Z"; - av[2] = "456"; - NUTS_FAIL(nng_opts_parse(ac, av, case1, &v, &a, &opti), NNG_EINVAL); - NUTS_TRUE(opti == 1); -} - -void -test_negative_bad_long(void) -{ - int opti = 1; - char *av[3]; - int ac = 3; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "--something"; - av[2] = "456"; - NUTS_FAIL(nng_opts_parse(ac, av, case1, &v, &a, &opti), NNG_EINVAL); - NUTS_TRUE(opti == 1); -} - -void -test_option_separator_flag(void) -{ - int opti = 1; - char *av[5]; - int ac = 5; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "-f"; - av[2] = "-"; - av[3] = "-v"; - av[4] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(v == 1); - NUTS_TRUE(opti == 2); - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 3); -} - -void -test_no_options(void) -{ - int opti = 1; - char *av[1]; - int ac = 1; - int v; - char *a = NULL; - - av[0] = "program"; - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); -} - -void -test_arg_only(void) -{ - int opti = 1; - char *av[2]; - int ac = 2; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "123"; - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 1); -} - -void -test_mixed_long_short(void) -{ - int opti = 1; - char *av[7]; - int ac = 7; - int v; - char *a = NULL; - - av[0] = "program"; - av[1] = "--value=123"; - av[2] = "-f"; - av[3] = "--longflag"; - av[4] = "-b"; - av[5] = "-vxyz"; - av[6] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 2); - NUTS_TRUE(v == 3); - NUTS_MATCH(a, "123"); - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 3); - NUTS_TRUE(v == 1); - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 4); - NUTS_TRUE(v == 2); - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 5); - NUTS_TRUE(v == 4); - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); - NUTS_TRUE(opti == 6); - NUTS_TRUE(v == 3); - NUTS_MATCH(a, "xyz"); - NUTS_MATCH(av[opti], "456"); - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); - NUTS_TRUE(opti == 6); -} - -void -test_ambiguous(void) -{ - int opti = 1; - char *av[2]; - int ac = 2; - int v; - char *a = NULL; - - nng_optspec spec[] = { - { "flag", 'f', 1, false }, - { "fluid", 0, 2, false }, - { NULL, 0, 0, false }, - }; - - av[0] = "program"; - av[1] = "--fl"; - NUTS_FAIL(nng_opts_parse(ac, av, spec, &v, &a, &opti), NNG_EAMBIGUOUS); -} - -void -test_missing_arg(void) -{ - int opti = 1; - char *av[2]; - int ac = 2; - int v; - char *a = NULL; - - nng_optspec spec[] = { - { "flag", 'f', 1, true }, - { NULL, 0, 0, false }, - }; - - av[0] = "program"; - av[1] = "--fl"; - NUTS_FAIL(nng_opts_parse(ac, av, spec, &v, &a, &opti), NNG_ENOARG); - av[0] = "program"; - av[1] = "-f"; - opti = 1; - NUTS_FAIL(nng_opts_parse(ac, av, spec, &v, &a, &opti), NNG_ENOARG); -} - -void -test_no_clustering(void) -{ - int opti = 1; - char *av[2]; - int ac = 2; - int v; - char *a = NULL; - - nng_optspec spec[] = { - { "flag", 'f', 1, false }, - { "verbose", 'v', 2, false }, - { NULL, 0, 0, false }, - }; - - av[0] = "program"; - av[1] = "-fv"; - NUTS_FAIL(nng_opts_parse(ac, av, spec, &v, &a, &opti), NNG_EINVAL); -} - -NUTS_TESTS = { - { "simple options", test_simple_options }, - { "long options", test_long_options }, - { "separator flag", test_option_separator_flag }, - { "no options", test_no_options }, - { "attached short", test_attached_long_equals }, - { "attached long equals", test_attached_long_equals }, - { "attached long colon", test_attached_long_colon }, - { "bad short", test_negative_bad_short }, - { "bad long", test_negative_bad_long }, - { "arg only", test_arg_only }, - { "options mixed long short", test_mixed_long_short }, - { "ambiguous options", test_ambiguous }, - { "missing argument", test_missing_arg }, - { "no clustering", test_no_clustering }, - { NULL, NULL }, -}; -- cgit v1.2.3-70-g09d2