From f603ceb5c67df6c1b5201b483f7fd5e9d37180d4 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sun, 14 Aug 2022 12:31:27 +0200 Subject: user/libc: port skeeto's getopt --- src/user/lib/vendor/getopt/getopt.c | 75 +++++++++++++++++++++++++++++++++++++ src/user/lib/vendor/getopt/getopt.h | 21 +++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/user/lib/vendor/getopt/getopt.c create mode 100644 src/user/lib/vendor/getopt/getopt.h (limited to 'src/user') 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 +#include +#include +#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; + } + } +} + diff --git a/src/user/lib/vendor/getopt/getopt.h b/src/user/lib/vendor/getopt/getopt.h new file mode 100644 index 0000000..4cb075c --- /dev/null +++ b/src/user/lib/vendor/getopt/getopt.h @@ -0,0 +1,21 @@ +/* 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 + */ +#ifndef GETOPT_H +#define GETOPT_H + +extern int optind, opterr, optopt; +extern char *optarg; + +int getopt(int argc, char * const argv[], const char *optstring); + +#endif -- cgit v1.2.3