diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libc/stdlib/getopt_long.c | 77 |
1 files changed, 36 insertions, 41 deletions
diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c index 7674d4a1e4..7f6dc23c44 100644 --- a/src/lib/libc/stdlib/getopt_long.c +++ b/src/lib/libc/stdlib/getopt_long.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: getopt_long.c,v 1.5 2002/12/06 16:03:29 millert Exp $ */ | 1 | /* $OpenBSD: getopt_long.c,v 1.6 2002/12/07 19:15:59 millert Exp $ */ |
| 2 | /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ | 2 | /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ |
| 3 | 3 | ||
| 4 | /* | 4 | /* |
| @@ -64,7 +64,7 @@ | |||
| 64 | */ | 64 | */ |
| 65 | 65 | ||
| 66 | #if defined(LIBC_SCCS) && !defined(lint) | 66 | #if defined(LIBC_SCCS) && !defined(lint) |
| 67 | static char *rcsid = "$OpenBSD: getopt_long.c,v 1.5 2002/12/06 16:03:29 millert Exp $"; | 67 | static char *rcsid = "$OpenBSD: getopt_long.c,v 1.6 2002/12/07 19:15:59 millert Exp $"; |
| 68 | #endif /* LIBC_SCCS and not lint */ | 68 | #endif /* LIBC_SCCS and not lint */ |
| 69 | 69 | ||
| 70 | #include <err.h> | 70 | #include <err.h> |
| @@ -173,12 +173,11 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, | |||
| 173 | /* | 173 | /* |
| 174 | * parse_long_options -- | 174 | * parse_long_options -- |
| 175 | * Parse long options in argc/argv argument vector. | 175 | * Parse long options in argc/argv argument vector. |
| 176 | * Returns -1 if long_only is set and the current option could be a short | 176 | * Returns -1 if short_too is set and the option does not match long_options. |
| 177 | * (single character) option instead. | ||
| 178 | */ | 177 | */ |
| 179 | static int | 178 | static int |
| 180 | parse_long_options(char * const *nargv, const char *options, | 179 | parse_long_options(char * const *nargv, const char *options, |
| 181 | const struct option *long_options, int *idx, int long_only) | 180 | const struct option *long_options, int *idx, int short_too) |
| 182 | { | 181 | { |
| 183 | char *current_argv, *has_equal; | 182 | char *current_argv, *has_equal; |
| 184 | size_t current_argv_len; | 183 | size_t current_argv_len; |
| @@ -208,11 +207,10 @@ parse_long_options(char * const *nargv, const char *options, | |||
| 208 | break; | 207 | break; |
| 209 | } | 208 | } |
| 210 | /* | 209 | /* |
| 211 | * Don't try a partial match of a short option when in | 210 | * If this is a known short option, don't allow |
| 212 | * long_only mode. Otherwise there is a potential conflict | 211 | * a partial match of a single character. |
| 213 | * between partial matches and short options. | ||
| 214 | */ | 212 | */ |
| 215 | if (long_only && current_argv_len == 1) | 213 | if (short_too && current_argv_len == 1) |
| 216 | continue; | 214 | continue; |
| 217 | 215 | ||
| 218 | if (match == -1) /* partial match */ | 216 | if (match == -1) /* partial match */ |
| @@ -273,7 +271,7 @@ parse_long_options(char * const *nargv, const char *options, | |||
| 273 | return (BADARG); | 271 | return (BADARG); |
| 274 | } | 272 | } |
| 275 | } else { /* unknown option */ | 273 | } else { /* unknown option */ |
| 276 | if (long_only) { | 274 | if (short_too) { |
| 277 | --optind; | 275 | --optind; |
| 278 | return (-1); | 276 | return (-1); |
| 279 | } | 277 | } |
| @@ -300,8 +298,7 @@ getopt_internal(int nargc, char * const *nargv, const char *options, | |||
| 300 | const struct option *long_options, int *idx, int flags) | 298 | const struct option *long_options, int *idx, int flags) |
| 301 | { | 299 | { |
| 302 | char *oli; /* option letter list index */ | 300 | char *oli; /* option letter list index */ |
| 303 | int optchar; | 301 | int optchar, short_too; |
| 304 | int long_only; | ||
| 305 | static int posixly_correct = -1; | 302 | static int posixly_correct = -1; |
| 306 | 303 | ||
| 307 | optarg = NULL; | 304 | optarg = NULL; |
| @@ -320,12 +317,13 @@ getopt_internal(int nargc, char * const *nargv, const char *options, | |||
| 320 | options++; | 317 | options++; |
| 321 | 318 | ||
| 322 | /* | 319 | /* |
| 323 | * XXX Some programs (like rsyncd) expect to be able to | 320 | * XXX Some GNU programs (like cvs) set optind to 0 instead of |
| 324 | * XXX re-initialize optind to 0 and have getopt_long(3) | 321 | * XXX using optreset. Work around this braindamage. |
| 325 | * XXX properly function again. Work around this braindamage. | ||
| 326 | */ | 322 | */ |
| 327 | if (optind == 0) | 323 | if (optind == 0) { |
| 328 | optind = 1; | 324 | optind = 1; |
| 325 | optreset = 1; | ||
| 326 | } | ||
| 329 | 327 | ||
| 330 | if (optreset) | 328 | if (optreset) |
| 331 | nonopt_start = nonopt_end = -1; | 329 | nonopt_start = nonopt_end = -1; |
| @@ -384,7 +382,10 @@ start: | |||
| 384 | } | 382 | } |
| 385 | if (nonopt_start != -1 && nonopt_end == -1) | 383 | if (nonopt_start != -1 && nonopt_end == -1) |
| 386 | nonopt_end = optind; | 384 | nonopt_end = optind; |
| 387 | if (strcmp(place, "--") == 0) { | 385 | |
| 386 | /* check for "--" or "--foo" with no long options */ | ||
| 387 | if (*++place == '-' && | ||
| 388 | (place[1] == '\0' || long_options == NULL)) { | ||
| 388 | optind++; | 389 | optind++; |
| 389 | place = EMSG; | 390 | place = EMSG; |
| 390 | /* | 391 | /* |
| @@ -399,38 +400,32 @@ start: | |||
| 399 | nonopt_start = nonopt_end = -1; | 400 | nonopt_start = nonopt_end = -1; |
| 400 | return (-1); | 401 | return (-1); |
| 401 | } | 402 | } |
| 402 | place++; | ||
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | /* Check long options if we have any */ | 405 | /* check long options if we have any */ |
| 406 | long_only = 0; | 406 | if (long_options != NULL && |
| 407 | if (long_options != NULL) { | 407 | (*place == '-' || (flags & FLAG_LONGONLY))) { |
| 408 | if (*place == '-' || | 408 | short_too = 0; |
| 409 | (long_only = (flags & FLAG_LONGONLY))) { | 409 | if (*place == '-') |
| 410 | if (!long_only) | 410 | place++; /* --foo long option */ |
| 411 | place++; | 411 | else if (*place != ':' && strchr(options, optchar) != NULL) |
| 412 | optchar = parse_long_options(nargv, options, | 412 | short_too = 1; /* could be short option too */ |
| 413 | long_options, idx, long_only); | 413 | |
| 414 | if (optchar != -1) { | 414 | optchar = parse_long_options(nargv, options, long_options, |
| 415 | place = EMSG; | 415 | idx, short_too); |
| 416 | return (optchar); | 416 | if (optchar != -1) { |
| 417 | } | 417 | place = EMSG; |
| 418 | return (optchar); | ||
| 418 | } | 419 | } |
| 419 | } | 420 | } |
| 421 | |||
| 420 | if ((optchar = (int)*place++) == (int)':' || | 422 | if ((optchar = (int)*place++) == (int)':' || |
| 421 | (oli = strchr(options, optchar)) == NULL) { | 423 | (oli = strchr(options, optchar)) == NULL) { |
| 422 | /* option letter unknown or ':' */ | 424 | /* option letter unknown or ':' */ |
| 423 | if (PRINT_ERROR) { | 425 | if (!*place) |
| 424 | if (long_only) | ||
| 425 | warnx(illoptstring, place - 1); | ||
| 426 | else | ||
| 427 | warnx(illoptchar, optchar); | ||
| 428 | } | ||
| 429 | if (!*place || long_only) { | ||
| 430 | ++optind; | 426 | ++optind; |
| 431 | if (*place) | 427 | if (PRINT_ERROR) |
| 432 | place = EMSG; | 428 | warnx(illoptchar, optchar); |
| 433 | } | ||
| 434 | optopt = optchar; | 429 | optopt = optchar; |
| 435 | return (BADCH); | 430 | return (BADCH); |
| 436 | } | 431 | } |
