diff options
author | millert <> | 2002-12-06 16:03:29 +0000 |
---|---|---|
committer | millert <> | 2002-12-06 16:03:29 +0000 |
commit | 25071cb01d98bb08f0c7db1ead925c76f842e478 (patch) | |
tree | 102ce34542e99015ed9dbe0607a26ebbd9d43549 /src/lib | |
parent | 5504584fd484b7a88fdb9ec6060ce1c70cd9bc0e (diff) | |
download | openbsd-25071cb01d98bb08f0c7db1ead925c76f842e478.tar.gz openbsd-25071cb01d98bb08f0c7db1ead925c76f842e478.tar.bz2 openbsd-25071cb01d98bb08f0c7db1ead925c76f842e478.zip |
Fix two compatibility issues with our getopt_long_only() vs. the GNU version:
o Check for long options even when not at the beginning of an option.
For instance, if -a is a short option w/o an arg and -static is a
boolean long option then -astatic is valid for getopt_long_only().
o If a potential long argument does not match longopts and the first
character is not a short option, print a warning and skip the rest
of the argument.
Also clean up some trailing whitespace and change return value of
parse_long_options() from -2 to -1 when unmatched and in long_only mode.
With these fixes the binutils ld seems happy with our getopt_long_only()
Diffstat (limited to 'src/lib')
-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 | } |