From 0d47952611198ef6b1163f366dc03922d20b1475 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 09:42:04 +0200 Subject: Adding upstream version 7.94+git20230807.3be01efb1+dfsg. Signed-off-by: Daniel Baumann --- nbase/getopt.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 nbase/getopt.c (limited to 'nbase/getopt.c') diff --git a/nbase/getopt.c b/nbase/getopt.c new file mode 100644 index 0000000..f9aad9f --- /dev/null +++ b/nbase/getopt.c @@ -0,0 +1,304 @@ +/* + * my_getopt.c - my re-implementation of getopt. + * Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler + * + * 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. + */ + +/* $Id$ */ + +#include +#include +#include +#include +#include "getopt.h" + +#if HAVE_CONFIG_H +#include "nbase_config.h" +#else +#ifdef WIN32 +#include "nbase_winconfig.h" /* mainly for _CRT_SECURE_NO_DEPRECATE */ +#endif /* WIN32 */ +#endif /* HAVE_CONFIG_H */ + +int optind=1, opterr=1, optopt=0; +char *optarg=0; + +/* reset argument parser to start-up values */ +int getopt_reset(void) +{ + optind = 1; + opterr = 1; + optopt = 0; + optarg = 0; + return 0; +} + + +/* this is the plain old UNIX getopt, with GNU-style extensions. */ +/* if you're porting some piece of UNIX software, this is all you need. */ +/* this supports GNU-style permutation and optional arguments */ + +static int _getopt(int argc, char * argv[], const char *opts) +{ + static int charind=0; + const char *s; + char mode, colon_mode; + int off = 0, opt = -1; + + if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+'; + else { + if((colon_mode = *opts) == ':') off ++; + if(((mode = opts[off]) == '+') || (mode == '-')) { + off++; + if((colon_mode != ':') && ((colon_mode = opts[off]) == ':')) + off ++; + } + } + optarg = 0; + if(charind) { + optopt = argv[optind][charind]; + for(s=opts+off; *s; s++) if(optopt == *s) { + charind++; + if((*(++s) == ':') || ((optopt == 'W') && (*s == ';'))) { + if(argv[optind][charind]) { + optarg = &(argv[optind++][charind]); + charind = 0; + } else if(*(++s) != ':') { + charind = 0; + if(++optind >= argc) { + if(opterr) fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], optopt); + opt = (colon_mode == ':') ? ':' : '?'; + goto my_getopt_ok; + } + optarg = argv[optind++]; + } + } + opt = optopt; + goto my_getopt_ok; + } + if(opterr) fprintf(stderr, + "%s: illegal option -- %c\n", + argv[0], optopt); + opt = '?'; + if(argv[optind][++charind] == '\0') { + optind++; + charind = 0; + } + my_getopt_ok: + if(charind && ! argv[optind][charind]) { + optind++; + charind = 0; + } + } else if((optind >= argc) || + ((argv[optind][0] == '-') && + (argv[optind][1] == '-') && + (argv[optind][2] == '\0'))) { + optind++; + opt = -1; + } else if((argv[optind][0] != '-') || + (argv[optind][1] == '\0')) { + char *tmp; + int i, j, k; + + if(mode == '+') opt = -1; + else if(mode == '-') { + optarg = argv[optind++]; + charind = 0; + opt = 1; + } else { + for(i=j=optind; i j) { + tmp=argv[--i]; + for(k=i; k+1 argc) optind = argc; + return opt; +} + +/* this is the extended getopt_long{,_only}, with some GNU-like + * extensions. Implements _getopt_internal in case any programs + * expecting GNU libc getopt call it. + */ + +int _getopt_internal(int argc, char * argv[], const char *shortopts, + const struct option *longopts, int *longind, + int long_only) +{ + char mode, colon_mode = *shortopts; + int shortoff = 0, opt = -1; + + if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+'; + else { + if((colon_mode = *shortopts) == ':') shortoff ++; + if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) { + shortoff++; + if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':')) + shortoff ++; + } + } + optarg = 0; + if((optind >= argc) || + ((argv[optind][0] == '-') && + (argv[optind][1] == '-') && + (argv[optind][2] == '\0'))) { + optind++; + opt = -1; + } else if((argv[optind][0] != '-') || + (argv[optind][1] == '\0')) { + char *tmp; + int i, j, k; + + opt = -1; + if(mode == '+') return -1; + else if(mode == '-') { + optarg = argv[optind++]; + return 1; + } + for(i=j=optind; i j) { + tmp=argv[--i]; + for(k=i; k+1= argc) { + opt = (colon_mode == ':') ? ':' : '?'; + if(opterr) fprintf(stderr, + "%s: option `--%s' requires an argument\n", + argv[0], longopts[found].name); + } else optarg = argv[optind]; + } + if(!opt) { + if (longind) *longind = found; + if(!longopts[found].flag) opt = longopts[found].val; + else *(longopts[found].flag) = longopts[found].val; + } + optind++; + } else if(!hits) { + if(offset == 1) opt = _getopt(argc, argv, shortopts); + else { + opt = '?'; + if(opterr) fprintf(stderr, + "%s: unrecognized option `%s'\n", + argv[0], argv[optind++]); + } + } else { + opt = '?'; + if(opterr) fprintf(stderr, + "%s: option `%s' is ambiguous\n", + argv[0], argv[optind++]); + } + } + if (optind > argc) optind = argc; + return opt; +} + +/* This function is kinda problematic because most getopt() nowadays + seem to use char * const argv[] (they DON'T permute the options list), + but this one does. So we remove it as long as HAVE_GETOPT is define, so + people can use the version from their platform instead */ + +#ifndef HAVE_GETOPT +int getopt(int argc, char * argv[], const char *opts) +{ + return _getopt(argc, argv, opts); +} +#endif /* HAVE_GETOPT */ + +int getopt_long(int argc, char * argv[], const char *shortopts, + const struct option *longopts, int *longind) +{ + return _getopt_internal(argc, argv, shortopts, longopts, longind, 0); +} + +int getopt_long_only(int argc, char * argv[], const char *shortopts, + const struct option *longopts, int *longind) +{ + return _getopt_internal(argc, argv, shortopts, longopts, longind, 1); +} -- cgit v1.2.3