Index: fusl/src/misc/getopt.c |
diff --git a/fusl/src/misc/getopt.c b/fusl/src/misc/getopt.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..921798303f747ca8edf6b13cfc1508c9f5191242 |
--- /dev/null |
+++ b/fusl/src/misc/getopt.c |
@@ -0,0 +1,103 @@ |
+#include <unistd.h> |
+#include <wchar.h> |
+#include <string.h> |
+#include <limits.h> |
+#include <stdlib.h> |
+#include "libc.h" |
+#include "locale_impl.h" |
+ |
+char *optarg; |
+int optind=1, opterr=1, optopt, __optpos, __optreset=0; |
+ |
+#define optpos __optpos |
+weak_alias(__optreset, optreset); |
+ |
+void __getopt_msg(const char *a, const char *b, const char *c, size_t l) |
+{ |
+ FILE *f = stderr; |
+ b = __lctrans_cur(b); |
+ flockfile(f); |
+ fwrite(a, strlen(a), 1, f) |
+ && fwrite(b, strlen(b), 1, f) |
+ && fwrite(c, l, 1, f) |
+ && putc('\n', f); |
+ funlockfile(f); |
+} |
+ |
+int getopt(int argc, char * const argv[], const char *optstring) |
+{ |
+ int i; |
+ wchar_t c, d; |
+ int k, l; |
+ char *optchar; |
+ |
+ if (!optind || __optreset) { |
+ __optreset = 0; |
+ __optpos = 0; |
+ optind = 1; |
+ } |
+ |
+ if (optind >= argc || !argv[optind]) |
+ return -1; |
+ |
+ if (argv[optind][0] != '-') { |
+ if (optstring[0] == '-') { |
+ optarg = argv[optind++]; |
+ return 1; |
+ } |
+ return -1; |
+ } |
+ |
+ if (!argv[optind][1]) |
+ return -1; |
+ |
+ if (argv[optind][1] == '-' && !argv[optind][2]) |
+ return optind++, -1; |
+ |
+ if (!optpos) optpos++; |
+ if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) { |
+ k = 1; |
+ c = 0xfffd; /* replacement char */ |
+ } |
+ optchar = argv[optind]+optpos; |
+ optopt = c; |
+ optpos += k; |
+ |
+ if (!argv[optind][optpos]) { |
+ optind++; |
+ optpos = 0; |
+ } |
+ |
+ if (optstring[0] == '-' || optstring[0] == '+') |
+ optstring++; |
+ |
+ i = 0; |
+ d = 0; |
+ do { |
+ l = mbtowc(&d, optstring+i, MB_LEN_MAX); |
+ if (l>0) i+=l; else i++; |
+ } while (l && d != c); |
+ |
+ if (d != c) { |
+ if (optstring[0] != ':' && opterr) |
+ __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); |
+ return '?'; |
+ } |
+ if (optstring[i] == ':') { |
+ if (optstring[i+1] == ':') optarg = 0; |
+ else if (optind >= argc) { |
+ if (optstring[0] == ':') return ':'; |
+ if (opterr) __getopt_msg(argv[0], |
+ ": option requires an argument: ", |
+ optchar, k); |
+ return '?'; |
+ } |
+ if (optstring[i+1] != ':' || optpos) { |
+ optarg = argv[optind++] + optpos; |
+ optpos = 0; |
+ } |
+ } |
+ return c; |
+} |
+ |
+weak_alias(getopt, __posix_getopt); |