diff options
Diffstat (limited to 'libc-top-half/musl/src/misc/getopt.c')
-rw-r--r-- | libc-top-half/musl/src/misc/getopt.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/misc/getopt.c b/libc-top-half/musl/src/misc/getopt.c new file mode 100644 index 0000000..c3f6699 --- /dev/null +++ b/libc-top-half/musl/src/misc/getopt.c @@ -0,0 +1,105 @@ +#define _BSD_SOURCE +#include <unistd.h> +#include <wchar.h> +#include <string.h> +#include <limits.h> +#include <stdlib.h> +#include "locale_impl.h" +#include "stdio_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); + FLOCK(f); + fputs(a, f)>=0 + && fwrite(b, strlen(b), 1, f) + && fwrite(c, 1, l, f)==l + && putc('\n', f); + FUNLOCK(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; + 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 || c == ':') { + optopt = c; + if (optstring[0] != ':' && opterr) + __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); + return '?'; + } + if (optstring[i] == ':') { + optarg = 0; + if (optstring[i+1] != ':' || optpos) { + optarg = argv[optind++] + optpos; + optpos = 0; + } + if (optind > argc) { + optopt = c; + if (optstring[0] == ':') return ':'; + if (opterr) __getopt_msg(argv[0], + ": option requires an argument: ", + optchar, k); + return '?'; + } + } + return c; +} + +weak_alias(getopt, __posix_getopt); |