X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmisc%2Fgetopt.c;h=921798303f747ca8edf6b13cfc1508c9f5191242;hb=51fc77c7c03fa0b300e9a609b18f11f0e4db065a;hp=abf0e8477f5f71a7e58bd84b6ce92228f36a770d;hpb=0b44a0315b47dd8eced9f3b7f31580cf14bbfc01;p=musl diff --git a/src/misc/getopt.c b/src/misc/getopt.c index abf0e847..92179830 100644 --- a/src/misc/getopt.c +++ b/src/misc/getopt.c @@ -3,10 +3,26 @@ #include #include #include +#include "libc.h" +#include "locale_impl.h" char *optarg; -int optind=1, opterr=1, optopt; -static int optpos; +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) { @@ -15,8 +31,26 @@ int getopt(int argc, char * const argv[], const char *optstring) int k, l; char *optchar; - if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1]) + 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; @@ -34,30 +68,36 @@ int getopt(int argc, char * const argv[], const char *optstring) optpos = 0; } - for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1); + 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) { - write(2, argv[0], strlen(argv[0])); - write(2, ": illegal option: ", 18); - write(2, optchar, k); - write(2, "\n", 1); - } + if (optstring[0] != ':' && opterr) + __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); return '?'; } - if (optstring[i+1] == ':') { - if (optind >= argc) { + if (optstring[i] == ':') { + if (optstring[i+1] == ':') optarg = 0; + else if (optind >= argc) { if (optstring[0] == ':') return ':'; - if (opterr) { - write(2, argv[0], strlen(argv[0])); - write(2, ": option requires an argument: ", 31); - write(2, optchar, k); - write(2, "\n", 1); - } + if (opterr) __getopt_msg(argv[0], + ": option requires an argument: ", + optchar, k); return '?'; } - optarg = argv[optind++] + optpos; - optpos = 0; + if (optstring[i+1] != ':' || optpos) { + optarg = argv[optind++] + optpos; + optpos = 0; + } } return c; } + +weak_alias(getopt, __posix_getopt);