summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2013-06-25 14:48:10 -0700
committerElliott Hughes <enh@google.com>2013-06-25 14:56:17 -0700
commitd278b828fef47fb2d7098f8ec70867fbd3da09d6 (patch)
tree428a7092fb0485245959068f1b9328f863fe02db
parentc76550b3377f50a2bc53536e2713e14edc8dbeac (diff)
downloadbionic-d278b828fef47fb2d7098f8ec70867fbd3da09d6.zip
bionic-d278b828fef47fb2d7098f8ec70867fbd3da09d6.tar.gz
bionic-d278b828fef47fb2d7098f8ec70867fbd3da09d6.tar.bz2
Switch to current upstream getopt_long.
Change-Id: I4c646dcb8be9e88dd54d069a03bbc5fbfd92de03
-rw-r--r--libc/Android.mk2
-rw-r--r--libc/NOTICE7
-rw-r--r--libc/include/getopt.h44
-rw-r--r--libc/upstream-freebsd/freebsd-compat.h1
-rw-r--r--libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c (renamed from libc/unistd/getopt_long.c)187
5 files changed, 152 insertions, 89 deletions
diff --git a/libc/Android.mk b/libc/Android.mk
index 04741be..b239b74 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -9,7 +9,6 @@ libc_common_src_files := \
unistd/alarm.c \
unistd/exec.c \
unistd/fnmatch.c \
- unistd/getopt_long.c \
unistd/syslog.c \
unistd/system.c \
unistd/time.c \
@@ -279,6 +278,7 @@ libc_upstream_freebsd_src_files := \
upstream-freebsd/lib/libc/stdio/tempnam.c \
upstream-freebsd/lib/libc/stdio/tmpnam.c \
upstream-freebsd/lib/libc/stdio/wsetup.c \
+ upstream-freebsd/lib/libc/stdlib/getopt_long.c \
upstream-freebsd/lib/libc/stdlib/qsort.c \
upstream-freebsd/lib/libc/stdlib/realpath.c \
upstream-freebsd/lib/libc/string/wcpcpy.c \
diff --git a/libc/NOTICE b/libc/NOTICE
index 2937518..f31d2f6 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -3060,13 +3060,6 @@ are met:
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by the NetBSD
- Foundation, Inc. and its contributors.
-4. Neither the name of The NetBSD Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index 56f1983..4451941 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: getopt.h,v 1.1 2002/12/03 20:24:29 millert Exp $ */
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
+/* $FreeBSD$ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -16,13 +16,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -43,7 +36,8 @@
#include <sys/cdefs.h>
/*
- * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
+ * GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension.
+ * getopt() is declared here too for GNU programs.
*/
#define no_argument 0
#define required_argument 1
@@ -64,26 +58,20 @@ struct option {
};
__BEGIN_DECLS
-int getopt_long(int, char * const *, const char *,
- const struct option *, int *);
-int getopt_long_only(int, char * const *, const char *,
- const struct option *, int *);
-#ifndef _GETOPT_DEFINED_
-#define _GETOPT_DEFINED_
-int getopt(int, char * const *, const char *);
-
-
-extern char *optarg; /* getopt(3) external variables */
-extern int opterr;
-extern int optind;
-extern int optopt;
-extern int optreset;
-
-#if 0 /* MISSING FROM BIONIC */
-int getsubopt(char **, char * const *, char **);
-extern char *suboptarg; /* getsubopt(3) external variable */
-#endif /* MISSING */
+int getopt_long(int, char * const *, const char *,
+ const struct option *, int *);
+int getopt_long_only(int, char * const *, const char *,
+ const struct option *, int *);
+#ifndef _GETOPT_DECLARED
+#define _GETOPT_DECLARED
+int getopt(int, char * const [], const char *);
+extern char *optarg; /* getopt(3) external variables */
+extern int optind, opterr, optopt;
+#endif
+#ifndef _OPTRESET_DECLARED
+#define _OPTRESET_DECLARED
+extern int optreset; /* getopt(3) external variable */
#endif
__END_DECLS
diff --git a/libc/upstream-freebsd/freebsd-compat.h b/libc/upstream-freebsd/freebsd-compat.h
index 5298663..8030eea 100644
--- a/libc/upstream-freebsd/freebsd-compat.h
+++ b/libc/upstream-freebsd/freebsd-compat.h
@@ -18,6 +18,7 @@
#define _BIONIC_FREEBSD_COMPAT_H_included
#define __USE_BSD
+#define REPLACE_GETOPT
#define _close close
#define _fcntl fcntl
diff --git a/libc/unistd/getopt_long.c b/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
index dbdf01a..9f7f6d5 100644
--- a/libc/unistd/getopt_long.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getopt_long.c,v 1.20 2005/10/25 15:49:37 jmc Exp $ */
+/* $OpenBSD: getopt_long.c,v 1.22 2006/10/04 21:29:04 jmc Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
@@ -35,13 +35,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -56,22 +49,33 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
+#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */
+
+#if 0 /* we prefer to keep our getopt(3) */
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
+#endif
#ifdef REPLACE_GETOPT
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
+int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#endif
-int optreset; /* reset getopt */
#define PRINT_ERROR ((opterr) && (*options != ':'))
@@ -86,10 +90,17 @@ int optreset; /* reset getopt */
#define EMSG ""
+#ifdef GNU_COMPATIBLE
+#define NO_PREFIX (-1)
+#define D_PREFIX 0
+#define DD_PREFIX 1
+#define W_PREFIX 2
+#endif
+
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
- const struct option *, int *, int);
+ const struct option *, int *, int, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
@@ -101,11 +112,21 @@ static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
+static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */
+#ifdef GNU_COMPATIBLE
+static int dash_prefix = NO_PREFIX;
+static const char gnuoptchar[] = "invalid option -- %c";
+
+static const char recargstring[] = "option `%s%s' requires an argument";
+static const char ambig[] = "option `%s%.*s' is ambiguous";
+static const char noarg[] = "option `%s%.*s' doesn't allow an argument";
+static const char illoptstring[] = "unrecognized option `%s%s'";
+#else
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
-static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
+#endif
/*
* Compute the greatest common divisor of a and b.
@@ -169,14 +190,35 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,
*/
static int
parse_long_options(char * const *nargv, const char *options,
- const struct option *long_options, int *idx, int short_too)
+ const struct option *long_options, int *idx, int short_too, int flags)
{
char *current_argv, *has_equal;
+#ifdef GNU_COMPATIBLE
+ char *current_dash;
+#endif
size_t current_argv_len;
- int i, match;
+ int i, match, exact_match, second_partial_match;
current_argv = place;
+#ifdef GNU_COMPATIBLE
+ switch (dash_prefix) {
+ case D_PREFIX:
+ current_dash = "-";
+ break;
+ case DD_PREFIX:
+ current_dash = "--";
+ break;
+ case W_PREFIX:
+ current_dash = "-W ";
+ break;
+ default:
+ current_dash = "";
+ break;
+ }
+#endif
match = -1;
+ exact_match = 0;
+ second_partial_match = 0;
optind++;
@@ -196,6 +238,7 @@ parse_long_options(char * const *nargv, const char *options,
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
+ exact_match = 1;
break;
}
/*
@@ -205,25 +248,37 @@ parse_long_options(char * const *nargv, const char *options,
if (short_too && current_argv_len == 1)
continue;
- if (match == -1) /* partial match */
+ if (match == -1) /* first partial match */
match = i;
- else {
- /* ambiguous abbreviation */
- if (PRINT_ERROR)
- fprintf(stderr,
- ambig, (int)current_argv_len,
- current_argv);
- optopt = 0;
- return (BADCH);
- }
+ else if ((flags & FLAG_LONGONLY) ||
+ long_options[i].has_arg !=
+ long_options[match].has_arg ||
+ long_options[i].flag != long_options[match].flag ||
+ long_options[i].val != long_options[match].val)
+ second_partial_match = 1;
+ }
+ if (!exact_match && second_partial_match) {
+ /* ambiguous abbreviation */
+ if (PRINT_ERROR)
+ warnx(ambig,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ (int)current_argv_len,
+ current_argv);
+ optopt = 0;
+ return (BADCH);
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
- fprintf(stderr,
- noarg, (int)current_argv_len,
- current_argv);
+ warnx(noarg,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ (int)current_argv_len,
+ current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
@@ -231,7 +286,11 @@ parse_long_options(char * const *nargv, const char *options,
optopt = long_options[match].val;
else
optopt = 0;
+#ifdef GNU_COMPATIBLE
+ return (BADCH);
+#else
return (BADARG);
+#endif
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
@@ -252,9 +311,11 @@ parse_long_options(char * const *nargv, const char *options,
* should be generated.
*/
if (PRINT_ERROR)
- fprintf(stderr,
- recargstring,
- current_argv);
+ warnx(recargstring,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
@@ -271,7 +332,11 @@ parse_long_options(char * const *nargv, const char *options,
return (-1);
}
if (PRINT_ERROR)
- fprintf(stderr, illoptstring, current_argv);
+ warnx(illoptstring,
+#ifdef GNU_COMPATIBLE
+ current_dash,
+#endif
+ current_argv);
optopt = 0;
return (BADCH);
}
@@ -294,7 +359,7 @@ getopt_internal(int nargc, char * const *nargv, const char *options,
{
char *oli; /* option letter list index */
int optchar, short_too;
- static int posixly_correct = -1;
+ int posixly_correct; /* no static, can be changed on the fly */
if (options == NULL)
return (-1);
@@ -303,12 +368,18 @@ getopt_internal(int nargc, char * const *nargv, const char *options,
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*/
- if (posixly_correct == -1)
- posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+ posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+#ifdef GNU_COMPATIBLE
+ if (*options == '-')
+ flags |= FLAG_ALLARGS;
+ else if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+#else
if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
else if (*options == '-')
flags |= FLAG_ALLARGS;
+#endif
if (*options == '+' || *options == '-')
options++;
@@ -344,7 +415,11 @@ start:
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
+#ifdef GNU_COMPATIBLE
+ place[1] == '\0') {
+#else
(place[1] == '\0' && strchr(options, '-') == NULL)) {
+#endif
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
@@ -407,20 +482,26 @@ start:
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
- if (*place == '-')
+#ifdef GNU_COMPATIBLE
+ dash_prefix = D_PREFIX;
+#endif
+ if (*place == '-') {
place++; /* --foo long option */
- else if (*place != ':' && strchr(options, *place) != NULL)
+#ifdef GNU_COMPATIBLE
+ dash_prefix = DD_PREFIX;
+#endif
+ } else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
- idx, short_too);
+ idx, short_too, flags);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
- if (((optchar = (int)*place++) == (int)':') ||
+ if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = strchr(options, optchar)) == NULL) {
/*
@@ -432,8 +513,14 @@ start:
return (-1);
if (!*place)
++optind;
+#ifdef GNU_COMPATIBLE
if (PRINT_ERROR)
- fprintf(stderr, illoptchar, optchar);
+ warnx(posixly_correct ? illoptchar : gnuoptchar,
+ optchar);
+#else
+ if (PRINT_ERROR)
+ warnx(illoptchar, optchar);
+#endif
optopt = optchar;
return (BADCH);
}
@@ -444,13 +531,16 @@ start:
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
- fprintf(stderr, recargchar, optchar);
+ warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
+#ifdef GNU_COMPATIBLE
+ dash_prefix = W_PREFIX;
+#endif
optchar = parse_long_options(nargv, options, long_options,
- idx, 0);
+ idx, 0, flags);
place = EMSG;
return (optchar);
}
@@ -461,24 +551,15 @@ start:
optarg = NULL;
if (*place) /* no white space */
optarg = place;
- /* XXX: disable test for :: if PC? (GNU doesn't) */
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
- fprintf(stderr, recargchar, optchar);
+ warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
- } else if (!(flags & FLAG_PERMUTE)) {
- /*
- * If permutation is disabled, we can accept an
- * optional arg separated by whitespace so long
- * as it does not start with a dash (-).
- */
- if (optind + 1 < nargc && *nargv[optind + 1] != '-')
- optarg = nargv[++optind];
}
place = EMSG;
++optind;
@@ -516,7 +597,7 @@ getopt(int nargc, char * const *nargv, const char *options)
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
- const struct option *long_options, int *idx)
+ const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
@@ -529,7 +610,7 @@ getopt_long(int nargc, char * const *nargv, const char *options,
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
- const struct option *long_options, int *idx)
+ const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,