diff options
author | João Valverde <j@v6e.pt> | 2021-09-16 13:56:11 +0100 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2021-09-17 00:43:54 +0100 |
commit | 2deb1c95d9c59eebd29a2581d067100af6126233 (patch) | |
tree | a176e6971a039edf3ae653deb3edb03e4862d6a3 /wsutil | |
parent | 8df2a73594fbcc812f4ea22a72ab7a79bfb63dc3 (diff) |
Merge ws_getopt source files
No need to keep a separate ws_getopt_long.c file.
Diffstat (limited to 'wsutil')
-rw-r--r-- | wsutil/CMakeLists.txt | 1 | ||||
-rw-r--r-- | wsutil/ws_getopt.c | 147 | ||||
-rw-r--r-- | wsutil/ws_getopt.h | 2 | ||||
-rw-r--r-- | wsutil/ws_getopt_long.c | 174 |
4 files changed, 142 insertions, 182 deletions
diff --git a/wsutil/CMakeLists.txt b/wsutil/CMakeLists.txt index 29c5d78049..6c4cfadd04 100644 --- a/wsutil/CMakeLists.txt +++ b/wsutil/CMakeLists.txt @@ -130,7 +130,6 @@ set(WSUTIL_COMMON_FILES glib-compat.c ws_assert.c ws_getopt.c - ws_getopt_long.c ws_mempbrk.c ws_pipe.c wsgcrypt.c diff --git a/wsutil/ws_getopt.c b/wsutil/ws_getopt.c index 0b37bd8a48..c93f54fbe7 100644 --- a/wsutil/ws_getopt.c +++ b/wsutil/ws_getopt.c @@ -25,13 +25,12 @@ * ---------------------------------------------------------------------- */ -//#define _BSD_SOURCE -//#include <unistd.h> -#include <wchar.h> -#include <string.h> -#include <limits.h> +#include <stddef.h> #include <stdlib.h> +#include <limits.h> #include <stdio.h> +#include <string.h> +#include <wchar.h> #include <wsutil/ws_getopt.h> @@ -47,6 +46,16 @@ void __getopt_msg(const char *a, const char *b, const char *c, size_t l) putc('\n', f); } +static void permute(char *const *argv, int dest, int src) +{ + char **av = (char **)argv; + char *tmp = av[src]; + int i; + for (i=src; i>dest; i--) + av[i] = av[i-1]; + av[dest] = tmp; +} + int ws_getopt(int argc, char * const argv[], const char *optstring) { int i; @@ -123,3 +132,131 @@ int ws_getopt(int argc, char * const argv[], const char *optstring) } return c; } + +static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly); + +static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) +{ + int ret, skipped, resumed; + if (!ws_optind || ws_optreset) { + ws_optreset = 0; + ws_optpos = 0; + ws_optind = 1; + } + if (ws_optind >= argc || !argv[ws_optind]) return -1; + skipped = ws_optind; + if (optstring[0] != '+' && optstring[0] != '-') { + int i; + for (i=ws_optind; ; i++) { + if (i >= argc || !argv[i]) return -1; + if (argv[i][0] == '-' && argv[i][1]) break; + } + ws_optind = i; + } + resumed = ws_optind; + ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly); + if (resumed > skipped) { + int i, cnt = ws_optind-resumed; + for (i=0; i<cnt; i++) + permute(argv, skipped, ws_optind-1); + ws_optind = skipped + cnt; + } + return ret; +} + +static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) +{ + ws_optarg = 0; + if (longopts && argv[ws_optind][0] == '-' && + ((longonly && argv[ws_optind][1] && argv[ws_optind][1] != '-') || + (argv[ws_optind][1] == '-' && argv[ws_optind][2]))) + { + int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':'; + int i, cnt, match = -1; + char *arg = NULL, *opt, *start = argv[ws_optind]+1; + for (cnt=i=0; longopts[i].name; i++) { + const char *name = longopts[i].name; + opt = start; + if (*opt == '-') opt++; + while (*opt && *opt != '=' && *opt == *name) + name++, opt++; + if (*opt && *opt != '=') continue; + arg = opt; + match = i; + if (!*name) { + cnt = 1; + break; + } + cnt++; + } + if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) { + int l = arg-start; + for (i=0; optstring[i]; i++) { + int j; + for (j=0; j<l && start[j]==optstring[i+j]; j++); + if (j==l) { + cnt++; + break; + } + } + } + if (cnt==1) { + i = match; + opt = arg; + ws_optind++; + if (*opt == '=') { + if (!longopts[i].has_arg) { + ws_optopt = longopts[i].val; + if (colon || !ws_opterr) + return '?'; + __getopt_msg(argv[0], + ": option does not take an argument: ", + longopts[i].name, + strlen(longopts[i].name)); + return '?'; + } + ws_optarg = opt+1; + } else if (longopts[i].has_arg == required_argument) { + if (!(ws_optarg = argv[ws_optind])) { + ws_optopt = longopts[i].val; + if (colon) return ':'; + if (!ws_opterr) return '?'; + __getopt_msg(argv[0], + ": option requires an argument: ", + longopts[i].name, + strlen(longopts[i].name)); + return '?'; + } + ws_optind++; + } + if (idx) *idx = i; + if (longopts[i].flag) { + *longopts[i].flag = longopts[i].val; + return 0; + } + return longopts[i].val; + } + if (argv[ws_optind][1] == '-') { + ws_optopt = 0; + if (!colon && ws_opterr) + __getopt_msg(argv[0], cnt ? + ": option is ambiguous: " : + ": unrecognized option: ", + argv[ws_optind]+2, + strlen(argv[ws_optind]+2)); + ws_optind++; + return '?'; + } + } + return ws_getopt(argc, argv, optstring); +} + +int ws_getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) +{ + return __getopt_long(argc, argv, optstring, longopts, idx, 0); +} + +int ws_getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) +{ + return __getopt_long(argc, argv, optstring, longopts, idx, 1); +} diff --git a/wsutil/ws_getopt.h b/wsutil/ws_getopt.h index f0a5b89625..e0115a7df4 100644 --- a/wsutil/ws_getopt.h +++ b/wsutil/ws_getopt.h @@ -48,8 +48,6 @@ struct option { WS_DLL_PUBLIC int ws_getopt_long(int, char *const *, const char *, const struct option *, int *); WS_DLL_PUBLIC int ws_getopt_long_only(int, char *const *, const char *, const struct option *, int *); -WS_DLL_LOCAL void __getopt_msg(const char *a, const char *b, const char *c, size_t l); - #define no_argument 0 #define required_argument 1 #define optional_argument 2 diff --git a/wsutil/ws_getopt_long.c b/wsutil/ws_getopt_long.c deleted file mode 100644 index 07351e7eaf..0000000000 --- a/wsutil/ws_getopt_long.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * musl as a whole is licensed under the following standard MIT license: - * - * ---------------------------------------------------------------------- - * Copyright © 2005-2020 Rich Felker, et al. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * ---------------------------------------------------------------------- - */ - -//#define _GNU_SOURCE -#include <stddef.h> -#include <stdlib.h> -#include <limits.h> -#include <stdio.h> -#include <string.h> -#include <stdio.h> - -#include <wsutil/ws_getopt.h> - -static void permute(char *const *argv, int dest, int src) -{ - char **av = (char **)argv; - char *tmp = av[src]; - int i; - for (i=src; i>dest; i--) - av[i] = av[i-1]; - av[dest] = tmp; -} - -static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly); - -static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) -{ - int ret, skipped, resumed; - if (!ws_optind || ws_optreset) { - ws_optreset = 0; - ws_optpos = 0; - ws_optind = 1; - } - if (ws_optind >= argc || !argv[ws_optind]) return -1; - skipped = ws_optind; - if (optstring[0] != '+' && optstring[0] != '-') { - int i; - for (i=ws_optind; ; i++) { - if (i >= argc || !argv[i]) return -1; - if (argv[i][0] == '-' && argv[i][1]) break; - } - ws_optind = i; - } - resumed = ws_optind; - ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly); - if (resumed > skipped) { - int i, cnt = ws_optind-resumed; - for (i=0; i<cnt; i++) - permute(argv, skipped, ws_optind-1); - ws_optind = skipped + cnt; - } - return ret; -} - -static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly) -{ - ws_optarg = 0; - if (longopts && argv[ws_optind][0] == '-' && - ((longonly && argv[ws_optind][1] && argv[ws_optind][1] != '-') || - (argv[ws_optind][1] == '-' && argv[ws_optind][2]))) - { - int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':'; - int i, cnt, match = -1; - char *arg = NULL, *opt, *start = argv[ws_optind]+1; - for (cnt=i=0; longopts[i].name; i++) { - const char *name = longopts[i].name; - opt = start; - if (*opt == '-') opt++; - while (*opt && *opt != '=' && *opt == *name) - name++, opt++; - if (*opt && *opt != '=') continue; - arg = opt; - match = i; - if (!*name) { - cnt = 1; - break; - } - cnt++; - } - if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) { - int l = arg-start; - for (i=0; optstring[i]; i++) { - int j; - for (j=0; j<l && start[j]==optstring[i+j]; j++); - if (j==l) { - cnt++; - break; - } - } - } - if (cnt==1) { - i = match; - opt = arg; - ws_optind++; - if (*opt == '=') { - if (!longopts[i].has_arg) { - ws_optopt = longopts[i].val; - if (colon || !ws_opterr) - return '?'; - __getopt_msg(argv[0], - ": option does not take an argument: ", - longopts[i].name, - strlen(longopts[i].name)); - return '?'; - } - ws_optarg = opt+1; - } else if (longopts[i].has_arg == required_argument) { - if (!(ws_optarg = argv[ws_optind])) { - ws_optopt = longopts[i].val; - if (colon) return ':'; - if (!ws_opterr) return '?'; - __getopt_msg(argv[0], - ": option requires an argument: ", - longopts[i].name, - strlen(longopts[i].name)); - return '?'; - } - ws_optind++; - } - if (idx) *idx = i; - if (longopts[i].flag) { - *longopts[i].flag = longopts[i].val; - return 0; - } - return longopts[i].val; - } - if (argv[ws_optind][1] == '-') { - ws_optopt = 0; - if (!colon && ws_opterr) - __getopt_msg(argv[0], cnt ? - ": option is ambiguous: " : - ": unrecognized option: ", - argv[ws_optind]+2, - strlen(argv[ws_optind]+2)); - ws_optind++; - return '?'; - } - } - return ws_getopt(argc, argv, optstring); -} - -int ws_getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) -{ - return __getopt_long(argc, argv, optstring, longopts, idx, 0); -} - -int ws_getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx) -{ - return __getopt_long(argc, argv, optstring, longopts, idx, 1); -} |