diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libc/stdlib/getopt_long.c | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c index bcbd53cf44..7674d4a1e4 100644 --- a/src/lib/libc/stdlib/getopt_long.c +++ b/src/lib/libc/stdlib/getopt_long.c | |||
| @@ -1,6 +1,32 @@ | |||
| 1 | /* $OpenBSD: getopt_long.c,v 1.4 2002/12/05 22:26:04 millert Exp $ */ | 1 | /* $OpenBSD: getopt_long.c,v 1.5 2002/12/06 16:03:29 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 | /* | ||
| 5 | * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * 1. Redistributions of source code must retain the above copyright | ||
| 12 | * notice, this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * 3. The name of the author may not be used to endorse or promote products | ||
| 17 | * derived from this software without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
| 20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
| 21 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | ||
| 22 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
| 25 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
| 27 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
| 28 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | */ | ||
| 4 | /*- | 30 | /*- |
| 5 | * Copyright (c) 2000 The NetBSD Foundation, Inc. | 31 | * Copyright (c) 2000 The NetBSD Foundation, Inc. |
| 6 | * All rights reserved. | 32 | * All rights reserved. |
| @@ -38,7 +64,7 @@ | |||
| 38 | */ | 64 | */ |
| 39 | 65 | ||
| 40 | #if defined(LIBC_SCCS) && !defined(lint) | 66 | #if defined(LIBC_SCCS) && !defined(lint) |
| 41 | static char *rcsid = "$OpenBSD: getopt_long.c,v 1.4 2002/12/05 22:26:04 millert Exp $"; | 67 | static char *rcsid = "$OpenBSD: getopt_long.c,v 1.5 2002/12/06 16:03:29 millert Exp $"; |
| 42 | #endif /* LIBC_SCCS and not lint */ | 68 | #endif /* LIBC_SCCS and not lint */ |
| 43 | 69 | ||
| 44 | #include <err.h> | 70 | #include <err.h> |
| @@ -70,7 +96,7 @@ char *optarg; /* argument associated with option */ | |||
| 70 | 96 | ||
| 71 | static int getopt_internal(int, char * const *, const char *, | 97 | static int getopt_internal(int, char * const *, const char *, |
| 72 | const struct option *, int *, int); | 98 | const struct option *, int *, int); |
| 73 | static int parse_long_options(int, char * const *, const char *, | 99 | static int parse_long_options(char * const *, const char *, |
| 74 | const struct option *, int *, int); | 100 | const struct option *, int *, int); |
| 75 | static int gcd(int, int); | 101 | static int gcd(int, int); |
| 76 | static void permute_args(int, int, int, char * const *); | 102 | static void permute_args(int, int, int, char * const *); |
| @@ -103,7 +129,7 @@ gcd(int a, int b) | |||
| 103 | b = c; | 129 | b = c; |
| 104 | c = a % b; | 130 | c = a % b; |
| 105 | } | 131 | } |
| 106 | 132 | ||
| 107 | return (b); | 133 | return (b); |
| 108 | } | 134 | } |
| 109 | 135 | ||
| @@ -147,11 +173,11 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, | |||
| 147 | /* | 173 | /* |
| 148 | * parse_long_options -- | 174 | * parse_long_options -- |
| 149 | * Parse long options in argc/argv argument vector. | 175 | * Parse long options in argc/argv argument vector. |
| 150 | * Returns -2 if long_only is set and the current option could be a short | 176 | * Returns -1 if long_only is set and the current option could be a short |
| 151 | * (single character) option instead. | 177 | * (single character) option instead. |
| 152 | */ | 178 | */ |
| 153 | static int | 179 | static int |
| 154 | parse_long_options(int nargc, char * const *nargv, const char *options, | 180 | parse_long_options(char * const *nargv, const char *options, |
| 155 | const struct option *long_options, int *idx, int long_only) | 181 | const struct option *long_options, int *idx, int long_only) |
| 156 | { | 182 | { |
| 157 | char *current_argv, *has_equal; | 183 | char *current_argv, *has_equal; |
| @@ -249,7 +275,7 @@ parse_long_options(int nargc, char * const *nargv, const char *options, | |||
| 249 | } else { /* unknown option */ | 275 | } else { /* unknown option */ |
| 250 | if (long_only) { | 276 | if (long_only) { |
| 251 | --optind; | 277 | --optind; |
| 252 | return (-2); | 278 | return (-1); |
| 253 | } | 279 | } |
| 254 | if (PRINT_ERROR) | 280 | if (PRINT_ERROR) |
| 255 | warnx(illoptstring, current_argv); | 281 | warnx(illoptstring, current_argv); |
| @@ -261,7 +287,7 @@ parse_long_options(int nargc, char * const *nargv, const char *options, | |||
| 261 | if (long_options[match].flag) { | 287 | if (long_options[match].flag) { |
| 262 | *long_options[match].flag = long_options[match].val; | 288 | *long_options[match].flag = long_options[match].val; |
| 263 | return (0); | 289 | return (0); |
| 264 | } else | 290 | } else |
| 265 | return (long_options[match].val); | 291 | return (long_options[match].val); |
| 266 | } | 292 | } |
| 267 | 293 | ||
| @@ -275,6 +301,7 @@ getopt_internal(int nargc, char * const *nargv, const char *options, | |||
| 275 | { | 301 | { |
| 276 | char *oli; /* option letter list index */ | 302 | char *oli; /* option letter list index */ |
| 277 | int optchar; | 303 | int optchar; |
| 304 | int long_only; | ||
| 278 | static int posixly_correct = -1; | 305 | static int posixly_correct = -1; |
| 279 | 306 | ||
| 280 | optarg = NULL; | 307 | optarg = NULL; |
| @@ -328,7 +355,7 @@ start: | |||
| 328 | place = EMSG; | 355 | place = EMSG; |
| 329 | if (flags & FLAG_ALLARGS) { | 356 | if (flags & FLAG_ALLARGS) { |
| 330 | /* | 357 | /* |
| 331 | * GNU extension: | 358 | * GNU extension: |
| 332 | * return non-option as argument to option 1 | 359 | * return non-option as argument to option 1 |
| 333 | */ | 360 | */ |
| 334 | optarg = nargv[optind++]; | 361 | optarg = nargv[optind++]; |
| @@ -373,31 +400,37 @@ start: | |||
| 373 | return (-1); | 400 | return (-1); |
| 374 | } | 401 | } |
| 375 | place++; | 402 | place++; |
| 403 | } | ||
| 376 | 404 | ||
| 377 | /* Check long options if we have any */ | 405 | /* Check long options if we have any */ |
| 378 | if (long_options != NULL) { | 406 | long_only = 0; |
| 379 | int long_only = 0; | 407 | if (long_options != NULL) { |
| 380 | 408 | if (*place == '-' || | |
| 381 | if (*place == '-' || | 409 | (long_only = (flags & FLAG_LONGONLY))) { |
| 382 | (long_only = (flags & FLAG_LONGONLY))) { | 410 | if (!long_only) |
| 383 | if (!long_only) | 411 | place++; |
| 384 | place++; | 412 | optchar = parse_long_options(nargv, options, |
| 385 | optchar = parse_long_options(nargc, nargv, | 413 | long_options, idx, long_only); |
| 386 | options, long_options, idx, long_only); | 414 | if (optchar != -1) { |
| 387 | if (optchar != -2) { | 415 | place = EMSG; |
| 388 | place = EMSG; | 416 | return (optchar); |
| 389 | return (optchar); | ||
| 390 | } | ||
| 391 | } | 417 | } |
| 392 | } | 418 | } |
| 393 | } | 419 | } |
| 394 | if ((optchar = (int)*place++) == (int)':' || | 420 | if ((optchar = (int)*place++) == (int)':' || |
| 395 | (oli = strchr(options, optchar)) == NULL) { | 421 | (oli = strchr(options, optchar)) == NULL) { |
| 396 | /* option letter unknown or ':' */ | 422 | /* option letter unknown or ':' */ |
| 397 | if (!*place) | 423 | if (PRINT_ERROR) { |
| 424 | if (long_only) | ||
| 425 | warnx(illoptstring, place - 1); | ||
| 426 | else | ||
| 427 | warnx(illoptchar, optchar); | ||
| 428 | } | ||
| 429 | if (!*place || long_only) { | ||
| 398 | ++optind; | 430 | ++optind; |
| 399 | if (PRINT_ERROR) | 431 | if (*place) |
| 400 | warnx(illoptchar, optchar); | 432 | place = EMSG; |
| 433 | } | ||
| 401 | optopt = optchar; | 434 | optopt = optchar; |
| 402 | return (BADCH); | 435 | return (BADCH); |
| 403 | } | 436 | } |
| @@ -413,8 +446,8 @@ start: | |||
| 413 | return (BADARG); | 446 | return (BADARG); |
| 414 | } else /* white space */ | 447 | } else /* white space */ |
| 415 | place = nargv[optind]; | 448 | place = nargv[optind]; |
| 416 | optchar = parse_long_options(nargc, nargv, options, | 449 | optchar = parse_long_options(nargv, options, long_options, |
| 417 | long_options, idx, 0); | 450 | idx, 0); |
| 418 | place = EMSG; | 451 | place = EMSG; |
| 419 | return (optchar); | 452 | return (optchar); |
| 420 | } | 453 | } |
