github.com/afumu/libc@v0.0.6/musl/src/misc/getopt.c (about) 1 #define _BSD_SOURCE 2 #include <unistd.h> 3 #include <wchar.h> 4 #include <string.h> 5 #include <limits.h> 6 #include <stdlib.h> 7 #include "locale_impl.h" 8 #include "stdio_impl.h" 9 10 char *optarg; 11 int optind=1, opterr=1, optopt, __optpos, __optreset=0; 12 13 #define optpos __optpos 14 weak_alias(__optreset, optreset); 15 16 void __getopt_msg(const char *a, const char *b, const char *c, size_t l) 17 { 18 FILE *f = stderr; 19 b = __lctrans_cur(b); 20 FLOCK(f); 21 fputs(a, f)>=0 22 && fwrite(b, strlen(b), 1, f) 23 && fwrite(c, 1, l, f)==l 24 && putc('\n', f); 25 FUNLOCK(f); 26 } 27 28 int getopt(int argc, char * const argv[], const char *optstring) 29 { 30 int i; 31 wchar_t c, d; 32 int k, l; 33 char *optchar; 34 35 if (!optind || __optreset) { 36 __optreset = 0; 37 __optpos = 0; 38 optind = 1; 39 } 40 41 if (optind >= argc || !argv[optind]) 42 return -1; 43 44 if (argv[optind][0] != '-') { 45 if (optstring[0] == '-') { 46 optarg = argv[optind++]; 47 return 1; 48 } 49 return -1; 50 } 51 52 if (!argv[optind][1]) 53 return -1; 54 55 if (argv[optind][1] == '-' && !argv[optind][2]) 56 return optind++, -1; 57 58 if (!optpos) optpos++; 59 if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) { 60 k = 1; 61 c = 0xfffd; /* replacement char */ 62 } 63 optchar = argv[optind]+optpos; 64 optpos += k; 65 66 if (!argv[optind][optpos]) { 67 optind++; 68 optpos = 0; 69 } 70 71 if (optstring[0] == '-' || optstring[0] == '+') 72 optstring++; 73 74 i = 0; 75 d = 0; 76 do { 77 l = mbtowc(&d, optstring+i, MB_LEN_MAX); 78 if (l>0) i+=l; else i++; 79 } while (l && d != c); 80 81 if (d != c || c == ':') { 82 optopt = c; 83 if (optstring[0] != ':' && opterr) 84 __getopt_msg(argv[0], ": unrecognized option: ", optchar, k); 85 return '?'; 86 } 87 if (optstring[i] == ':') { 88 optarg = 0; 89 if (optstring[i+1] != ':' || optpos) { 90 optarg = argv[optind++] + optpos; 91 optpos = 0; 92 } 93 if (optind > argc) { 94 optopt = c; 95 if (optstring[0] == ':') return ':'; 96 if (opterr) __getopt_msg(argv[0], 97 ": option requires an argument: ", 98 optchar, k); 99 return '?'; 100 } 101 } 102 return c; 103 } 104 105 weak_alias(getopt, __posix_getopt);