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 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]); 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