From a19298ed002eb20d91c37fd5067de18466211f83 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 16 Mar 2012 15:25:40 +0200 Subject: Sync from GLIBC. --- getopt.c | 118 +++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 85 insertions(+), 33 deletions(-) (limited to 'getopt.c') diff --git a/getopt.c b/getopt.c index 6521f48e..c539e3d7 100644 --- a/getopt.c +++ b/getopt.c @@ -2,7 +2,7 @@ NOTE: getopt is part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! - Copyright (C) 1987-1996,1998-2004,2008,2009,2010 + Copyright (C) 1987-1996,1998-2004,2008,2009,2010,2011 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,9 +17,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ + License along with the GNU C Library; if not, see + . */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ @@ -74,7 +73,7 @@ # define _(msgid) gettext (msgid) #endif -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC # include #endif @@ -526,23 +525,29 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, || !strchr (optstring, argv[d->optind][1]))))) { char *nameend; + unsigned int namelen; const struct option *p; const struct option *pfound = NULL; + struct option_list + { + const struct option *p; + struct option_list *next; + int needs_free; + } *ambig_list = NULL; int exact = 0; - int ambig = 0; int indfound = -1; int option_index; for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; + namelen = nameend - d->__nextchar; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) + if (!strncmp (p->name, d->__nextchar, namelen)) { - if ((unsigned int) (nameend - d->__nextchar) - == (unsigned int) strlen (p->name)) + if (namelen == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; @@ -560,19 +565,46 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) + { /* Second or later nonexact match found. */ - ambig = 1; + struct option_list *newp = malloc (sizeof (*newp)); + newp->p = p; + newp->needs_free = 1; + newp->next = ambig_list; + ambig_list = newp; + } } - if (ambig && !exact) + if (ambig_list != NULL && !exact) { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; + struct option_list first; + first.p = pfound; + first.next = ambig_list; + ambig_list = &first; - if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) +#if defined _LIBC + char *buf = NULL; + size_t buflen = 0; + + FILE *fp = open_memstream (&buf, &buflen); + if (fp != NULL) + { + fprintf (fp, + _("%s: option '%s' is ambiguous; possibilities:"), + argv[0], argv[d->optind]); + + do + { + fprintf (fp, " '--%s'", ambig_list->p->name); + ambig_list = ambig_list->next; + } + while (ambig_list != NULL); + + fputc_unlocked ('\n', fp); + + if (__builtin_expect (fclose (fp) != EOF, 1)) { _IO_flockfile (stderr); @@ -586,9 +618,24 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, free (buf); } + } #else - fprintf (stderr, _("%s: option '%s' is ambiguous\n"), + fprintf (stderr, + _("%s: option '%s' is ambiguous; possibilities:"), argv[0], argv[d->optind]); + do + { + struct option_list *tmp_next; + + fprintf (stderr, " '--%s'", ambig_list->p->name); + tmp_next = ambig_list->next; + if (ambig_list->needs_free) + free(ambig_list); + ambig_list = tmp_next; + } + while (ambig_list != NULL); + + fputc ('\n', stderr); #endif } d->__nextchar += strlen (d->__nextchar); @@ -611,7 +658,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; int n; #endif @@ -619,7 +666,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, if (argv[d->optind - 1][1] == '-') { /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC n = __asprintf (&buf, _("\ %s: option '--%s' doesn't allow an argument\n"), argv[0], pfound->name); @@ -632,7 +679,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, else { /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC n = __asprintf (&buf, _("\ %s: option '%c%s' doesn't allow an argument\n"), argv[0], argv[d->optind - 1][0], @@ -645,7 +692,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, #endif } -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC if (n >= 0) { _IO_flockfile (stderr); @@ -678,7 +725,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; if (__asprintf (&buf, _("\ @@ -729,7 +776,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; int n; #endif @@ -737,7 +784,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, if (argv[d->optind][1] == '-') { /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), argv[0], d->__nextchar); #else @@ -748,7 +795,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, else { /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), argv[0], argv[d->optind][0], d->__nextchar); #else @@ -757,7 +804,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, #endif } -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC if (n >= 0) { _IO_flockfile (stderr); @@ -795,19 +842,19 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; int n; #endif -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), argv[0], c); #else fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); #endif -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC if (n >= 0) { _IO_flockfile (stderr); @@ -830,6 +877,9 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { + if (longopts == NULL) + goto no_longs; + char *nameend; const struct option *p; const struct option *pfound = NULL; @@ -850,7 +900,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; if (__asprintf (&buf, @@ -924,7 +974,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), @@ -964,7 +1014,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; if (__asprintf (&buf, _("\ @@ -1003,7 +1053,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; if (__asprintf (&buf, _("\ @@ -1045,6 +1095,8 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, } return pfound->val; } + + no_longs: d->__nextchar = NULL; return 'W'; /* Let the application handle it. */ } @@ -1076,7 +1128,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC && defined USE_IN_LIBIO +#if defined _LIBC char *buf; if (__asprintf (&buf, _("\ -- cgit v1.2.3 From 366e06bf71b500939fa3a70e3cce91d9a7776e14 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 20 Mar 2012 20:37:26 +0200 Subject: Make getopt always compile, fix C89 issues. --- getopt.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'getopt.c') diff --git a/getopt.c b/getopt.c index c539e3d7..c5c72a23 100644 --- a/getopt.c +++ b/getopt.c @@ -48,6 +48,11 @@ # endif #endif +/* !@#$%^&*() !!!!!!!! */ +#ifdef GAWK +#undef ELIDE_CODE +#endif + #ifndef ELIDE_CODE @@ -582,6 +587,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, struct option_list first; first.p = pfound; first.next = ambig_list; + first.needs_free = 0; ambig_list = &first; #if defined _LIBC @@ -877,9 +883,6 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { - if (longopts == NULL) - goto no_longs; - char *nameend; const struct option *p; const struct option *pfound = NULL; @@ -888,6 +891,9 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, int indfound = 0; int option_index; + if (longopts == NULL) + goto no_longs; + /* This is an option that requires an argument. */ if (*d->__nextchar != '\0') { -- cgit v1.2.3 From 42b4bf2e5656427243f63bc7174cc7eddf1faa9c Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 21 Mar 2012 22:20:19 +0200 Subject: Minor getopt fix for cygwin and NEWS update. --- getopt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'getopt.c') diff --git a/getopt.c b/getopt.c index c5c72a23..b1f854af 100644 --- a/getopt.c +++ b/getopt.c @@ -58,9 +58,9 @@ /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ +#if defined (__GNU_LIBRARY__) || defined (__CYGWIN__) +/* Don't include stdlib.h for non-GNU C libraries and non-Cygwin because some + of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ -- cgit v1.2.3 From 089476b5415e9844175a2fbf1bde6faf18ae0b61 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 28 Mar 2012 21:45:38 +0200 Subject: Additional getopt fix, for DJGPP this time. --- getopt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'getopt.c') diff --git a/getopt.c b/getopt.c index b1f854af..58df01a0 100644 --- a/getopt.c +++ b/getopt.c @@ -58,9 +58,12 @@ /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ -#if defined (__GNU_LIBRARY__) || defined (__CYGWIN__) -/* Don't include stdlib.h for non-GNU C libraries and non-Cygwin because some - of them contain conflicting prototypes for getopt. */ +#if defined (__GNU_LIBRARY__) || defined (__CYGWIN__) || defined(DJGPP) +/* Don't include stdlib.h for + * non-GNU C libraries + * non-Cygwin + * non-DJGPP + * because some of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ -- cgit v1.2.3