diff options
Diffstat (limited to 'gl/getopt.c')
-rw-r--r-- | gl/getopt.c | 159 |
1 files changed, 106 insertions, 53 deletions
diff --git a/gl/getopt.c b/gl/getopt.c index 3791f129..ef0f4cee 100644 --- a/gl/getopt.c +++ b/gl/getopt.c | |||
@@ -2,7 +2,7 @@ | |||
2 | NOTE: getopt is part of the C library, so if you don't know what | 2 | NOTE: getopt is part of the C library, so if you don't know what |
3 | "Keep this file name-space clean" means, talk to drepper@gnu.org | 3 | "Keep this file name-space clean" means, talk to drepper@gnu.org |
4 | before changing it! | 4 | before changing it! |
5 | Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2010 Free Software | 5 | Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2013 Free Software |
6 | Foundation, Inc. | 6 | Foundation, Inc. |
7 | This file is part of the GNU C Library. | 7 | This file is part of the GNU C Library. |
8 | 8 | ||
@@ -41,15 +41,15 @@ | |||
41 | # include <wchar.h> | 41 | # include <wchar.h> |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | /* This version of `getopt' appears to the caller like standard Unix `getopt' | 44 | /* This version of 'getopt' appears to the caller like standard Unix 'getopt' |
45 | but it behaves differently for the user, since it allows the user | 45 | but it behaves differently for the user, since it allows the user |
46 | to intersperse the options with the other arguments. | 46 | to intersperse the options with the other arguments. |
47 | 47 | ||
48 | As `getopt_long' works, it permutes the elements of ARGV so that, | 48 | As 'getopt_long' works, it permutes the elements of ARGV so that, |
49 | when it is done, all the options precede everything else. Thus | 49 | when it is done, all the options precede everything else. Thus |
50 | all application programs are extended to handle flexible argument order. | 50 | all application programs are extended to handle flexible argument order. |
51 | 51 | ||
52 | Using `getopt' or setting the environment variable POSIXLY_CORRECT | 52 | Using 'getopt' or setting the environment variable POSIXLY_CORRECT |
53 | disables permutation. | 53 | disables permutation. |
54 | Then the behavior is completely standard. | 54 | Then the behavior is completely standard. |
55 | 55 | ||
@@ -58,24 +58,24 @@ | |||
58 | 58 | ||
59 | #include "getopt_int.h" | 59 | #include "getopt_int.h" |
60 | 60 | ||
61 | /* For communication from `getopt' to the caller. | 61 | /* For communication from 'getopt' to the caller. |
62 | When `getopt' finds an option that takes an argument, | 62 | When 'getopt' finds an option that takes an argument, |
63 | the argument value is returned here. | 63 | the argument value is returned here. |
64 | Also, when `ordering' is RETURN_IN_ORDER, | 64 | Also, when 'ordering' is RETURN_IN_ORDER, |
65 | each non-option ARGV-element is returned here. */ | 65 | each non-option ARGV-element is returned here. */ |
66 | 66 | ||
67 | char *optarg; | 67 | char *optarg; |
68 | 68 | ||
69 | /* Index in ARGV of the next element to be scanned. | 69 | /* Index in ARGV of the next element to be scanned. |
70 | This is used for communication to and from the caller | 70 | This is used for communication to and from the caller |
71 | and for communication between successive calls to `getopt'. | 71 | and for communication between successive calls to 'getopt'. |
72 | 72 | ||
73 | On entry to `getopt', zero means this is the first call; initialize. | 73 | On entry to 'getopt', zero means this is the first call; initialize. |
74 | 74 | ||
75 | When `getopt' returns -1, this is the index of the first of the | 75 | When 'getopt' returns -1, this is the index of the first of the |
76 | non-option elements that the caller should itself scan. | 76 | non-option elements that the caller should itself scan. |
77 | 77 | ||
78 | Otherwise, `optind' communicates from one call to the next | 78 | Otherwise, 'optind' communicates from one call to the next |
79 | how much of ARGV has been scanned so far. */ | 79 | how much of ARGV has been scanned so far. */ |
80 | 80 | ||
81 | /* 1003.2 says this must be 1 before any call. */ | 81 | /* 1003.2 says this must be 1 before any call. */ |
@@ -137,7 +137,7 @@ extern char *__getopt_nonoption_flags; | |||
137 | The other is elements [last_nonopt,optind), which contains all | 137 | The other is elements [last_nonopt,optind), which contains all |
138 | the options processed since those non-options were skipped. | 138 | the options processed since those non-options were skipped. |
139 | 139 | ||
140 | `first_nonopt' and `last_nonopt' are relocated so that they describe | 140 | 'first_nonopt' and 'last_nonopt' are relocated so that they describe |
141 | the new indices of the non-options in ARGV after they are moved. */ | 141 | the new indices of the non-options in ARGV after they are moved. */ |
142 | 142 | ||
143 | static void | 143 | static void |
@@ -154,7 +154,7 @@ exchange (char **argv, struct _getopt_data *d) | |||
154 | but it consists of two parts that need to be swapped next. */ | 154 | but it consists of two parts that need to be swapped next. */ |
155 | 155 | ||
156 | #if defined _LIBC && defined USE_NONOPTION_FLAGS | 156 | #if defined _LIBC && defined USE_NONOPTION_FLAGS |
157 | /* First make sure the handling of the `__getopt_nonoption_flags' | 157 | /* First make sure the handling of the '__getopt_nonoption_flags' |
158 | string can work normally. Our top argument must be in the range | 158 | string can work normally. Our top argument must be in the range |
159 | of the string. */ | 159 | of the string. */ |
160 | if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) | 160 | if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) |
@@ -291,48 +291,48 @@ _getopt_initialize (int argc _GL_UNUSED, | |||
291 | 291 | ||
292 | If an element of ARGV starts with '-', and is not exactly "-" or "--", | 292 | If an element of ARGV starts with '-', and is not exactly "-" or "--", |
293 | then it is an option element. The characters of this element | 293 | then it is an option element. The characters of this element |
294 | (aside from the initial '-') are option characters. If `getopt' | 294 | (aside from the initial '-') are option characters. If 'getopt' |
295 | is called repeatedly, it returns successively each of the option characters | 295 | is called repeatedly, it returns successively each of the option characters |
296 | from each of the option elements. | 296 | from each of the option elements. |
297 | 297 | ||
298 | If `getopt' finds another option character, it returns that character, | 298 | If 'getopt' finds another option character, it returns that character, |
299 | updating `optind' and `nextchar' so that the next call to `getopt' can | 299 | updating 'optind' and 'nextchar' so that the next call to 'getopt' can |
300 | resume the scan with the following option character or ARGV-element. | 300 | resume the scan with the following option character or ARGV-element. |
301 | 301 | ||
302 | If there are no more option characters, `getopt' returns -1. | 302 | If there are no more option characters, 'getopt' returns -1. |
303 | Then `optind' is the index in ARGV of the first ARGV-element | 303 | Then 'optind' is the index in ARGV of the first ARGV-element |
304 | that is not an option. (The ARGV-elements have been permuted | 304 | that is not an option. (The ARGV-elements have been permuted |
305 | so that those that are not options now come last.) | 305 | so that those that are not options now come last.) |
306 | 306 | ||
307 | OPTSTRING is a string containing the legitimate option characters. | 307 | OPTSTRING is a string containing the legitimate option characters. |
308 | If an option character is seen that is not listed in OPTSTRING, | 308 | If an option character is seen that is not listed in OPTSTRING, |
309 | return '?' after printing an error message. If you set `opterr' to | 309 | return '?' after printing an error message. If you set 'opterr' to |
310 | zero, the error message is suppressed but we still return '?'. | 310 | zero, the error message is suppressed but we still return '?'. |
311 | 311 | ||
312 | If a char in OPTSTRING is followed by a colon, that means it wants an arg, | 312 | If a char in OPTSTRING is followed by a colon, that means it wants an arg, |
313 | so the following text in the same ARGV-element, or the text of the following | 313 | so the following text in the same ARGV-element, or the text of the following |
314 | ARGV-element, is returned in `optarg'. Two colons mean an option that | 314 | ARGV-element, is returned in 'optarg'. Two colons mean an option that |
315 | wants an optional arg; if there is text in the current ARGV-element, | 315 | wants an optional arg; if there is text in the current ARGV-element, |
316 | it is returned in `optarg', otherwise `optarg' is set to zero. | 316 | it is returned in 'optarg', otherwise 'optarg' is set to zero. |
317 | 317 | ||
318 | If OPTSTRING starts with `-' or `+', it requests different methods of | 318 | If OPTSTRING starts with '-' or '+', it requests different methods of |
319 | handling the non-option ARGV-elements. | 319 | handling the non-option ARGV-elements. |
320 | See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. | 320 | See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. |
321 | 321 | ||
322 | Long-named options begin with `--' instead of `-'. | 322 | Long-named options begin with '--' instead of '-'. |
323 | Their names may be abbreviated as long as the abbreviation is unique | 323 | Their names may be abbreviated as long as the abbreviation is unique |
324 | or is an exact match for some defined option. If they have an | 324 | or is an exact match for some defined option. If they have an |
325 | argument, it follows the option name in the same ARGV-element, separated | 325 | argument, it follows the option name in the same ARGV-element, separated |
326 | from the option name by a `=', or else the in next ARGV-element. | 326 | from the option name by a '=', or else the in next ARGV-element. |
327 | When `getopt' finds a long-named option, it returns 0 if that option's | 327 | When 'getopt' finds a long-named option, it returns 0 if that option's |
328 | `flag' field is nonzero, the value of the option's `val' field | 328 | 'flag' field is nonzero, the value of the option's 'val' field |
329 | if the `flag' field is zero. | 329 | if the 'flag' field is zero. |
330 | 330 | ||
331 | The elements of ARGV aren't really const, because we permute them. | 331 | The elements of ARGV aren't really const, because we permute them. |
332 | But we pretend they're const in the prototype to be compatible | 332 | But we pretend they're const in the prototype to be compatible |
333 | with other systems. | 333 | with other systems. |
334 | 334 | ||
335 | LONGOPTS is a vector of `struct option' terminated by an | 335 | LONGOPTS is a vector of 'struct option' terminated by an |
336 | element containing a name which is zero. | 336 | element containing a name which is zero. |
337 | 337 | ||
338 | LONGIND returns the index in LONGOPT of the long-named option found. | 338 | LONGIND returns the index in LONGOPT of the long-named option found. |
@@ -409,7 +409,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
409 | d->__last_nonopt = d->optind; | 409 | d->__last_nonopt = d->optind; |
410 | } | 410 | } |
411 | 411 | ||
412 | /* The special ARGV-element `--' means premature end of options. | 412 | /* The special ARGV-element '--' means premature end of options. |
413 | Skip it like a null option, | 413 | Skip it like a null option, |
414 | then exchange with previous non-options as if it were an option, | 414 | then exchange with previous non-options as if it were an option, |
415 | then skip everything else like a non-option. */ | 415 | then skip everything else like a non-option. */ |
@@ -479,23 +479,28 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
479 | || !strchr (optstring, argv[d->optind][1]))))) | 479 | || !strchr (optstring, argv[d->optind][1]))))) |
480 | { | 480 | { |
481 | char *nameend; | 481 | char *nameend; |
482 | unsigned int namelen; | ||
482 | const struct option *p; | 483 | const struct option *p; |
483 | const struct option *pfound = NULL; | 484 | const struct option *pfound = NULL; |
485 | struct option_list | ||
486 | { | ||
487 | const struct option *p; | ||
488 | struct option_list *next; | ||
489 | } *ambig_list = NULL; | ||
484 | int exact = 0; | 490 | int exact = 0; |
485 | int ambig = 0; | ||
486 | int indfound = -1; | 491 | int indfound = -1; |
487 | int option_index; | 492 | int option_index; |
488 | 493 | ||
489 | for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) | 494 | for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) |
490 | /* Do nothing. */ ; | 495 | /* Do nothing. */ ; |
496 | namelen = nameend - d->__nextchar; | ||
491 | 497 | ||
492 | /* Test all long options for either exact match | 498 | /* Test all long options for either exact match |
493 | or abbreviated matches. */ | 499 | or abbreviated matches. */ |
494 | for (p = longopts, option_index = 0; p->name; p++, option_index++) | 500 | for (p = longopts, option_index = 0; p->name; p++, option_index++) |
495 | if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) | 501 | if (!strncmp (p->name, d->__nextchar, namelen)) |
496 | { | 502 | { |
497 | if ((unsigned int) (nameend - d->__nextchar) | 503 | if (namelen == (unsigned int) strlen (p->name)) |
498 | == (unsigned int) strlen (p->name)) | ||
499 | { | 504 | { |
500 | /* Exact match found. */ | 505 | /* Exact match found. */ |
501 | pfound = p; | 506 | pfound = p; |
@@ -513,35 +518,71 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
513 | || pfound->has_arg != p->has_arg | 518 | || pfound->has_arg != p->has_arg |
514 | || pfound->flag != p->flag | 519 | || pfound->flag != p->flag |
515 | || pfound->val != p->val) | 520 | || pfound->val != p->val) |
516 | /* Second or later nonexact match found. */ | 521 | { |
517 | ambig = 1; | 522 | /* Second or later nonexact match found. */ |
523 | struct option_list *newp = malloc (sizeof (*newp)); | ||
524 | newp->p = p; | ||
525 | newp->next = ambig_list; | ||
526 | ambig_list = newp; | ||
527 | } | ||
518 | } | 528 | } |
519 | 529 | ||
520 | if (ambig && !exact) | 530 | if (ambig_list != NULL && !exact) |
521 | { | 531 | { |
522 | if (print_errors) | 532 | if (print_errors) |
523 | { | 533 | { |
534 | struct option_list first; | ||
535 | first.p = pfound; | ||
536 | first.next = ambig_list; | ||
537 | ambig_list = &first; | ||
538 | |||
524 | #if defined _LIBC && defined USE_IN_LIBIO | 539 | #if defined _LIBC && defined USE_IN_LIBIO |
525 | char *buf; | 540 | char *buf = NULL; |
541 | size_t buflen = 0; | ||
526 | 542 | ||
527 | if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"), | 543 | FILE *fp = open_memstream (&buf, &buflen); |
528 | argv[0], argv[d->optind]) >= 0) | 544 | if (fp != NULL) |
529 | { | 545 | { |
530 | _IO_flockfile (stderr); | 546 | fprintf (fp, |
547 | _("%s: option '%s' is ambiguous; possibilities:"), | ||
548 | argv[0], argv[d->optind]); | ||
531 | 549 | ||
532 | int old_flags2 = ((_IO_FILE *) stderr)->_flags2; | 550 | do |
533 | ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; | 551 | { |
552 | fprintf (fp, " '--%s'", ambig_list->p->name); | ||
553 | ambig_list = ambig_list->next; | ||
554 | } | ||
555 | while (ambig_list != NULL); | ||
534 | 556 | ||
535 | __fxprintf (NULL, "%s", buf); | 557 | fputc_unlocked ('\n', fp); |
536 | 558 | ||
537 | ((_IO_FILE *) stderr)->_flags2 = old_flags2; | 559 | if (__builtin_expect (fclose (fp) != EOF, 1)) |
538 | _IO_funlockfile (stderr); | 560 | { |
561 | _IO_flockfile (stderr); | ||
539 | 562 | ||
540 | free (buf); | 563 | int old_flags2 = ((_IO_FILE *) stderr)->_flags2; |
564 | ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; | ||
565 | |||
566 | __fxprintf (NULL, "%s", buf); | ||
567 | |||
568 | ((_IO_FILE *) stderr)->_flags2 = old_flags2; | ||
569 | _IO_funlockfile (stderr); | ||
570 | |||
571 | free (buf); | ||
572 | } | ||
541 | } | 573 | } |
542 | #else | 574 | #else |
543 | fprintf (stderr, _("%s: option '%s' is ambiguous\n"), | 575 | fprintf (stderr, |
576 | _("%s: option '%s' is ambiguous; possibilities:"), | ||
544 | argv[0], argv[d->optind]); | 577 | argv[0], argv[d->optind]); |
578 | do | ||
579 | { | ||
580 | fprintf (stderr, " '--%s'", ambig_list->p->name); | ||
581 | ambig_list = ambig_list->next; | ||
582 | } | ||
583 | while (ambig_list != NULL); | ||
584 | |||
585 | fputc ('\n', stderr); | ||
545 | #endif | 586 | #endif |
546 | } | 587 | } |
547 | d->__nextchar += strlen (d->__nextchar); | 588 | d->__nextchar += strlen (d->__nextchar); |
@@ -550,6 +591,13 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
550 | return '?'; | 591 | return '?'; |
551 | } | 592 | } |
552 | 593 | ||
594 | while (ambig_list != NULL) | ||
595 | { | ||
596 | struct option_list *pn = ambig_list->next; | ||
597 | free (ambig_list); | ||
598 | ambig_list = pn; | ||
599 | } | ||
600 | |||
553 | if (pfound != NULL) | 601 | if (pfound != NULL) |
554 | { | 602 | { |
555 | option_index = indfound; | 603 | option_index = indfound; |
@@ -740,7 +788,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
740 | char c = *d->__nextchar++; | 788 | char c = *d->__nextchar++; |
741 | const char *temp = strchr (optstring, c); | 789 | const char *temp = strchr (optstring, c); |
742 | 790 | ||
743 | /* Increment `optind' when we start to process its last character. */ | 791 | /* Increment 'optind' when we start to process its last character. */ |
744 | if (*d->__nextchar == '\0') | 792 | if (*d->__nextchar == '\0') |
745 | ++d->optind; | 793 | ++d->optind; |
746 | 794 | ||
@@ -791,6 +839,9 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
791 | int indfound = 0; | 839 | int indfound = 0; |
792 | int option_index; | 840 | int option_index; |
793 | 841 | ||
842 | if (longopts == NULL) | ||
843 | goto no_longs; | ||
844 | |||
794 | /* This is an option that requires an argument. */ | 845 | /* This is an option that requires an argument. */ |
795 | if (*d->__nextchar != '\0') | 846 | if (*d->__nextchar != '\0') |
796 | { | 847 | { |
@@ -836,7 +887,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
836 | return c; | 887 | return c; |
837 | } | 888 | } |
838 | else | 889 | else |
839 | /* We already incremented `d->optind' once; | 890 | /* We already incremented 'd->optind' once; |
840 | increment it again when taking next ARGV-elt as argument. */ | 891 | increment it again when taking next ARGV-elt as argument. */ |
841 | d->optarg = argv[d->optind++]; | 892 | d->optarg = argv[d->optind++]; |
842 | 893 | ||
@@ -998,8 +1049,10 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
998 | } | 1049 | } |
999 | return pfound->val; | 1050 | return pfound->val; |
1000 | } | 1051 | } |
1001 | d->__nextchar = NULL; | 1052 | |
1002 | return 'W'; /* Let the application handle it. */ | 1053 | no_longs: |
1054 | d->__nextchar = NULL; | ||
1055 | return 'W'; /* Let the application handle it. */ | ||
1003 | } | 1056 | } |
1004 | if (temp[1] == ':') | 1057 | if (temp[1] == ':') |
1005 | { | 1058 | { |
@@ -1061,7 +1114,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
1061 | c = '?'; | 1114 | c = '?'; |
1062 | } | 1115 | } |
1063 | else | 1116 | else |
1064 | /* We already incremented `optind' once; | 1117 | /* We already incremented 'optind' once; |
1065 | increment it again when taking next ARGV-elt as argument. */ | 1118 | increment it again when taking next ARGV-elt as argument. */ |
1066 | d->optarg = argv[d->optind++]; | 1119 | d->optarg = argv[d->optind++]; |
1067 | d->__nextchar = NULL; | 1120 | d->__nextchar = NULL; |
@@ -1124,7 +1177,7 @@ __posix_getopt (int argc, char *const *argv, const char *optstring) | |||
1124 | #ifdef TEST | 1177 | #ifdef TEST |
1125 | 1178 | ||
1126 | /* Compile with -DTEST to make an executable for use in testing | 1179 | /* Compile with -DTEST to make an executable for use in testing |
1127 | the above definition of `getopt'. */ | 1180 | the above definition of 'getopt'. */ |
1128 | 1181 | ||
1129 | int | 1182 | int |
1130 | main (int argc, char **argv) | 1183 | main (int argc, char **argv) |