diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/supplemental/util/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | src/supplemental/util/options.c | 124 | ||||
| -rw-r--r-- | src/supplemental/util/options.h | 48 | ||||
| -rw-r--r-- | src/supplemental/util/platform.h | 6 |
4 files changed, 179 insertions, 7 deletions
diff --git a/src/supplemental/util/CMakeLists.txt b/src/supplemental/util/CMakeLists.txt index 443473d6..f94e2b45 100644 --- a/src/supplemental/util/CMakeLists.txt +++ b/src/supplemental/util/CMakeLists.txt @@ -8,8 +8,8 @@ # found online at https://opensource.org/licenses/MIT. # -set(SUPP_PLATFORM_SOURCES supplemental/util/platform.c) -set(SUPP_PLATFORM_HEADERS supplemental/util/platform.h) +set(SUPP_UTIL_SOURCES supplemental/util/options.c supplemental/util/platform.c) +set(SUPP_UTIL_HEADERS supplemental/util/options.h supplemental/util/platform.h) -set(NNG_SOURCES ${NNG_SOURCES} ${SUPP_PLATFORM_SOURCES} PARENT_SCOPE) -set(NNG_HEADERS ${NNG_HEADERS} ${SUPP_PLATFORM_HEADERS} PARENT_SCOPE) +set(NNG_SOURCES ${NNG_SOURCES} ${SUPP_UTIL_SOURCES} PARENT_SCOPE) +set(NNG_HEADERS ${NNG_HEADERS} ${SUPP_UTIL_HEADERS} PARENT_SCOPE) diff --git a/src/supplemental/util/options.c b/src/supplemental/util/options.c new file mode 100644 index 00000000..d8f78deb --- /dev/null +++ b/src/supplemental/util/options.c @@ -0,0 +1,124 @@ +// +// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2018 Capitar IT Group BV <info@capitar.com> +// +// 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 <stdlib.h> +#include <string.h> + +#include "core/nng_impl.h" +#include "supplemental/util/options.h" + +// Call with optidx set to 1 to start parsing. +int +nng_opts_parse(int argc, const char **argv, const nng_optspec *opts, int *val, + const char **optarg, int *optidx) +{ + const nng_optspec *opt; + int matches; + bool shortopt; + size_t l; + const char * arg = argv[*optidx]; + int i; + + if ((i = *optidx) >= argc) { + return (-1); + } + + 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_EINVAL); + 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_EINVAL); + } + *optarg = argv[i]; + } + *optidx = ++i; + *val = opt->o_val; + + return (0); +} diff --git a/src/supplemental/util/options.h b/src/supplemental/util/options.h new file mode 100644 index 00000000..02b3a9d4 --- /dev/null +++ b/src/supplemental/util/options.h @@ -0,0 +1,48 @@ +// +// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2018 Capitar IT Group BV <info@capitar.com> +// +// 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 <stdbool.h> + +#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, const char **argv, + const nng_optspec *opts, int *val, const char **optarg, int *optidx); + +#ifdef __cplusplus +} +#endif + +#endif // NNG_SUPPLEMENTAL_UTIL_OPTIONS_H
\ No newline at end of file diff --git a/src/supplemental/util/platform.h b/src/supplemental/util/platform.h index 1383fe15..fd287713 100644 --- a/src/supplemental/util/platform.h +++ b/src/supplemental/util/platform.h @@ -20,13 +20,13 @@ // APIs or Windows APIs, then by all means please feel free to simply // ignore this. +#include <stddef.h> +#include <stdint.h> + #ifdef __cplusplus extern "C" { #endif -#include <stddef.h> -#include <stdint.h> - // nng_time represents an absolute time since some arbitrary point in the // past, measured in milliseconds. The values are always positive. typedef uint64_t nng_time; |
