diff options
author | dzwdz | 2022-08-14 12:31:27 +0200 |
---|---|---|
committer | dzwdz | 2022-08-14 12:31:27 +0200 |
commit | f603ceb5c67df6c1b5201b483f7fd5e9d37180d4 (patch) | |
tree | 61984426a494cbe061124199923d72a11ddaa90b /src/user/lib/vendor/getopt/getopt.c | |
parent | 95c4d23af122131fd0f83dee70e9cce65c46d49f (diff) |
user/libc: port skeeto's getopt
Diffstat (limited to 'src/user/lib/vendor/getopt/getopt.c')
-rw-r--r-- | src/user/lib/vendor/getopt/getopt.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/user/lib/vendor/getopt/getopt.c b/src/user/lib/vendor/getopt/getopt.c new file mode 100644 index 0000000..63c9b51 --- /dev/null +++ b/src/user/lib/vendor/getopt/getopt.c @@ -0,0 +1,75 @@ +/* Adapted from https://github.com/skeeto/getopt by Chris Wellons */ + +/* A minimal POSIX getopt() implementation in ANSI C + * + * This is free and unencumbered software released into the public domain. + * + * This implementation supports the convention of resetting the option + * parser by assigning optind to 0. This resets the internal state + * appropriately. + * + * Ref: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html + */ +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include "getopt.h" + +int optind; +int opterr = 1; +int optopt; +char *optarg; + +int +getopt(int argc, char * const argv[], const char *optstring) +{ + static int optpos = 1; + const char *arg; + + /* Reset? */ + if (optind == 0) { + optind = !!argc; + optpos = 1; + } + + arg = argv[optind]; + if (arg && strcmp(arg, "--") == 0) { + optind++; + return -1; + } else if (!arg || arg[0] != '-' || !isalnum(arg[1])) { + return -1; + } else { + const char *opt = strchr(optstring, arg[optpos]); + optopt = arg[optpos]; + if (!opt) { + if (opterr && *optstring != ':') + fprintf(stderr, "%s: illegal option: %c\n", argv[0], optopt); + return '?'; + } else if (opt[1] == ':') { + if (arg[optpos + 1]) { + optarg = (char *)arg + optpos + 1; + optind++; + optpos = 1; + return optopt; + } else if (argv[optind + 1]) { + optarg = (char *)argv[optind + 1]; + optind += 2; + optpos = 1; + return optopt; + } else { + if (opterr && *optstring != ':') + fprintf(stderr, + "%s: option requires an argument: %c\n", + argv[0], optopt); + return *optstring == ':' ? ':' : '?'; + } + } else { + if (!arg[++optpos]) { + optind++; + optpos = 1; + } + return optopt; + } + } +} + |