1 #include "getopt.h"
2 
3 #include <stdio.h>
4 #include <string.h>
5 
6 #define  _getprogname() nargv[0]
7 
8 int opterr = 1;
9 int optind = 1;
10 int optopt = 0;
11 char* optarg;
12 
getopt(int argc,char * const argv[],const char * ostr)13 int getopt(int argc, char* const argv[], const char* ostr) {
14     static const char kEmpty[] = "";
15     static const char* place = kEmpty;
16     if (!*place) {
17         if (optind >= argc)
18             return -1;
19 
20         const char* arg = argv[optind];
21         if (arg[0] != '-') {
22             // Not an option.
23             return -1;
24         }
25         if (arg[1] == '-' && !arg[2]) {
26             // '--' -> end of options.
27             return -1;
28         }
29         if (!arg[1]) {
30             // Single '-', If the program wants it, treat it as an option.
31             // Otherwise, it's the end of options.
32             if (!strchr(ostr, '-')) {
33                 return -1;
34             }
35             optopt = '-';
36             place = arg + 1;
37         } else {
38             optopt = arg[1];
39             place = arg + 2;
40         }
41     };
42 
43     char* oindex = strchr(ostr, optopt);
44     if (!oindex) {
45         // Unsupported option.
46         (void)fprintf(stderr, "%s: illegal option -- %c\n", argv[0], optopt);
47         return '?';
48     }
49     if (oindex[1] != ':') {
50         // No argument needed.
51         optarg = NULL;
52         if (!*place)
53             optind++;
54         return optopt;
55     }
56 
57     // This option needs an argument. Either after the option character,
58     // or the argument that follows.
59     if (*place) {
60         optarg = (char *)place;
61     } else if (argc > ++optind) {
62         optarg = (char *)argv[optind++];
63     } else if (oindex[2] == ':') {
64         // Optional argument is missing.
65         place = kEmpty;
66         optarg = NULL;
67         return optopt;
68     } else {
69         // Missing argument.
70         place = kEmpty;
71         (void)fprintf(stderr, "%s: option requires an argument --%c\n",
72                       argv[0], optopt);
73         return ':';
74     }
75     return optopt;
76 }
77