summaryrefslogtreecommitdiff
path: root/src/user/lib/vendor/getopt
diff options
context:
space:
mode:
authordzwdz2022-08-14 12:31:27 +0200
committerdzwdz2022-08-14 12:31:27 +0200
commitf603ceb5c67df6c1b5201b483f7fd5e9d37180d4 (patch)
tree61984426a494cbe061124199923d72a11ddaa90b /src/user/lib/vendor/getopt
parent95c4d23af122131fd0f83dee70e9cce65c46d49f (diff)
user/libc: port skeeto's getopt
Diffstat (limited to 'src/user/lib/vendor/getopt')
-rw-r--r--src/user/lib/vendor/getopt/getopt.c75
-rw-r--r--src/user/lib/vendor/getopt/getopt.h21
2 files changed, 96 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;
+ }
+ }
+}
+
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