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 |