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