* parse_long_options -- * Parse long options in argc/argv argument vector. * Returns -1 if short_too is set and the option does not match long_options. */
| 188 | * Returns -1 if short_too is set and the option does not match long_options. |
| 189 | */ |
| 190 | static int parse_long_options( |
| 191 | char* const* nargv, char const* options, const struct option* long_options, int* idx, int short_too) |
| 192 | { |
| 193 | char *current_argv, *has_equal; |
| 194 | size_t current_argv_len; |
| 195 | int i, ambiguous, match; |
| 196 | |
| 197 | #define IDENTICAL_INTERPRETATION(_x, _y) \ |
| 198 | (long_options[(_x)].has_arg == long_options[(_y)].has_arg && long_options[(_x)].flag == long_options[(_y)].flag \ |
| 199 | && long_options[(_x)].val == long_options[(_y)].val) |
| 200 | |
| 201 | current_argv = place; |
| 202 | match = -1; |
| 203 | ambiguous = 0; |
| 204 | |
| 205 | optind++; |
| 206 | |
| 207 | if ((has_equal = strchr(current_argv, '=')) != NULL) |
| 208 | { |
| 209 | /* argument found (--option=arg) */ |
| 210 | current_argv_len = has_equal - current_argv; |
| 211 | has_equal++; |
| 212 | } |
| 213 | else |
| 214 | current_argv_len = strlen(current_argv); |
| 215 | |
| 216 | for (i = 0; long_options[i].name; i++) |
| 217 | { |
| 218 | /* find matching long option */ |
| 219 | if (strncmp(current_argv, long_options[i].name, current_argv_len)) |
| 220 | continue; |
| 221 | |
| 222 | if (strlen(long_options[i].name) == current_argv_len) |
| 223 | { |
| 224 | /* exact match */ |
| 225 | match = i; |
| 226 | ambiguous = 0; |
| 227 | break; |
| 228 | } |
| 229 | /* |
| 230 | * If this is a known short option, don't allow |
| 231 | * a partial match of a single character. |
| 232 | */ |
| 233 | if (short_too && current_argv_len == 1) |
| 234 | continue; |
| 235 | |
| 236 | if (match == -1) /* partial match */ |
| 237 | match = i; |
| 238 | else if (!IDENTICAL_INTERPRETATION(i, match)) |
| 239 | ambiguous = 1; |
| 240 | } |
| 241 | if (ambiguous) |
| 242 | { |
| 243 | /* ambiguous abbreviation */ |
| 244 | if (PRINT_ERROR) |
| 245 | warnx(ambig, (int) current_argv_len, current_argv); |
| 246 | optopt = 0; |
| 247 | return (BADCH); |
no test coverage detected