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