initial check-in, version 0.5.0
[musl] / src / misc / getopt.c
1 #include <unistd.h>
2 #include <wchar.h>
3 #include <string.h>
4 #include <limits.h>
5 #include <stdlib.h>
6
7 char *optarg;
8 int optind=1, opterr=1, optopt;
9 static int optpos;
10
11 int getopt(int argc, char * const argv[], const char *optstring)
12 {
13         int i;
14         wchar_t c, d;
15         int k, l;
16         char *optchar;
17
18         if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1])
19                 return -1;
20         if (argv[optind][1] == '-' && !argv[optind][2])
21                 return optind++, -1;
22
23         if (!optpos) optpos++;
24         if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
25                 k = 1;
26                 c = 0xfffd; /* replacement char */
27         }
28         optchar = argv[optind]+optpos;
29         optopt = c;
30         optpos += k;
31
32         if (!argv[optind][optpos]) {
33                 optind++;
34                 optpos = 0;
35         }
36
37         for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);
38
39         if (d != c) {
40                 if (optstring[0] != ':' && opterr) {
41                         write(2, argv[0], strlen(argv[0]));
42                         write(2, ": illegal option: ", 18);
43                         write(2, optchar, k);
44                         write(2, "\n", 1);
45                 }
46                 return '?';
47         }
48         if (optstring[i+1] == ':') {
49                 if (optind >= argc) {
50                         if (optstring[0] == ':') return ':';
51                         if (opterr) {
52                                 write(2, argv[0], strlen(argv[0]));
53                                 write(2, ": option requires an argument: ", 31);
54                                 write(2, optchar, k);
55                                 write(2, "\n", 1);
56                         }
57                         return '?';
58                 }
59                 optarg = argv[optind++] + optpos;
60                 optpos = 0;
61         }
62         return c;
63 }