From f77e5a5ec7f8b1373eeda0ea56f47137daf40330 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sat, 4 Jan 2025 17:57:28 -0800 Subject: [PATCH] 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. --- docs/ref/SUMMARY.md | 2 +- docs/ref/api/{cmd_opts.md => args.md} | 96 +++++----- docs/ref/api/errors.md | 2 - docs/ref/migrate/nanomsg.md | 2 +- docs/ref/migrate/nng1.md | 10 +- docs/ref/xref.md | 4 +- include/nng/args.h | 163 +++++++++++++++++ include/nng/nng.h | 2 - include/nng/supplemental/util/options.h | 50 ------ src/CMakeLists.txt | 3 +- src/core/CMakeLists.txt | 1 + .../util/options_test.c => core/args_test.c} | 71 ++++---- src/nng.c | 2 - src/sp/protocol/pipeline0/pull_test.c | 4 +- src/sp/protocol/pubsub0/sub_test.c | 4 +- src/supplemental/CMakeLists.txt | 1 - src/supplemental/util/CMakeLists.txt | 13 -- src/supplemental/util/options.c | 127 -------------- src/tools/nngcat/nngcat.c | 164 +++++++++--------- src/tools/perf/perf.c | 26 +-- 20 files changed, 370 insertions(+), 377 deletions(-) rename docs/ref/api/{cmd_opts.md => args.md} (61%) create mode 100644 include/nng/args.h delete mode 100644 include/nng/supplemental/util/options.h rename src/{supplemental/util/options_test.c => core/args_test.c} (72%) delete mode 100644 src/supplemental/util/CMakeLists.txt delete mode 100644 src/supplemental/util/options.c diff --git a/docs/ref/SUMMARY.md b/docs/ref/SUMMARY.md index 92f24307e..f36c5086b 100644 --- a/docs/ref/SUMMARY.md +++ b/docs/ref/SUMMARY.md @@ -38,7 +38,7 @@ - [ID Map](./api/id_map.md) - - [Command Options](./api/cmd_opts.md) + - [Arguments Parser](./api/args.md) - [Protocols](./proto/index.md) diff --git a/docs/ref/api/cmd_opts.md b/docs/ref/api/args.md similarity index 61% rename from docs/ref/api/cmd_opts.md rename to docs/ref/api/args.md index c28d3f89f..a40cef94f 100644 --- a/docs/ref/api/cmd_opts.md +++ b/docs/ref/api/args.md @@ -1,31 +1,39 @@ -# Command Options +# Command Arguments -Some _NNG_ utilities need to parse command line options, -and the supplementary function here allows applications that -need the same support to benefit from this. +Some NNG utilities need to parse command line options, +and for this purpose a header library is supplied. -To make use of this, the supplemental header `` -must be included. +To make use of this, the header `` must be included. -## Parse Command Line Options +> [!TIP] +> The functionality described here is entirely contained in the +> `nng/args.h` header file, and may be used without previously +> initializing the library with [`nng_init`], and may even be used +> in programs that are not linked against the NNG library. + +## Parse Command Line Arguments ```c -typedef struct nng_optspec { - const char *o_name; // Long style name (may be NULL for short only) - int o_short; // Short option (no clustering!) - int o_val; // Value stored on a good parse (>0) - bool o_arg; // Option takes an argument if true +typedef struct nng_arg_spec { + const char *a_name; // Long style name (may be NULL for short only) + int a_short; // Short option (no clustering!) + int a_val; // Value stored on a good parse (>0) + bool a_arg; // Option takes an argument if true } nng_optspec; -int nng_opts_parse(int argc, char *const *argv, +#define NNG_ARG_END (-1) +#define NNG_ARG_INVAL (-2) +#define NNG_ARG_AMBIG (-3) +#define NNG_ARG_MISSING (-4) + +int nng_args_parse(int argc, char *const *argv, const nng_optspec *spec, int *val, char **arg, int *idx); ``` -The {{i:`nng_opts_parse`}} function is a intended to facilitate parsing +The {{i:`nng_args_parse`}} function is intended to facilitate parsing {{i:command-line arguments}}. This function exists largely to stand in for {{i:`getopt`}} from POSIX systems, -but it is available everywhere that _NNG_ is, and it includes -some capabilities missing from `getopt`. +but it is available on all platforms, and it includes some capabilities missing from `getopt`. The function parses arguments from `main`{{footnote: Parsing argument strings from other sources can be done as well, @@ -34,7 +42,7 @@ although usually then _idx_ will be initialized to zero.}} starting at the index referenced by _idx_. (New invocations typically set the value pointed to by _idx_ to 1.) -Options are parsed as specified by _spec_ (see [Option Specification](#option-specification).) +Options are parsed as specified by _spec_ (see [Argument Specification](#argument-specification).) The value of the parsed option will be stored at the address indicated by _val_, and the value of _idx_ will be incremented to reflect the next option to parse. @@ -52,23 +60,23 @@ returned. This function may return the following errors: -- [`NNG_EAMBIGUOUS`]: Parsed option matches more than one specification. -- [`NNG_ENOARG`]: Option requires an argument, but one is not present. -- [`NNG_EINVAL`]: An invalid (unknown) argument is present. +- [`NNG_ARG_AMBIGU`]: Parsed option matches more than one specification. +- [`NNG_ARG_MISSING`]: Option requires an argument, but one is not present. +- [`NNG_ARG_INVAL`]: An invalid (unknown) argument is present in _argv_. ### Option Specification -The calling program must first create an array of {{i:`nng_optspec`}} structures +The calling program must first create an array of {{i:`nng_arg_spec`}} structures describing the options to be supported. This structure has the following members: -- `o_name`: +- `a_name`: The long style name for the option, such as "verbose". This will be parsed as a [long option](#long-options) on the command line when it is prefixed with two dashes. It may be `NULL` if only a [short option](#short-options) is to be supported. -- `o_short`: +- `a_short`: This is a single letter (at present only ASCII letters are supported). These options appear as just a single letter, and are prefixed with a single dash on the command line. @@ -81,10 +89,10 @@ This structure has the following members: This value is assigned by the application program, and must be non-zero for a valid option. If this is zero, then it indicates the end of the specifications, and the rest of this structure is ignored. - The value will be returned to the caller in _val_ by `nng_opts_parse` when + The value will be returned to the caller in _val_ by `nng_args_parse` when this option is parsed from the command line. -- `o_arg`: +- `a_arg`: This value should be set to `true` if the option should take an argument. @@ -112,7 +120,7 @@ same element of _argv_, or may appear in the next _argv_ element. ### Prefix Matching When using long options, the parser will match if it is equal to a prefix -of the `o_name` member of a option specification, provided that it do so +of the `a_name` member of a option specification, provided that it do so unambiguously (meaning it must not match any other option specification.) ## Example @@ -124,26 +132,26 @@ The following program fragment demonstrates this function. char *logfile; // options to be set bool verbose; - static nng_optspec specs[] = { + static nng_arg_spec specs[] = { { - .o_name = "logfile", - .o_short = 'D', - .o_val = OPT_LOGFILE, - .o_arg = true, + .a_name = "logfile", + .a_short = 'D', + .a_val = OPT_LOGFILE, + .a_arg = true, }, { - .o_name = "verbose", - .o_short = 'V', - .o_val = OPT_VERBOSE, - .o_arg = false, + .a_name = "verbose", + .a_short = 'V', + .a_val = OPT_VERBOSE, + .a_arg = false, }, { - .o_val = 0; // Terminate array + .a_val = 0; // Terminate array } }; for (int idx = 1;;) { int rv, opt; char *arg; - rv = nng_opts_parse(argc, argv, specs, &opt, &arg, &idx); + rv = nng_args_parse(argc, argv, specs, &opt, &arg, &idx); if (rv != 0) { break; } @@ -156,8 +164,18 @@ The following program fragment demonstrates this function. break; } } - if (rv != -1) { - printf("Options error: %s\n", nng_strerror(rv)); + if (rv != NNG_ARG_END) { + switch (rv) { + case NNG_ARG_AMBIG: + printf("Options error: ambiguous option\n"); + break; + case NNG_ARG_MISSING: + printf("Options error: required option argument missing\n"); + break; + case NNG_ARG_INVAL: + printf("Options error: unknown option present\n"); + break; + } exit(1); } ``` diff --git a/docs/ref/api/errors.md b/docs/ref/api/errors.md index 6954b6587..2a4ccc930 100644 --- a/docs/ref/api/errors.md +++ b/docs/ref/api/errors.md @@ -65,8 +65,6 @@ future locale-specific strings may be presented instead. | `NNG_EWRITEONLY` | 25 | Write only resource. A read operation failed because the object only supports writes. | | `NNG_ECRYPTO` | 26 | Cryptographic error. Usually indicates an invalid key was used for TLS. | | `NNG_EPEERAUTH` | 27 | Peer could not be authenticated. | -| `NNG_ENOARG` | 28 | Option requires argument. A command-line option was supplied without an argument. Only used with [`nng_opts_parse`]. | -| `NNG_EAMBIGUOUS` | 29 | Ambiguous option. The command line option could not be unambiguously resolved. Only used with [`nng_opts_parse`]. | | `NNG_EBADTYPE` | 30 | Incorrect type. A type-specific function was used for an object of the wrong type. | | `NNG_ECONNSHUT` | 31 | Connection shutdown. The connection was shut down and cannot be used. | | `NNG_ESTOPPED` | 1000 | Operation stopped. The operation was stopped with [`nng_aio_stop`] or [`nng_aio_close`]. | diff --git a/docs/ref/migrate/nanomsg.md b/docs/ref/migrate/nanomsg.md index 78eed618c..7d71613c7 100644 --- a/docs/ref/migrate/nanomsg.md +++ b/docs/ref/migrate/nanomsg.md @@ -101,7 +101,7 @@ There are some exceptions. Be aware that the numeric values are _not_ the same. | -------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | `EINTR` | [`NNG_EINTR`] | | | `ENOMEM` | [`NNG_ENOMEM`] | | -| `EINVAL` | [`NNG_EINVAL`], [`NNG_EADDRINVAL`], [`NNG_EBADTYPE`], [`NNG_EAMBIGUOUS`] | NNG discrimates between different types of errors. | +| `EINVAL` | [`NNG_EINVAL`], [`NNG_EADDRINVAL`], [`NNG_EBADTYPE`] | NNG discrimates between different types of errors. | | `EBUSY` | [`NNG_EBUSY`] | | | `ETIMEDOUT` | [`NNG_ETIMEDOUT`] | | | `ECONNREFUSED` | [`NNG_ECONNREFUSED`] | | diff --git a/docs/ref/migrate/nng1.md b/docs/ref/migrate/nng1.md index cfb40a903..c203b790f 100644 --- a/docs/ref/migrate/nng1.md +++ b/docs/ref/migrate/nng1.md @@ -88,7 +88,7 @@ suboptimal in terms of performance. Modern code should use one of [`nng_sendmsg`], [`nng_recvmsg`], [`nng_socket_send`], or [`nng_socket_recv`] to get the maximum performance benefit. Working directly with [`nng_msg`] structures gives more control, reduces copies, and reduces allocation activity. -## New AIO Error Code NNG_ESTOPPED +## Error Code Changes When an operation fails with [`NNG_ESTOPPED`], it means that the associated [`nni_aio`] object has been permanently stopped and must not be reused. Applications must watch for this error code, and @@ -96,6 +96,8 @@ not resubmit an operation that returns it. This is particularly important for ca resubmit operations. Failure to observe this rule will lead to an infinite loop as any further operations on the object will fail immediately with `NNG_ESTOPPED`. +The error codes `NNG_EAMBIGUOUS` and `NNG_ENOARG` have been removed. + ## AIO Provider API changes The API used for providers for asynchronous I/O operations has changed slightly. @@ -365,6 +367,12 @@ and is presently only supported for IPC when Named Pipes are used. Planned future changes to switch to UNIX domain sockets may eliminate support for security descriptors altogether in NNG. +## Command Line Argument Parser Changes + +The supplemental function `nng_opts_parse` and supporting definitions have moved. +This functionality is now supplied by a header only library, available in `nng/args.h`. +See [`nng_args_parse`] for more information. + ## ZeroTier Support Removed The Layer 2 special ZeroTier transport has been removed. diff --git a/docs/ref/xref.md b/docs/ref/xref.md index 4345e2ea2..85c9f2f6f 100644 --- a/docs/ref/xref.md +++ b/docs/ref/xref.md @@ -193,7 +193,7 @@ [`nng_dialer_get_tls`]: /TODO.md [`nng_listener_set_tls`]: /TODO.md [`nng_listener_get_tls`]: /TODO.md -[`nng_opts_parse`]: /api/cmd_opts.md#parse-command-line-options +[`nng_args_parse`]: /api/args.md#parse-command-line-arguments [`nng_aio_finish`]: /TODO.md [`nng_aio_reset`]: /TODO.md [`nng_aio_start`]: /TODO.md @@ -272,8 +272,6 @@ [`NNG_EWRITEONLY`]: /api/errors.md#NNG_EWRITEONLY [`NNG_ECRYPTO`]: /api/errors.md#NNG_ECRYPTO [`NNG_EPEERAUTH`]: /api/errors.md#NNG_EPEERAUTH -[`NNG_ENOARG`]: /api/errors.md#NNG_ENOARG -[`NNG_EAMBIGUOUS`]: /api/errors.md#NNG_EAMBIGUOUS [`NNG_EBADTYPE`]: /api/errors.md#NNG_EBADTYPE [`NNG_ECONNSHUT`]: /api/errors.md#NNG_ECONNSHUT [`NNG_EINTERNAL`]: /api/errors.md#NNG_EINTERNAL diff --git a/include/nng/args.h b/include/nng/args.h new file mode 100644 index 000000000..faaa98b2f --- /dev/null +++ b/include/nng/args.h @@ -0,0 +1,163 @@ +// +// Copyright 2025 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. +// + +// This is a relatively simple "command line options parsing" library, used to +// parse command line options. We would use getopt(3), but there are +// two problems with getopt(3). First, it isn't available on all +// platforms (especially Win32), and second, it doesn't support long +// options. We *exclusively* support long options. POSIX style +// short option clustering is *NOT* supported. +// +// This is a header library, and it does not depend on anything else in NNG. +// This is by design, please do not add dependencies beyond what is available +// in fairly minimal standard C99 or C11. +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// This is a relatively simple "options parsing" library, used to +// parse command line options. We would use getopt(3), but there are +// two problems with getopt(3). First, it isn't available on all +// platforms (especially Win32), and second, it doesn't support long +// options. We *exclusively* support long options. POSIX style +// short option clustering is *NOT* supported. + +struct nng_arg_spec { + const char *a_name; // Long style name (may be NULL for short only) + int a_short; // Short option (no clustering!) + int a_val; // Value stored on a good parse (>0) + bool a_arg; // Option takes an argument if true +}; + +typedef struct nng_arg_spec nng_arg_spec; + +#define NNG_ARG_END (-1) // no more arguments (not an error) +#define NNG_ARG_INVAL (-2) // an invalid argument/option was given in argv +#define NNG_ARG_AMBIG (-3) // an arg in argv resolves to more than one spec +#define NNG_ARG_MISSING (-4) // a required option argument is missing + +// Call with *optidx set to 1 to start parsing for a standard program, or with +// 0 if parsing arguments without the executable in argv[0]. +// +// The val will store the value of the matched "o_val", optarg will be +// set to match the option string, and optidx will be increment appropriately. +// Returns -1 when the end of options is reached, 0 on success, or +// NNG_EINVAL if the option parse is invalid for any reason. +int +nng_args_parse(int argc, char *const *argv, const nng_arg_spec *specs, + int *val, char **optarg, int *optidx) +{ + const nng_arg_spec *spec; + 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; + spec = NULL; + + for (int x = 0; specs[x].a_val != 0; x++) { + + if (shortopt) { + if (arg[0] == specs[x].a_short) { + matches = 1; + spec = &specs[x]; + break; + } + continue; + } + + if ((specs[x].a_name == NULL) || + (strncmp(arg, specs[x].a_name, l) != 0)) { + continue; + } + matches++; + spec = &specs[x]; + + if (strlen(specs[x].a_name) == l) { + // Perfect match. + matches = 1; + break; + } + } + + switch (matches) { + case 1: + // Exact match + break; + case 0: + // No such option + return (NNG_ARG_INVAL); + break; + default: + // Ambiguous (not match) + return (NNG_ARG_AMBIG); + break; + } + + if (!spec->a_arg) { + // No option clustering for short options yet. + if (arg[l] != '\0') { + return (NNG_ARG_INVAL); + } + *val = spec->a_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_ARG_MISSING); + } + *optarg = argv[i]; + } + *optidx = ++i; + *val = spec->a_val; + + return (0); +} diff --git a/include/nng/nng.h b/include/nng/nng.h index 980e527aa..5a9f5dbc7 100644 --- a/include/nng/nng.h +++ b/include/nng/nng.h @@ -1059,8 +1059,6 @@ enum nng_errno_enum { NNG_EWRITEONLY = 25, NNG_ECRYPTO = 26, NNG_EPEERAUTH = 27, - NNG_ENOARG = 28, - NNG_EAMBIGUOUS = 29, NNG_EBADTYPE = 30, NNG_ECONNSHUT = 31, NNG_ESTOPPED = 999, diff --git a/include/nng/supplemental/util/options.h b/include/nng/supplemental/util/options.h deleted file mode 100644 index 6d0a3c1a6..000000000 --- a/include/nng/supplemental/util/options.h +++ /dev/null @@ -1,50 +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. -// - -#ifndef NNG_SUPPLEMENTAL_UTIL_OPTIONS_H -#define NNG_SUPPLEMENTAL_UTIL_OPTIONS_H - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// This is a relatively simple "options parsing" library, used to -// parse command line options. We would use getopt(3), but there are -// two problems with getopt(3). First, it isn't available on all -// platforms (especially Win32), and second, it doesn't support long -// options. We *exclusively* support long options. POSIX style -// short option clustering is *NOT* supported. - -struct nng_optspec { - const char *o_name; // Long style name (may be NULL for short only) - int o_short; // Short option (no clustering!) - int o_val; // Value stored on a good parse (>0) - bool o_arg; // Option takes an argument if true -}; - -typedef struct nng_optspec nng_optspec; - -// Call with *optidx set to 1 to start parsing for a standard program. -// The val will store the value of the matched "o_val", optarg will be -// set to match the option string, and optidx will be increment appropriately. -// Returns -1 when the end of options is reached, 0 on success, or -// NNG_EINVAL if the option parse is invalid for any reason. -NNG_DECL int nng_opts_parse(int argc, char *const *argv, - const nng_optspec *opts, int *val, char **optarg, int *optidx); - -#ifdef __cplusplus -} -#endif - -#endif // NNG_SUPPLEMENTAL_UTIL_OPTIONS_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b49048faa..1bdd4b7a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2024 Staysail Systems, Inc. +# Copyright 2025 Staysail Systems, Inc. # Copyright 2018 Capitar IT Group BV # # This software is supplied under the terms of the MIT License, a @@ -9,6 +9,7 @@ # nng_sources(nng.c nng_legacy.c) +nng_headers(nng/args.h) nng_headers(nng/nng.h) target_include_directories(nng PRIVATE ${PROJECT_SOURCE_DIR}/src) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9f5b4a957..a247ed897 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -81,6 +81,7 @@ nng_sources( ) nng_test(aio_test) +nng_test(args_test) nng_test(buf_size_test) nng_test(errors_test) nng_test(id_test) diff --git a/src/supplemental/util/options_test.c b/src/core/args_test.c similarity index 72% rename from src/supplemental/util/options_test.c rename to src/core/args_test.c index 036f29403..5139fece7 100644 --- a/src/supplemental/util/options_test.c +++ b/src/core/args_test.c @@ -8,12 +8,11 @@ // found online at https://opensource.org/licenses/MIT. // -#include "nng/nng.h" +#include +#include #include -#include - -static nng_optspec case1[] = { +static nng_arg_spec case1[] = { // clang-format off { "flag", 'f', 1, false }, { "longflag", 0, 2, false }, @@ -37,15 +36,15 @@ test_simple_options(void) av[2] = "-v"; av[3] = "123"; av[4] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); + NUTS_PASS(nng_args_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_PASS(nng_args_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(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 4); NUTS_MATCH(av[opti], "456"); } @@ -64,15 +63,15 @@ test_long_options(void) av[2] = "--value"; av[3] = "123"; av[4] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); + NUTS_PASS(nng_args_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_PASS(nng_args_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(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 4); NUTS_MATCH(av[opti], "456"); } @@ -89,11 +88,11 @@ test_attached_short(void) av[0] = "program"; av[1] = "-v123"; av[2] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); + NUTS_PASS(nng_args_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(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 2); NUTS_MATCH(av[opti], "456"); } @@ -110,11 +109,11 @@ test_attached_long_equals(void) av[0] = "program"; av[1] = "--value=123"; av[2] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); + NUTS_PASS(nng_args_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(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 2); NUTS_MATCH(av[opti], "456"); } @@ -131,11 +130,11 @@ test_attached_long_colon(void) av[0] = "program"; av[1] = "--value:123"; av[2] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); + NUTS_PASS(nng_args_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(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 2); NUTS_MATCH(av[opti], "456"); } @@ -152,7 +151,7 @@ test_negative_bad_short(void) av[0] = "program"; av[1] = "-Z"; av[2] = "456"; - NUTS_FAIL(nng_opts_parse(ac, av, case1, &v, &a, &opti), NNG_EINVAL); + NUTS_FAIL(nng_args_parse(ac, av, case1, &v, &a, &opti), NNG_ARG_INVAL); NUTS_TRUE(opti == 1); } @@ -168,7 +167,7 @@ test_negative_bad_long(void) av[0] = "program"; av[1] = "--something"; av[2] = "456"; - NUTS_FAIL(nng_opts_parse(ac, av, case1, &v, &a, &opti), NNG_EINVAL); + NUTS_FAIL(nng_args_parse(ac, av, case1, &v, &a, &opti), NNG_ARG_INVAL); NUTS_TRUE(opti == 1); } @@ -186,10 +185,10 @@ test_option_separator_flag(void) av[2] = "-"; av[3] = "-v"; av[4] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); + NUTS_PASS(nng_args_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(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 3); } @@ -203,7 +202,7 @@ test_no_options(void) char *a = NULL; av[0] = "program"; - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); + NUTS_TRUE(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); } void @@ -217,7 +216,7 @@ test_arg_only(void) av[0] = "program"; av[1] = "123"; - NUTS_TRUE(nng_opts_parse(ac, av, case1, &v, &a, &opti) == -1); + NUTS_TRUE(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 1); } @@ -237,25 +236,25 @@ test_mixed_long_short(void) av[4] = "-b"; av[5] = "-vxyz"; av[6] = "456"; - NUTS_PASS(nng_opts_parse(ac, av, case1, &v, &a, &opti)); + NUTS_PASS(nng_args_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_PASS(nng_args_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_PASS(nng_args_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_PASS(nng_args_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_PASS(nng_args_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(nng_args_parse(ac, av, case1, &v, &a, &opti) == -1); NUTS_TRUE(opti == 6); } @@ -268,7 +267,7 @@ test_ambiguous(void) int v; char *a = NULL; - nng_optspec spec[] = { + nng_arg_spec spec[] = { { "flag", 'f', 1, false }, { "fluid", 0, 2, false }, { NULL, 0, 0, false }, @@ -276,7 +275,7 @@ test_ambiguous(void) av[0] = "program"; av[1] = "--fl"; - NUTS_FAIL(nng_opts_parse(ac, av, spec, &v, &a, &opti), NNG_EAMBIGUOUS); + NUTS_FAIL(nng_args_parse(ac, av, spec, &v, &a, &opti), NNG_ARG_AMBIG); } void @@ -288,18 +287,20 @@ test_missing_arg(void) int v; char *a = NULL; - nng_optspec spec[] = { + nng_arg_spec 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); + NUTS_FAIL( + nng_args_parse(ac, av, spec, &v, &a, &opti), NNG_ARG_MISSING); av[0] = "program"; av[1] = "-f"; opti = 1; - NUTS_FAIL(nng_opts_parse(ac, av, spec, &v, &a, &opti), NNG_ENOARG); + NUTS_FAIL( + nng_args_parse(ac, av, spec, &v, &a, &opti), NNG_ARG_MISSING); } void @@ -311,7 +312,7 @@ test_no_clustering(void) int v; char *a = NULL; - nng_optspec spec[] = { + nng_arg_spec spec[] = { { "flag", 'f', 1, false }, { "verbose", 'v', 2, false }, { NULL, 0, 0, false }, @@ -319,7 +320,7 @@ test_no_clustering(void) av[0] = "program"; av[1] = "-fv"; - NUTS_FAIL(nng_opts_parse(ac, av, spec, &v, &a, &opti), NNG_EINVAL); + NUTS_FAIL(nng_args_parse(ac, av, spec, &v, &a, &opti), NNG_ARG_INVAL); } NUTS_TESTS = { diff --git a/src/nng.c b/src/nng.c index 345f47d90..002f29f8a 100644 --- a/src/nng.c +++ b/src/nng.c @@ -1266,8 +1266,6 @@ static const struct { { NNG_EWRITEONLY, "Write only resource" }, { NNG_ECRYPTO, "Cryptographic error" }, { NNG_EPEERAUTH, "Peer could not be authenticated" }, - { NNG_ENOARG, "Option requires argument" }, - { NNG_EAMBIGUOUS, "Ambiguous option" }, { NNG_EBADTYPE, "Incorrect type" }, { NNG_ECONNSHUT, "Connection shutdown" }, { NNG_ESTOPPED, "Operation stopped"}, diff --git a/src/sp/protocol/pipeline0/pull_test.c b/src/sp/protocol/pipeline0/pull_test.c index 8ed9cc0ef..321340826 100644 --- a/src/sp/protocol/pipeline0/pull_test.c +++ b/src/sp/protocol/pipeline0/pull_test.c @@ -243,10 +243,10 @@ test_pull_recv_abort(void) nng_aio_set_timeout(aio, 1000); nng_socket_recv(s, aio); - nng_aio_abort(aio, NNG_EAMBIGUOUS); + nng_aio_abort(aio, NNG_ESTATE); nng_aio_wait(aio); - NUTS_FAIL(nng_aio_result(aio), NNG_EAMBIGUOUS); + NUTS_FAIL(nng_aio_result(aio), NNG_ESTATE); NUTS_CLOSE(s); nng_aio_free(aio); } diff --git a/src/sp/protocol/pubsub0/sub_test.c b/src/sp/protocol/pubsub0/sub_test.c index 13fc07bf5..7f4e44809 100644 --- a/src/sp/protocol/pubsub0/sub_test.c +++ b/src/sp/protocol/pubsub0/sub_test.c @@ -301,10 +301,10 @@ test_sub_ctx_recv_abort(void) nng_aio_set_timeout(aio, 1000); nng_ctx_recv(ctx, aio); - nng_aio_abort(aio, NNG_EAMBIGUOUS); + nng_aio_abort(aio, NNG_EINTERNAL); nng_aio_wait(aio); - NUTS_FAIL(nng_aio_result(aio), NNG_EAMBIGUOUS); + NUTS_FAIL(nng_aio_result(aio), NNG_EINTERNAL); NUTS_CLOSE(sub); nng_aio_free(aio); } diff --git a/src/supplemental/CMakeLists.txt b/src/supplemental/CMakeLists.txt index 9a54beeaf..fe808c8d8 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 d75413630..000000000 --- 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 961e0bb27..000000000 --- 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/tools/nngcat/nngcat.c b/src/tools/nngcat/nngcat.c index dc998cf39..26b7c6393 100644 --- a/src/tools/nngcat/nngcat.c +++ b/src/tools/nngcat/nngcat.c @@ -1,5 +1,5 @@ // -// Copyright 2024 Staysail Systems, Inc. +// Copyright 2025 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // Copyright 2020 Lager Data, Inc. // @@ -17,8 +17,8 @@ #include #include +#include #include -#include // Globals. We need this to avoid passing around everything. int format = 0; @@ -91,105 +91,105 @@ enum options { OPT_RECVMAXSZ, }; -static nng_optspec opts[] = { - { .o_name = "help", .o_short = 'h', .o_val = OPT_HELP }, - { .o_name = "verbose", .o_short = 'v', .o_val = OPT_VERBOSE }, - { .o_name = "silent", .o_short = 'q', .o_val = OPT_SILENT }, - { .o_name = "req0", .o_val = OPT_REQ0 }, - { .o_name = "rep0", .o_val = OPT_REP0 }, - { .o_name = "push0", .o_val = OPT_PUSH0 }, - { .o_name = "pull0", .o_val = OPT_PULL0 }, - { .o_name = "pub0", .o_val = OPT_PUB0 }, - { .o_name = "sub", .o_val = OPT_SUB0 }, // explicit for alias - { .o_name = "sub0", .o_val = OPT_SUB0 }, - { .o_name = "surveyor0", .o_val = OPT_SURVEY0 }, - { .o_name = "respondent0", .o_val = OPT_RESPOND0 }, - { .o_name = "pair", .o_val = OPT_PAIR }, - { .o_name = "pair0", .o_val = OPT_PAIR0 }, - { .o_name = "pair1", .o_val = OPT_PAIR1 }, - { .o_name = "bus0", .o_val = OPT_BUS0 }, - { .o_name = "dial", .o_val = OPT_DIAL, .o_arg = true }, - { .o_name = "listen", .o_val = OPT_LISTEN, .o_arg = true }, - { .o_name = "data", .o_short = 'D', .o_val = OPT_DATA, .o_arg = true }, - { .o_name = "file", .o_short = 'F', .o_val = OPT_FILE, .o_arg = true }, - { .o_name = "subscribe", .o_val = OPT_SUBSCRIBE, .o_arg = true }, - { .o_name = "format", .o_val = OPT_FORMAT, .o_arg = true }, - { .o_name = "ascii", .o_short = 'A', .o_val = OPT_ASCII }, - { .o_name = "quoted", .o_short = 'Q', .o_val = OPT_QUOTED }, - { .o_name = "raw", .o_val = OPT_RAW }, - { .o_name = "hex", .o_val = OPT_HEX }, - { .o_name = "compat", .o_val = OPT_COMPAT }, - { .o_name = "async", .o_val = OPT_ASYNC }, - { .o_name = "msgpack", .o_val = OPT_MSGPACK }, +static nng_arg_spec opts[] = { + { .a_name = "help", .a_short = 'h', .a_val = OPT_HELP }, + { .a_name = "verbose", .a_short = 'v', .a_val = OPT_VERBOSE }, + { .a_name = "silent", .a_short = 'q', .a_val = OPT_SILENT }, + { .a_name = "req0", .a_val = OPT_REQ0 }, + { .a_name = "rep0", .a_val = OPT_REP0 }, + { .a_name = "push0", .a_val = OPT_PUSH0 }, + { .a_name = "pull0", .a_val = OPT_PULL0 }, + { .a_name = "pub0", .a_val = OPT_PUB0 }, + { .a_name = "sub", .a_val = OPT_SUB0 }, // explicit for alias + { .a_name = "sub0", .a_val = OPT_SUB0 }, + { .a_name = "surveyor0", .a_val = OPT_SURVEY0 }, + { .a_name = "respondent0", .a_val = OPT_RESPOND0 }, + { .a_name = "pair", .a_val = OPT_PAIR }, + { .a_name = "pair0", .a_val = OPT_PAIR0 }, + { .a_name = "pair1", .a_val = OPT_PAIR1 }, + { .a_name = "bus0", .a_val = OPT_BUS0 }, + { .a_name = "dial", .a_val = OPT_DIAL, .a_arg = true }, + { .a_name = "listen", .a_val = OPT_LISTEN, .a_arg = true }, + { .a_name = "data", .a_short = 'D', .a_val = OPT_DATA, .a_arg = true }, + { .a_name = "file", .a_short = 'F', .a_val = OPT_FILE, .a_arg = true }, + { .a_name = "subscribe", .a_val = OPT_SUBSCRIBE, .a_arg = true }, + { .a_name = "format", .a_val = OPT_FORMAT, .a_arg = true }, + { .a_name = "ascii", .a_short = 'A', .a_val = OPT_ASCII }, + { .a_name = "quoted", .a_short = 'Q', .a_val = OPT_QUOTED }, + { .a_name = "raw", .a_val = OPT_RAW }, + { .a_name = "hex", .a_val = OPT_HEX }, + { .a_name = "compat", .a_val = OPT_COMPAT }, + { .a_name = "async", .a_val = OPT_ASYNC }, + { .a_name = "msgpack", .a_val = OPT_MSGPACK }, { - .o_name = "recv-maxsz", - .o_short = 'Z', - .o_val = OPT_RECVMAXSZ, - .o_arg = true, + .a_name = "recv-maxsz", + .a_short = 'Z', + .a_val = OPT_RECVMAXSZ, + .a_arg = true, }, { - .o_name = "count", - .o_short = 'C', - .o_val = OPT_COUNT, - .o_arg = true, + .a_name = "count", + .a_short = 'C', + .a_val = OPT_COUNT, + .a_arg = true, }, { - .o_name = "delay", - .o_short = 'd', - .o_val = OPT_DELAY, - .o_arg = true, + .a_name = "delay", + .a_short = 'd', + .a_val = OPT_DELAY, + .a_arg = true, }, { - .o_name = "interval", - .o_short = 'i', - .o_val = OPT_INTERVAL, - .o_arg = true, + .a_name = "interval", + .a_short = 'i', + .a_val = OPT_INTERVAL, + .a_arg = true, }, - { .o_name = "recv-timeout", .o_val = OPT_RCV_TIMEO, .o_arg = true }, - { .o_name = "send-timeout", .o_val = OPT_SND_TIMEO, .o_arg = true }, - { .o_name = "socket-name", .o_val = OPT_SOCK_NAME, .o_arg = true }, + { .a_name = "recv-timeout", .a_val = OPT_RCV_TIMEO, .a_arg = true }, + { .a_name = "send-timeout", .a_val = OPT_SND_TIMEO, .a_arg = true }, + { .a_name = "socket-name", .a_val = OPT_SOCK_NAME, .a_arg = true }, // Legacy compatibility with nanocat. - { .o_name = "bind", .o_val = OPT_LISTEN, .o_arg = true }, - { .o_name = "connect", .o_val = OPT_DIAL, .o_arg = true }, + { .a_name = "bind", .a_val = OPT_LISTEN, .a_arg = true }, + { .a_name = "connect", .a_val = OPT_DIAL, .a_arg = true }, { - .o_name = "bind-ipc", - .o_short = 'X', - .o_val = OPT_LISTEN_IPC, - .o_arg = true, + .a_name = "bind-ipc", + .a_short = 'X', + .a_val = OPT_LISTEN_IPC, + .a_arg = true, }, { - .o_name = "connect-ipc", - .o_short = 'x', - .o_val = OPT_DIAL_IPC, - .o_arg = true, + .a_name = "connect-ipc", + .a_short = 'x', + .a_val = OPT_DIAL_IPC, + .a_arg = true, }, { - .o_name = "bind-local", - .o_short = 'L', - .o_val = OPT_LISTEN_LOCAL, - .o_arg = true, + .a_name = "bind-local", + .a_short = 'L', + .a_val = OPT_LISTEN_LOCAL, + .a_arg = true, }, { - .o_name = "connect-local", - .o_short = 'l', - .o_val = OPT_DIAL_LOCAL, - .o_arg = true, + .a_name = "connect-local", + .a_short = 'l', + .a_val = OPT_DIAL_LOCAL, + .a_arg = true, }, - { .o_name = "insecure", .o_short = 'k', .o_val = OPT_INSECURE }, - { .o_name = "cacert", .o_val = OPT_CACERT, .o_arg = true }, - { .o_name = "key", .o_val = OPT_KEYFILE, .o_arg = true }, + { .a_name = "insecure", .a_short = 'k', .a_val = OPT_INSECURE }, + { .a_name = "cacert", .a_val = OPT_CACERT, .a_arg = true }, + { .a_name = "key", .a_val = OPT_KEYFILE, .a_arg = true }, { - .o_name = "cert", - .o_short = 'E', - .o_val = OPT_CERTFILE, - .o_arg = true, + .a_name = "cert", + .a_short = 'E', + .a_val = OPT_CERTFILE, + .a_arg = true, }, - { .o_name = "version", .o_short = 'V', .o_val = OPT_VERSION }, + { .a_name = "version", .a_short = 'V', .a_val = OPT_VERSION }, // Sentinel. - { .o_name = NULL, .o_val = 0 }, + { .a_name = NULL, .a_val = 0 }, }; static void @@ -705,7 +705,7 @@ main(int ac, char **av) nng_init(NULL); atexit(nng_fini); - while ((rv = nng_opts_parse(ac, av, opts, &val, &arg, &idx)) == 0) { + while ((rv = nng_args_parse(ac, av, opts, &val, &arg, &idx)) == 0) { switch (val) { case OPT_HELP: help(); @@ -860,13 +860,13 @@ main(int ac, char **av) } } switch (rv) { - case NNG_EINVAL: + case NNG_ARG_INVAL: fatal("Option %s is invalid.", av[idx]); break; - case NNG_EAMBIGUOUS: + case NNG_ARG_AMBIG: fatal("Option %s is ambiguous (specify in full).", av[idx]); break; - case NNG_ENOARG: + case NNG_ARG_MISSING: fatal("Option %s requires argument.", av[idx]); break; default: diff --git a/src/tools/perf/perf.c b/src/tools/perf/perf.c index 5ce99c049..e83c89ffd 100644 --- a/src/tools/perf/perf.c +++ b/src/tools/perf/perf.c @@ -1,5 +1,5 @@ // -// Copyright 2024 Staysail Systems, Inc. +// Copyright 2025 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a @@ -15,8 +15,8 @@ #include #include +#include #include -#include static void die(const char *, ...); static int @@ -80,15 +80,15 @@ enum options { }; // These are not universally supported by the variants yet. -static nng_optspec opts[] = { - { .o_name = "pair1", .o_val = OPT_PAIR1 }, - { .o_name = "pair0", .o_val = OPT_PAIR0 }, - { .o_name = "reqrep0", .o_val = OPT_REQREP0 }, - { .o_name = "bus0", .o_val = OPT_BUS0 }, - { .o_name = "pubsub0", .o_val = OPT_PUBSUB0 }, - { .o_name = "pipeline0", .o_val = OPT_PIPELINE0 }, - { .o_name = "url", .o_val = OPT_URL, .o_arg = true }, - { .o_name = NULL, .o_val = 0 }, +static nng_arg_spec opts[] = { + { .a_name = "pair1", .a_val = OPT_PAIR1 }, + { .a_name = "pair0", .a_val = OPT_PAIR0 }, + { .a_name = "reqrep0", .a_val = OPT_REQREP0 }, + { .a_name = "bus0", .a_val = OPT_BUS0 }, + { .a_name = "pubsub0", .a_val = OPT_PUBSUB0 }, + { .a_name = "pipeline0", .a_val = OPT_PIPELINE0 }, + { .a_name = "url", .a_val = OPT_URL, .a_arg = true }, + { .a_name = NULL, .a_val = 0 }, }; static void latency_client(const char *, size_t, int); @@ -319,7 +319,7 @@ do_inproc_lat(int argc, char **argv) addr = "inproc://latency_test"; optidx = 0; - while ((rv = nng_opts_parse(argc, argv, opts, &val, &arg, &optidx)) == + while ((rv = nng_args_parse(argc, argv, opts, &val, &arg, &optidx)) == 0) { switch (val) { case OPT_REQREP0: @@ -381,7 +381,7 @@ do_inproc_thr(int argc, char **argv) char *addr = "inproc://throughput-test"; optidx = 0; - while ((rv = nng_opts_parse(argc, argv, opts, &val, &arg, &optidx)) == + while ((rv = nng_args_parse(argc, argv, opts, &val, &arg, &optidx)) == 0) { switch (val) { #if 0