| OLD | NEW |
| 1 #define _GNU_SOURCE | 1 #define _GNU_SOURCE |
| 2 #include <stddef.h> | 2 #include <stddef.h> |
| 3 #include <getopt.h> | 3 #include <getopt.h> |
| 4 #include <stdio.h> | 4 #include <stdio.h> |
| 5 #include <string.h> | 5 #include <string.h> |
| 6 | 6 |
| 7 extern int __optpos, __optreset; | 7 extern int __optpos, __optreset; |
| 8 | 8 |
| 9 static void permute(char *const *argv, int dest, int src) | 9 static void permute(char* const* argv, int dest, int src) { |
| 10 { | 10 char** av = (char**)argv; |
| 11 » char **av = (char **)argv; | 11 char* tmp = av[src]; |
| 12 » char *tmp = av[src]; | 12 int i; |
| 13 » int i; | 13 for (i = src; i > dest; i--) |
| 14 » for (i=src; i>dest; i--) | 14 av[i] = av[i - 1]; |
| 15 » » av[i] = av[i-1]; | 15 av[dest] = tmp; |
| 16 » av[dest] = tmp; | |
| 17 } | 16 } |
| 18 | 17 |
| 19 void __getopt_msg(const char *, const char *, const char *, size_t); | 18 void __getopt_msg(const char*, const char*, const char*, size_t); |
| 20 | 19 |
| 21 static int __getopt_long_core(int argc, char *const *argv, const char *optstring
, const struct option *longopts, int *idx, int longonly); | 20 static int __getopt_long_core(int argc, |
| 21 char* const* argv, |
| 22 const char* optstring, |
| 23 const struct option* longopts, |
| 24 int* idx, |
| 25 int longonly); |
| 22 | 26 |
| 23 static int __getopt_long(int argc, char *const *argv, const char *optstring, con
st struct option *longopts, int *idx, int longonly) | 27 static int __getopt_long(int argc, |
| 24 { | 28 char* const* argv, |
| 25 » int ret, skipped, resumed; | 29 const char* optstring, |
| 26 » if (!optind || __optreset) { | 30 const struct option* longopts, |
| 27 » » __optreset = 0; | 31 int* idx, |
| 28 » » __optpos = 0; | 32 int longonly) { |
| 29 » » optind = 1; | 33 int ret, skipped, resumed; |
| 30 » } | 34 if (!optind || __optreset) { |
| 31 » if (optind >= argc || !argv[optind]) return -1; | 35 __optreset = 0; |
| 32 » skipped = optind; | 36 __optpos = 0; |
| 33 » if (optstring[0] != '+' && optstring[0] != '-') { | 37 optind = 1; |
| 34 » » int i; | 38 } |
| 35 » » for (i=optind; ; i++) { | 39 if (optind >= argc || !argv[optind]) |
| 36 » » » if (i >= argc || !argv[i]) return -1; | 40 return -1; |
| 37 » » » if (argv[i][0] == '-' && argv[i][1]) break; | 41 skipped = optind; |
| 38 » » } | 42 if (optstring[0] != '+' && optstring[0] != '-') { |
| 39 » » optind = i; | 43 int i; |
| 40 » } | 44 for (i = optind;; i++) { |
| 41 » resumed = optind; | 45 if (i >= argc || !argv[i]) |
| 42 » ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly)
; | 46 return -1; |
| 43 » if (resumed > skipped) { | 47 if (argv[i][0] == '-' && argv[i][1]) |
| 44 » » int i, cnt = optind-resumed; | 48 break; |
| 45 » » for (i=0; i<cnt; i++) | 49 } |
| 46 » » » permute(argv, skipped, optind-1); | 50 optind = i; |
| 47 » » optind = skipped + cnt; | 51 } |
| 48 » } | 52 resumed = optind; |
| 49 » return ret; | 53 ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly); |
| 54 if (resumed > skipped) { |
| 55 int i, cnt = optind - resumed; |
| 56 for (i = 0; i < cnt; i++) |
| 57 permute(argv, skipped, optind - 1); |
| 58 optind = skipped + cnt; |
| 59 } |
| 60 return ret; |
| 50 } | 61 } |
| 51 | 62 |
| 52 static int __getopt_long_core(int argc, char *const *argv, const char *optstring
, const struct option *longopts, int *idx, int longonly) | 63 static int __getopt_long_core(int argc, |
| 53 { | 64 char* const* argv, |
| 54 » optarg = 0; | 65 const char* optstring, |
| 55 » if (longopts && argv[optind][0] == '-' && | 66 const struct option* longopts, |
| 56 » » ((longonly && argv[optind][1]) || | 67 int* idx, |
| 57 » » (argv[optind][1] == '-' && argv[optind][2]))) | 68 int longonly) { |
| 58 » { | 69 optarg = 0; |
| 59 » » int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':'
; | 70 if (longopts && argv[optind][0] == '-' && |
| 60 » » int i, cnt, match; | 71 ((longonly && argv[optind][1]) || |
| 61 » » char *opt; | 72 (argv[optind][1] == '-' && argv[optind][2]))) { |
| 62 » » for (cnt=i=0; longopts[i].name; i++) { | 73 int colon = optstring[optstring[0] == '+' || optstring[0] == '-'] == ':'; |
| 63 » » » const char *name = longopts[i].name; | 74 int i, cnt, match; |
| 64 » » » opt = argv[optind]+1; | 75 char* opt; |
| 65 » » » if (*opt == '-') opt++; | 76 for (cnt = i = 0; longopts[i].name; i++) { |
| 66 » » » for (; *name && *name == *opt; name++, opt++); | 77 const char* name = longopts[i].name; |
| 67 » » » if (*opt && *opt != '=') continue; | 78 opt = argv[optind] + 1; |
| 68 » » » match = i; | 79 if (*opt == '-') |
| 69 » » » if (!*name) { | 80 opt++; |
| 70 » » » » cnt = 1; | 81 for (; *name && *name == *opt; name++, opt++) |
| 71 » » » » break; | 82 ; |
| 72 » » » } | 83 if (*opt && *opt != '=') |
| 73 » » » cnt++; | 84 continue; |
| 74 » » } | 85 match = i; |
| 75 » » if (cnt==1) { | 86 if (!*name) { |
| 76 » » » i = match; | 87 cnt = 1; |
| 77 » » » optind++; | 88 break; |
| 78 » » » optopt = longopts[i].val; | 89 } |
| 79 » » » if (*opt == '=') { | 90 cnt++; |
| 80 » » » » if (!longopts[i].has_arg) { | 91 } |
| 81 » » » » » if (colon || !opterr) | 92 if (cnt == 1) { |
| 82 » » » » » » return '?'; | 93 i = match; |
| 83 » » » » » __getopt_msg(argv[0], | 94 optind++; |
| 84 » » » » » » ": option does not take an argum
ent: ", | 95 optopt = longopts[i].val; |
| 85 » » » » » » longopts[i].name, | 96 if (*opt == '=') { |
| 86 » » » » » » strlen(longopts[i].name)); | 97 if (!longopts[i].has_arg) { |
| 87 » » » » » return '?'; | 98 if (colon || !opterr) |
| 88 » » » » } | 99 return '?'; |
| 89 » » » » optarg = opt+1; | 100 __getopt_msg(argv[0], ": option does not take an argument: ", |
| 90 » » » } else if (longopts[i].has_arg == required_argument) { | 101 longopts[i].name, strlen(longopts[i].name)); |
| 91 » » » » if (!(optarg = argv[optind])) { | 102 return '?'; |
| 92 » » » » » if (colon) return ':'; | 103 } |
| 93 » » » » » if (!opterr) return '?'; | 104 optarg = opt + 1; |
| 94 » » » » » __getopt_msg(argv[0], | 105 } else if (longopts[i].has_arg == required_argument) { |
| 95 » » » » » » ": option requires an argument:
", | 106 if (!(optarg = argv[optind])) { |
| 96 » » » » » » longopts[i].name, | 107 if (colon) |
| 97 » » » » » » strlen(longopts[i].name)); | 108 return ':'; |
| 98 » » » » » return '?'; | 109 if (!opterr) |
| 99 » » » » } | 110 return '?'; |
| 100 » » » » optind++; | 111 __getopt_msg(argv[0], ": option requires an argument: ", |
| 101 » » » } | 112 longopts[i].name, strlen(longopts[i].name)); |
| 102 » » » if (idx) *idx = i; | 113 return '?'; |
| 103 » » » if (longopts[i].flag) { | 114 } |
| 104 » » » » *longopts[i].flag = longopts[i].val; | 115 optind++; |
| 105 » » » » return 0; | 116 } |
| 106 » » » } | 117 if (idx) |
| 107 » » » return longopts[i].val; | 118 *idx = i; |
| 108 » » } | 119 if (longopts[i].flag) { |
| 109 » » if (argv[optind][1] == '-') { | 120 *longopts[i].flag = longopts[i].val; |
| 110 » » » if (!colon && opterr) | 121 return 0; |
| 111 » » » » __getopt_msg(argv[0], cnt ? | 122 } |
| 112 » » » » » ": option is ambiguous: " : | 123 return longopts[i].val; |
| 113 » » » » » ": unrecognized option: ", | 124 } |
| 114 » » » » » argv[optind]+2, | 125 if (argv[optind][1] == '-') { |
| 115 » » » » » strlen(argv[optind]+2)); | 126 if (!colon && opterr) |
| 116 » » » optind++; | 127 __getopt_msg(argv[0], cnt ? ": option is ambiguous: " |
| 117 » » » return '?'; | 128 : ": unrecognized option: ", |
| 118 » » } | 129 argv[optind] + 2, strlen(argv[optind] + 2)); |
| 119 » } | 130 optind++; |
| 120 » return getopt(argc, argv, optstring); | 131 return '?'; |
| 132 } |
| 133 } |
| 134 return getopt(argc, argv, optstring); |
| 121 } | 135 } |
| 122 | 136 |
| 123 int getopt_long(int argc, char *const *argv, const char *optstring, const struct
option *longopts, int *idx) | 137 int getopt_long(int argc, |
| 124 { | 138 char* const* argv, |
| 125 » return __getopt_long(argc, argv, optstring, longopts, idx, 0); | 139 const char* optstring, |
| 140 const struct option* longopts, |
| 141 int* idx) { |
| 142 return __getopt_long(argc, argv, optstring, longopts, idx, 0); |
| 126 } | 143 } |
| 127 | 144 |
| 128 int getopt_long_only(int argc, char *const *argv, const char *optstring, const s
truct option *longopts, int *idx) | 145 int getopt_long_only(int argc, |
| 129 { | 146 char* const* argv, |
| 130 » return __getopt_long(argc, argv, optstring, longopts, idx, 1); | 147 const char* optstring, |
| 148 const struct option* longopts, |
| 149 int* idx) { |
| 150 return __getopt_long(argc, argv, optstring, longopts, idx, 1); |
| 131 } | 151 } |
| OLD | NEW |