Implementation based on [1]. [1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html */
| 167 | [1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html |
| 168 | */ |
| 169 | int getopt_long(int argc, wchar_t* const argv[], const wchar_t* optstring, |
| 170 | const struct option* longopts, int* longindex) { |
| 171 | const struct option* o = longopts; |
| 172 | const struct option* match = NULL; |
| 173 | int num_matches = 0; |
| 174 | size_t argument_name_length = 0; |
| 175 | const wchar_t* current_argument = NULL; |
| 176 | int retval = -1; |
| 177 | |
| 178 | optarg = NULL; |
| 179 | optopt = 0; |
| 180 | |
| 181 | if (optind >= argc) |
| 182 | return -1; |
| 183 | |
| 184 | if (wcslen(argv[optind]) < 3 || wcsncmp(argv[optind], L"--", 2) != 0) |
| 185 | return getopt(argc, argv, optstring); |
| 186 | |
| 187 | /* It's an option; starts with -- and is longer than two chars. */ |
| 188 | current_argument = argv[optind] + 2; |
| 189 | argument_name_length = wcscspn(current_argument, L"="); |
| 190 | for (; o->name; ++o) { |
| 191 | if (wcsncmp(o->name, current_argument, argument_name_length) == 0) { |
| 192 | match = o; |
| 193 | ++num_matches; |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | if (num_matches == 1) { |
| 198 | /* If longindex is not NULL, it points to a variable which is set to the |
| 199 | index of the long option relative to longopts. */ |
| 200 | if (longindex) |
| 201 | *longindex = (int)(match - longopts); |
| 202 | |
| 203 | /* If flag is NULL, then getopt_long() shall return val. |
| 204 | Otherwise, getopt_long() returns 0, and flag shall point to a variable |
| 205 | which shall be set to val if the option is found, but left unchanged if |
| 206 | the option is not found. */ |
| 207 | if (match->flag) |
| 208 | *(match->flag) = match->val; |
| 209 | |
| 210 | retval = match->flag ? 0 : match->val; |
| 211 | |
| 212 | if (match->has_arg != no_argument) { |
| 213 | optarg = wcschr(argv[optind], '='); |
| 214 | if (optarg != NULL) |
| 215 | ++optarg; |
| 216 | |
| 217 | if (match->has_arg == required_argument) { |
| 218 | /* Only scan the next argv for required arguments. Behavior is not |
| 219 | specified, but has been observed with Ubuntu and Mac OSX. */ |
| 220 | if (optarg == NULL && ++optind < argc) { |
| 221 | optarg = argv[optind]; |
| 222 | } |
| 223 | |
| 224 | if (optarg == NULL) |
| 225 | retval = ':'; |
| 226 | } |
no test coverage detected