1
0
mirror of https://git.savannah.gnu.org/git/gnulib.git synced 2025-08-17 12:41:05 +03:00

getopt-gnu: flush out another BSD bug

POSIX requires 'echo foo > bar; m4 -Dfoo=1 bar -Dfoo=2 bar' to
output '1' then '2'.  To achieve this, m4 relies on the GNU
getopt{,_long} extension of a leading '-'.  However, BSD getopt
fails to honor this extension when POSIXLY_CORRECT.

Also, BSD getopt fails to reparse POSIXLY_CORRECT from the
environment even when a reset is requested (whether by
optreset=1 or by optind=0).

* m4/getopt.m4 (gl_GETOPT_CHECK_HEADERS): Test for the bug.
* tests/test-getopt.c (main): Check POSIXLY_CORRECT first, to
flush out BSD bug.
* tests/test-getopt.h (test_getopt): End lists with NULL.
* tests/test-getopt_long.h (test_getopt_long): Likewise.
(test_getopt_long_posix): Enhance test.
* modules/getopt-posix-tests (Depends-on): Add stdbool.
* doc/glibc-functions/getopt_long.texi (getopt_long): Mention
getopt-gnu.
* doc/glibc-functions/getopt_long_only.texi (getopt_long_only):
Likewise.

Signed-off-by: Eric Blake <ebb9@byu.net>
This commit is contained in:
Eric Blake
2009-11-27 17:47:21 -07:00
parent 6184bd1482
commit c0c5acfbe2
9 changed files with 409 additions and 192 deletions

View File

@@ -1,3 +1,18 @@
2009-11-27 Eric Blake <ebb9@byu.net>
getopt-gnu: flush out another BSD bug
* m4/getopt.m4 (gl_GETOPT_CHECK_HEADERS): Test for the bug.
* tests/test-getopt.c (main): Check POSIXLY_CORRECT first, to
flush out BSD bug.
* tests/test-getopt.h (test_getopt): End lists with NULL.
* tests/test-getopt_long.h (test_getopt_long): Likewise.
(test_getopt_long_posix): Enhance test.
* modules/getopt-posix-tests (Depends-on): Add stdbool.
* doc/glibc-functions/getopt_long.texi (getopt_long): Mention
getopt-gnu.
* doc/glibc-functions/getopt_long_only.texi (getopt_long_only):
Likewise.
2009-11-27 Simon Josefsson <simon@josefsson.org> 2009-11-27 Simon Josefsson <simon@josefsson.org>
* modules/idpriv-droptemp-tests (Notice): Fix text. * modules/idpriv-droptemp-tests (Notice): Fix text.

View File

@@ -2,15 +2,33 @@
@subsection @code{getopt_long} @subsection @code{getopt_long}
@findex getopt_long @findex getopt_long
Gnulib module: --- Gnulib module: getopt-gnu
Portability problems fixed by Gnulib: Portability problems fixed by Gnulib:
@itemize @itemize
@item
The function @code{getopt_long} does not support the @samp{+} flag in
the options string on some platforms:
MacOS X 10.5, AIX 5.2, OSF/1 5.1, Solaris 10.
@item
The function @code{getopt_long} does not obey the @samp{-} flag in the
options string when @env{POSIXLY_CORRECT} is set on some platforms:
Cygwin 1.7.0.
@item
The function @code{getopt_long} does not support options with optional
arguments on some platforms:
MacOS X 10.5, OpenBSD 4.0, AIX 5.2, IRIX 6.5, Solaris 10, Cygwin 1.5.x.
@item
This function is missing on some platforms:
AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Interix 3.5.
@end itemize @end itemize
Portability problems not fixed by Gnulib: Portability problems not fixed by Gnulib:
@itemize @itemize
@item @item
This function is missing on some platforms: The glibc implementation allows a complete reset of the environment,
AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Interix 3.5. including re-checking for @env{POSIXLY_CORRECT}, by setting
@code{optind} to 0. Other implementations provide @code{optreset},
causing a reset by setting it non-zero, although it does not
necessarily re-read @env{POSIXLY_CORRECT}.
@end itemize @end itemize

View File

@@ -2,15 +2,34 @@
@subsection @code{getopt_long_only} @subsection @code{getopt_long_only}
@findex getopt_long_only @findex getopt_long_only
Gnulib module: --- Gnulib module: getopt-gnu
Portability problems fixed by Gnulib: Portability problems fixed by Gnulib:
@itemize @itemize
@item
The function @code{getopt_long_only} does not support the @samp{+}
flag in the options string on some platforms:
MacOS X 10.5, AIX 5.2, OSF/1 5.1, Solaris 10.
@item
The function @code{getopt_long_only} does not obey the @samp{-} flag
in the options string when @env{POSIXLY_CORRECT} is set on some platforms:
Cygwin 1.7.0.
@item
The function @code{getopt_long_only} does not support options with
optional arguments on some platforms:
MacOS X 10.5, OpenBSD 4.0, AIX 5.2, Solaris 10, Cygwin 1.5.x.
@item
This function is missing on some platforms:
MacOS X 10.3, FreeBSD 5.2.1, NetBSD 3.0, AIX 5.1, HP-UX 11, IRIX 6.5,
OSF/1 5.1, mingw, Interix 3.5.
@end itemize @end itemize
Portability problems not fixed by Gnulib: Portability problems not fixed by Gnulib:
@itemize @itemize
@item @item
This function is missing on some platforms: The glibc implementation allows a complete reset of the environment,
MacOS X 10.3, FreeBSD 5.2.1, NetBSD 3.0, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, mingw, Interix 3.5. including re-checking for @env{POSIXLY_CORRECT}, by setting
@code{optind} to 0. Other implementations provide @code{optreset},
causing a reset by setting it non-zero, although it does not
necessarily re-read @env{POSIXLY_CORRECT}.
@end itemize @end itemize

View File

@@ -25,6 +25,10 @@ The function @code{getopt} does not support the @samp{+} flag in the options
string on some platforms: string on some platforms:
MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10. MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10.
@item @item
The function @code{getopt} does not obey the @samp{-} flag in the options
string when @env{POSIXLY_CORRECT} is set on some platforms:
Cygwin 1.7.0.
@item
The function @code{getopt} does not support options with optional arguments The function @code{getopt} does not support options with optional arguments
on some platforms: on some platforms:
MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1,
@@ -32,6 +36,10 @@ Solaris 10, Cygwin 1.5.x.
@item @item
The function @code{getopt_long} is missing on some platforms: The function @code{getopt_long} is missing on some platforms:
AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Interix 3.5. AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Interix 3.5.
@item
The function @code{getopt_long_only} is missing on some platforms:
MacOS X 10.3, FreeBSD 5.2.1, NetBSD 3.0, AIX 5.1, HP-UX 11, IRIX 6.5,
OSF/1 5.1, Solaris 9, mingw, Interix 3.5.
@end itemize @end itemize
Portability problems not fixed by Gnulib: Portability problems not fixed by Gnulib:
@@ -41,8 +49,12 @@ The default behavior of the glibc implementation of @code{getopt} allows
mixing option and non-option arguments on the command line in any order. mixing option and non-option arguments on the command line in any order.
Other implementations, such as the one in Cygwin, enforce strict POSIX Other implementations, such as the one in Cygwin, enforce strict POSIX
compliance: they require that the option arguments precede the non-option compliance: they require that the option arguments precede the non-option
arguments. This is something to watch out in your program's testsuite. arguments. This is something to watch out in your program's
testsuite.
@item @item
The function @code{getopt_long_only} is missing on some platforms: The glibc implementation allows a complete reset of the environment,
MacOS X 10.3, FreeBSD 5.2.1, NetBSD 3.0, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw, Interix 3.5. including re-checking for @env{POSIXLY_CORRECT}, by setting
@code{optind} to 0. Other implementations provide @code{optreset},
causing a reset by setting it non-zero, although it does not
necessarily re-read @env{POSIXLY_CORRECT}.
@end itemize @end itemize

View File

@@ -1,4 +1,4 @@
# getopt.m4 serial 23 # getopt.m4 serial 24
dnl Copyright (C) 2002-2006, 2008-2009 Free Software Foundation, Inc. dnl Copyright (C) 2002-2006, 2008-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@@ -75,11 +75,13 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes]) AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes])
fi fi
dnl BSD getopt_long uses an incompatible method to reset option processing, dnl BSD getopt_long uses an incompatible method to reset option processing.
dnl but the testsuite does not show a need to use this 'optreset' variable. dnl Existence of the variable, in and of itself, is not a reason to replace
if false && test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then dnl getopt, but knowledge of the variable is needed to determine how to
AC_CHECK_DECL([optreset], [gl_replace_getopt=yes], [], dnl reset and whether a reset reparses the environment.
[#include <getopt.h>]) if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
AC_CHECK_DECLS([optreset], [], [],
[[#include <getopt.h>]])
fi fi
dnl mingw's getopt (in libmingwex.a) does weird things when the options dnl mingw's getopt (in libmingwex.a) does weird things when the options
@@ -96,9 +98,7 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
/* The glibc implementation of getopt supports setting optind = 0 as a means #if !HAVE_DECL_OPTRESET
of clearing the internal state, but other implementations don't. */
#if (__GLIBC__ >= 2)
# define OPTIND_MIN 0 # define OPTIND_MIN 0
#else #else
# define OPTIND_MIN 1 # define OPTIND_MIN 1
@@ -116,6 +116,7 @@ main ()
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = OPTIND_MIN; optind = OPTIND_MIN;
opterr = 0; opterr = 0;
@@ -141,6 +142,7 @@ main ()
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = OPTIND_MIN; optind = OPTIND_MIN;
opterr = 0; opterr = 0;
@@ -182,11 +184,22 @@ main ()
if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu], AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu],
[AC_RUN_IFELSE( [# Even with POSIXLY_CORRECT, the GNU extension of leading '-' in the
# optstring is necessary for programs like m4 that have POSIX-mandated
# semantics for supporting options interspersed with files.
gl_had_POSIXLY_CORRECT=${POSIXLY_CORRECT:+yes}
POSIXLY_CORRECT=1
export POSIXLY_CORRECT
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <getopt.h> [AC_LANG_PROGRAM([[#include <getopt.h>
#include <stddef.h> #include <stddef.h>
#include <string.h>]], #include <string.h>
[[ #if !HAVE_DECL_OPTRESET
# define OPTIND_MIN 0
#else
# define OPTIND_MIN (optreset = 1)
#endif
]], [[
/* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw,
and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5,
OSF/1 5.1, Solaris 10. */ OSF/1 5.1, Solaris 10. */
@@ -201,9 +214,9 @@ main ()
} }
/* This code succeeds on glibc 2.8, mingw, /* This code succeeds on glibc 2.8, mingw,
and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin. */ IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */
{ {
char *argv[] = { "program", "-p", "foo", "bar" }; char *argv[] = { "program", "-p", "foo", "bar", NULL };
optind = 1; optind = 1;
if (getopt (4, argv, "p::") != 'p') if (getopt (4, argv, "p::") != 'p')
@@ -215,16 +228,29 @@ main ()
if (optind != 2) if (optind != 2)
return 5; return 5;
} }
/* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */
{
char *argv[] = { "program", "foo", "-p", NULL };
optind = OPTIND_MIN;
if (getopt (3, argv, "-p") != 1)
return 6;
if (getopt (3, argv, "-p") != 'p')
return 7;
}
return 0; return 0;
]])], ]])],
[gl_cv_func_getopt_gnu=yes], [gl_cv_func_getopt_gnu=yes],
[gl_cv_func_getopt_gnu=no], [gl_cv_func_getopt_gnu=no],
[dnl Cross compiling. Guess based on host and declarations. [dnl Cross compiling. Guess based on host and declarations.
case "$host_os" in case $host_os:$ac_cv_have_decl_optreset in
*-gnu* | mingw*) gl_cv_func_getopt_gnu=no;; *-gnu*:* | mingw*:*) gl_cv_func_getopt_gnu=no;;
*) gl_cv_func_getopt_gnu=yes;; *:yes) gl_cv_func_getopt_gnu=no;;
*) gl_cv_func_getopt_gnu=yes;;
esac esac
]) ])
if test "$gl_had_POSIXLY_CORRECT" != yes; then
AS_UNSET([POSIXLY_CORRECT])
fi
]) ])
if test "$gl_cv_func_getopt_gnu" = "no"; then if test "$gl_cv_func_getopt_gnu" = "no"; then
gl_replace_getopt=yes gl_replace_getopt=yes

View File

@@ -5,6 +5,7 @@ tests/test-getopt_long.h
Depends-on: Depends-on:
setenv setenv
stdbool
unistd unistd
unsetenv unsetenv

View File

@@ -55,14 +55,18 @@
int int
main (void) main (void)
{ {
unsetenv ("POSIXLY_CORRECT"); setenv ("POSIXLY_CORRECT", "1", 1);
test_getopt (); test_getopt ();
#if GNULIB_GETOPT_GNU
test_getopt_long_posix ();
#endif
unsetenv ("POSIXLY_CORRECT");
test_getopt ();
#if GNULIB_GETOPT_GNU #if GNULIB_GETOPT_GNU
test_getopt_long (); test_getopt_long ();
setenv ("POSIXLY_CORRECT", "1", 0);
test_getopt_long_posix ();
#endif #endif
return 0; return 0;

View File

@@ -16,6 +16,8 @@
/* Written by Bruno Haible <bruno@clisp.org>, 2009. */ /* Written by Bruno Haible <bruno@clisp.org>, 2009. */
#include <stdbool.h>
static void static void
getopt_loop (int argc, const char **argv, getopt_loop (int argc, const char **argv,
const char *options, const char *options,
@@ -62,6 +64,14 @@ static void
test_getopt (void) test_getopt (void)
{ {
int start; int start;
bool posixly = !!getenv ("POSIXLY_CORRECT");
/* See comment in getopt.c:
glibc gets a LSB-compliant getopt.
Standalone applications get a POSIX-compliant getopt. */
#if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__)
/* Using getopt from gnulib or from a non-glibc system. */
posixly = true;
#endif
/* Test processing of boolean options. */ /* Test processing of boolean options. */
for (start = OPTIND_MIN; start <= 1; start++) for (start = OPTIND_MIN; start <= 1; start++)
@@ -80,6 +90,7 @@ test_getopt (void)
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "ab", getopt_loop (argc, argv, "ab",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -109,6 +120,7 @@ test_getopt (void)
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "ab", getopt_loop (argc, argv, "ab",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -137,6 +149,7 @@ test_getopt (void)
argv[argc++] = "-ba"; argv[argc++] = "-ba";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "ab", getopt_loop (argc, argv, "ab",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -166,6 +179,7 @@ test_getopt (void)
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "ab", getopt_loop (argc, argv, "ab",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -195,6 +209,7 @@ test_getopt (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "-pfoo"; argv[argc++] = "-pfoo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "p:q:", getopt_loop (argc, argv, "p:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -223,6 +238,7 @@ test_getopt (void)
argv[argc++] = "-p"; argv[argc++] = "-p";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "p:q:", getopt_loop (argc, argv, "p:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -253,6 +269,7 @@ test_getopt (void)
argv[argc++] = "baz"; argv[argc++] = "baz";
argv[argc++] = "-pfoo"; argv[argc++] = "-pfoo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "abp:q:", getopt_loop (argc, argv, "abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -283,6 +300,7 @@ test_getopt (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "-pfoo"; argv[argc++] = "-pfoo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "p::q::", getopt_loop (argc, argv, "p::q::",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -311,6 +329,7 @@ test_getopt (void)
argv[argc++] = "-p"; argv[argc++] = "-p";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "p::q::", getopt_loop (argc, argv, "p::q::",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -339,6 +358,7 @@ test_getopt (void)
argv[argc++] = "-p"; argv[argc++] = "-p";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "abp::q::", getopt_loop (argc, argv, "abp::q::",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -372,6 +392,7 @@ test_getopt (void)
argv[argc++] = "-x"; argv[argc++] = "-x";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "abp:q:", getopt_loop (argc, argv, "abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -405,46 +426,47 @@ test_getopt (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "abp:q:", getopt_loop (argc, argv, "abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
&non_options_count, non_options, &unrecognized); &non_options_count, non_options, &unrecognized);
/* See comment in getopt.c: if (posixly)
glibc gets a LSB-compliant getopt. {
Standalone applications get a POSIX-compliant getopt. */ ASSERT (strcmp (argv[0], "program") == 0);
#if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__) ASSERT (strcmp (argv[1], "donald") == 0);
/* Using getopt from gnulib or from a non-glibc system. */ ASSERT (strcmp (argv[2], "-p") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[3], "billy") == 0);
ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[2], "-p") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[3], "billy") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (argv[7] == NULL);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (a_seen == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (b_seen == 0);
ASSERT (a_seen == 0); ASSERT (p_value == NULL);
ASSERT (b_seen == 0); ASSERT (q_value == NULL);
ASSERT (p_value == NULL); ASSERT (non_options_count == 0);
ASSERT (q_value == NULL); ASSERT (unrecognized == 0);
ASSERT (non_options_count == 0); ASSERT (optind == 1);
ASSERT (unrecognized == 0); }
ASSERT (optind == 1); else
#else {
/* Using getopt from glibc. */ ASSERT (strcmp (argv[0], "program") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "-p") == 0);
ASSERT (strcmp (argv[1], "-p") == 0); ASSERT (strcmp (argv[2], "billy") == 0);
ASSERT (strcmp (argv[2], "billy") == 0); ASSERT (strcmp (argv[3], "-a") == 0);
ASSERT (strcmp (argv[3], "-a") == 0); ASSERT (strcmp (argv[4], "donald") == 0);
ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[5], "duck") == 0);
ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
ASSERT (q_value == NULL); ASSERT (q_value == NULL);
ASSERT (non_options_count == 0); ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0); ASSERT (unrecognized == 0);
ASSERT (optind == 4); ASSERT (optind == 4);
#endif }
} }
/* Check that '--' ends the argument processing. */ /* Check that '--' ends the argument processing. */
@@ -472,56 +494,57 @@ test_getopt (void)
argv[argc++] = "-q"; argv[argc++] = "-q";
argv[argc++] = "johnny"; argv[argc++] = "johnny";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "abp:q:", getopt_loop (argc, argv, "abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
&non_options_count, non_options, &unrecognized); &non_options_count, non_options, &unrecognized);
/* See comment in getopt.c: if (posixly)
glibc gets a LSB-compliant getopt. {
Standalone applications get a POSIX-compliant getopt. */ ASSERT (strcmp (argv[0], "program") == 0);
#if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__) ASSERT (strcmp (argv[1], "donald") == 0);
/* Using getopt from gnulib or from a non-glibc system. */ ASSERT (strcmp (argv[2], "-p") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[3], "billy") == 0);
ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[2], "-p") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[3], "billy") == 0); ASSERT (strcmp (argv[6], "--") == 0);
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[7], "-b") == 0);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[8], "foo") == 0);
ASSERT (strcmp (argv[6], "--") == 0); ASSERT (strcmp (argv[9], "-q") == 0);
ASSERT (strcmp (argv[7], "-b") == 0); ASSERT (strcmp (argv[10], "johnny") == 0);
ASSERT (strcmp (argv[8], "foo") == 0); ASSERT (strcmp (argv[11], "bar") == 0);
ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (argv[12] == NULL);
ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (a_seen == 0);
ASSERT (strcmp (argv[11], "bar") == 0); ASSERT (b_seen == 0);
ASSERT (a_seen == 0); ASSERT (p_value == NULL);
ASSERT (b_seen == 0); ASSERT (q_value == NULL);
ASSERT (p_value == NULL); ASSERT (non_options_count == 0);
ASSERT (q_value == NULL); ASSERT (unrecognized == 0);
ASSERT (non_options_count == 0); ASSERT (optind == 1);
ASSERT (unrecognized == 0); }
ASSERT (optind == 1); else
#else {
/* Using getopt from glibc. */ ASSERT (strcmp (argv[0], "program") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "-p") == 0);
ASSERT (strcmp (argv[1], "-p") == 0); ASSERT (strcmp (argv[2], "billy") == 0);
ASSERT (strcmp (argv[2], "billy") == 0); ASSERT (strcmp (argv[3], "-a") == 0);
ASSERT (strcmp (argv[3], "-a") == 0); ASSERT (strcmp (argv[4], "--") == 0);
ASSERT (strcmp (argv[4], "--") == 0); ASSERT (strcmp (argv[5], "donald") == 0);
ASSERT (strcmp (argv[5], "donald") == 0); ASSERT (strcmp (argv[6], "duck") == 0);
ASSERT (strcmp (argv[6], "duck") == 0); ASSERT (strcmp (argv[7], "-b") == 0);
ASSERT (strcmp (argv[7], "-b") == 0); ASSERT (strcmp (argv[8], "foo") == 0);
ASSERT (strcmp (argv[8], "foo") == 0); ASSERT (strcmp (argv[9], "-q") == 0);
ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[10], "johnny") == 0);
ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[11], "bar") == 0);
ASSERT (strcmp (argv[11], "bar") == 0); ASSERT (argv[12] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
ASSERT (q_value == NULL); ASSERT (q_value == NULL);
ASSERT (non_options_count == 0); ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0); ASSERT (unrecognized == 0);
ASSERT (optind == 5); ASSERT (optind == 5);
#endif }
} }
#if GNULIB_GETOPT_GNU #if GNULIB_GETOPT_GNU
@@ -545,6 +568,7 @@ test_getopt (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "-abp:q:", getopt_loop (argc, argv, "-abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -556,6 +580,7 @@ test_getopt (void)
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -593,6 +618,7 @@ test_getopt (void)
argv[argc++] = "-q"; argv[argc++] = "-q";
argv[argc++] = "johnny"; argv[argc++] = "johnny";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "-abp:q:", getopt_loop (argc, argv, "-abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -609,6 +635,7 @@ test_getopt (void)
ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[9], "-q") == 0);
ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[10], "johnny") == 0);
ASSERT (strcmp (argv[11], "bar") == 0); ASSERT (strcmp (argv[11], "bar") == 0);
ASSERT (argv[12] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -659,46 +686,47 @@ test_getopt (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "abp:q:-", getopt_loop (argc, argv, "abp:q:-",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
&non_options_count, non_options, &unrecognized); &non_options_count, non_options, &unrecognized);
/* See comment in getopt.c: if (posixly)
glibc gets a LSB-compliant getopt. {
Standalone applications get a POSIX-compliant getopt. */ ASSERT (strcmp (argv[0], "program") == 0);
#if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__) ASSERT (strcmp (argv[1], "donald") == 0);
/* Using getopt from gnulib or from a non-glibc system. */ ASSERT (strcmp (argv[2], "-p") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[3], "billy") == 0);
ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[2], "-p") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[3], "billy") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (argv[7] == NULL);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (a_seen == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (b_seen == 0);
ASSERT (a_seen == 0); ASSERT (p_value == NULL);
ASSERT (b_seen == 0); ASSERT (q_value == NULL);
ASSERT (p_value == NULL); ASSERT (non_options_count == 0);
ASSERT (q_value == NULL); ASSERT (unrecognized == 0);
ASSERT (non_options_count == 0); ASSERT (optind == 1);
ASSERT (unrecognized == 0); }
ASSERT (optind == 1); else
#else {
/* Using getopt from glibc. */ ASSERT (strcmp (argv[0], "program") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "-p") == 0);
ASSERT (strcmp (argv[1], "-p") == 0); ASSERT (strcmp (argv[2], "billy") == 0);
ASSERT (strcmp (argv[2], "billy") == 0); ASSERT (strcmp (argv[3], "-a") == 0);
ASSERT (strcmp (argv[3], "-a") == 0); ASSERT (strcmp (argv[4], "donald") == 0);
ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[5], "duck") == 0);
ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
ASSERT (q_value == NULL); ASSERT (q_value == NULL);
ASSERT (non_options_count == 0); ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0); ASSERT (unrecognized == 0);
ASSERT (optind == 4); ASSERT (optind == 4);
#endif }
} }
/* Check that the '+' flag causes the first non-option to terminate the /* Check that the '+' flag causes the first non-option to terminate the
@@ -722,6 +750,7 @@ test_getopt (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "+abp:q:", getopt_loop (argc, argv, "+abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -733,6 +762,7 @@ test_getopt (void)
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (argv[7] == NULL);
ASSERT (a_seen == 0); ASSERT (a_seen == 0);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value == NULL); ASSERT (p_value == NULL);
@@ -755,6 +785,7 @@ test_getopt (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "-+"; argv[argc++] = "-+";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "+abp:q:", getopt_loop (argc, argv, "+abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -793,6 +824,7 @@ test_getopt (void)
argv[argc++] = "-q"; argv[argc++] = "-q";
argv[argc++] = "johnny"; argv[argc++] = "johnny";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "+abp:q:", getopt_loop (argc, argv, "+abp:q:",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
@@ -809,6 +841,7 @@ test_getopt (void)
ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[9], "-q") == 0);
ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[10], "johnny") == 0);
ASSERT (strcmp (argv[11], "bar") == 0); ASSERT (strcmp (argv[11], "bar") == 0);
ASSERT (argv[12] == NULL);
ASSERT (a_seen == 0); ASSERT (a_seen == 0);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value == NULL); ASSERT (p_value == NULL);
@@ -838,45 +871,46 @@ test_getopt (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_loop (argc, argv, "abp:q:+", getopt_loop (argc, argv, "abp:q:+",
&a_seen, &b_seen, &p_value, &q_value, &a_seen, &b_seen, &p_value, &q_value,
&non_options_count, non_options, &unrecognized); &non_options_count, non_options, &unrecognized);
/* See comment in getopt.c: if (posixly)
glibc gets a LSB-compliant getopt. {
Standalone applications get a POSIX-compliant getopt. */ ASSERT (strcmp (argv[0], "program") == 0);
#if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__) ASSERT (strcmp (argv[1], "donald") == 0);
/* Using getopt from gnulib or from a non-glibc system. */ ASSERT (strcmp (argv[2], "-p") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[3], "billy") == 0);
ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[2], "-p") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[3], "billy") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (argv[7] == NULL);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (a_seen == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (b_seen == 0);
ASSERT (a_seen == 0); ASSERT (p_value == NULL);
ASSERT (b_seen == 0); ASSERT (q_value == NULL);
ASSERT (p_value == NULL); ASSERT (non_options_count == 0);
ASSERT (q_value == NULL); ASSERT (unrecognized == 0);
ASSERT (non_options_count == 0); ASSERT (optind == 1);
ASSERT (unrecognized == 0); }
ASSERT (optind == 1); else
#else {
/* Using getopt from glibc. */ ASSERT (strcmp (argv[0], "program") == 0);
ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "-p") == 0);
ASSERT (strcmp (argv[1], "-p") == 0); ASSERT (strcmp (argv[2], "billy") == 0);
ASSERT (strcmp (argv[2], "billy") == 0); ASSERT (strcmp (argv[3], "-a") == 0);
ASSERT (strcmp (argv[3], "-a") == 0); ASSERT (strcmp (argv[4], "donald") == 0);
ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[5], "duck") == 0);
ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
ASSERT (q_value == NULL); ASSERT (q_value == NULL);
ASSERT (non_options_count == 0); ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0); ASSERT (unrecognized == 0);
ASSERT (optind == 4); ASSERT (optind == 4);
#endif }
} }
} }

View File

@@ -111,6 +111,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--x"; argv[argc++] = "--x";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -125,6 +126,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xt"; argv[argc++] = "--xt";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -139,6 +141,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xtr"; argv[argc++] = "--xtr";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -153,6 +156,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xtra"; argv[argc++] = "--xtra";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -166,6 +170,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xtre"; argv[argc++] = "--xtre";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -180,6 +185,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xtrem"; argv[argc++] = "--xtrem";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -194,6 +200,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xtreme"; argv[argc++] = "--xtreme";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -207,6 +214,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xtremel"; argv[argc++] = "--xtremel";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -220,6 +228,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "--xtremely"; argv[argc++] = "--xtremely";
argv[argc] = NULL;
optind = 1; optind = 1;
opterr = 0; opterr = 0;
c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index); c = do_getopt_long (argc, argv, "ab", long_options_required, &option_index);
@@ -243,6 +252,7 @@ test_getopt_long (void)
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "ab", long_options_required, getopt_long_loop (argc, argv, "ab", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -272,6 +282,7 @@ test_getopt_long (void)
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "ab", long_options_required, getopt_long_loop (argc, argv, "ab", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -300,6 +311,7 @@ test_getopt_long (void)
argv[argc++] = "-ba"; argv[argc++] = "-ba";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "ab", long_options_required, getopt_long_loop (argc, argv, "ab", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -329,6 +341,7 @@ test_getopt_long (void)
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "ab", long_options_required, getopt_long_loop (argc, argv, "ab", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -358,6 +371,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "-pfoo"; argv[argc++] = "-pfoo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "p:q:", long_options_required, getopt_long_loop (argc, argv, "p:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -386,6 +400,7 @@ test_getopt_long (void)
argv[argc++] = "-p"; argv[argc++] = "-p";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "p:q:", long_options_required, getopt_long_loop (argc, argv, "p:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -416,6 +431,7 @@ test_getopt_long (void)
argv[argc++] = "baz"; argv[argc++] = "baz";
argv[argc++] = "-pfoo"; argv[argc++] = "-pfoo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "abp:q:", long_options_required, getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -445,6 +461,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "-pfoo"; argv[argc++] = "-pfoo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "p::q::", long_options_optional, getopt_long_loop (argc, argv, "p::q::", long_options_optional,
&p_value, &q_value, &p_value, &q_value,
@@ -473,6 +490,7 @@ test_getopt_long (void)
argv[argc++] = "-p"; argv[argc++] = "-p";
argv[argc++] = "foo"; argv[argc++] = "foo";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "p::q::", long_options_optional, getopt_long_loop (argc, argv, "p::q::", long_options_optional,
&p_value, &q_value, &p_value, &q_value,
@@ -501,6 +519,7 @@ test_getopt_long (void)
argv[argc++] = "-p"; argv[argc++] = "-p";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "abp::q::", long_options_optional, getopt_long_loop (argc, argv, "abp::q::", long_options_optional,
&p_value, &q_value, &p_value, &q_value,
@@ -533,6 +552,7 @@ test_getopt_long (void)
argv[argc++] = "-x"; argv[argc++] = "-x";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "abp:q:", long_options_required, getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -566,6 +586,7 @@ test_getopt_long (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "abp:q:", long_options_required, getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -577,6 +598,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[4], "donald") == 0);
ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[5], "duck") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -611,6 +633,7 @@ test_getopt_long (void)
argv[argc++] = "-q"; argv[argc++] = "-q";
argv[argc++] = "johnny"; argv[argc++] = "johnny";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "abp:q:", long_options_required, getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -627,6 +650,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[9], "-q") == 0);
ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[10], "johnny") == 0);
ASSERT (strcmp (argv[11], "bar") == 0); ASSERT (strcmp (argv[11], "bar") == 0);
ASSERT (argv[12] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -656,6 +680,7 @@ test_getopt_long (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "-abp:q:", long_options_required, getopt_long_loop (argc, argv, "-abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -667,6 +692,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -704,6 +730,7 @@ test_getopt_long (void)
argv[argc++] = "-q"; argv[argc++] = "-q";
argv[argc++] = "johnny"; argv[argc++] = "johnny";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "-abp:q:", long_options_required, getopt_long_loop (argc, argv, "-abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -720,6 +747,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[9], "-q") == 0);
ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[10], "johnny") == 0);
ASSERT (strcmp (argv[11], "bar") == 0); ASSERT (strcmp (argv[11], "bar") == 0);
ASSERT (argv[12] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -769,6 +797,7 @@ test_getopt_long (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "abp:q:-", long_options_required, getopt_long_loop (argc, argv, "abp:q:-", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -780,6 +809,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[4], "donald") == 0);
ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[5], "duck") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -810,6 +840,7 @@ test_getopt_long (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "+abp:q:", long_options_required, getopt_long_loop (argc, argv, "+abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -821,6 +852,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[4], "duck") == 0);
ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[5], "-a") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (argv[7] == NULL);
ASSERT (a_seen == 0); ASSERT (a_seen == 0);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value == NULL); ASSERT (p_value == NULL);
@@ -843,6 +875,7 @@ test_getopt_long (void)
argv[argc++] = "program"; argv[argc++] = "program";
argv[argc++] = "-+"; argv[argc++] = "-+";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "+abp:q:", long_options_required, getopt_long_loop (argc, argv, "+abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -881,6 +914,7 @@ test_getopt_long (void)
argv[argc++] = "-q"; argv[argc++] = "-q";
argv[argc++] = "johnny"; argv[argc++] = "johnny";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "+abp:q:", long_options_required, getopt_long_loop (argc, argv, "+abp:q:", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -897,6 +931,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[9], "-q") == 0);
ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[10], "johnny") == 0);
ASSERT (strcmp (argv[11], "bar") == 0); ASSERT (strcmp (argv[11], "bar") == 0);
ASSERT (argv[12] == NULL);
ASSERT (a_seen == 0); ASSERT (a_seen == 0);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value == NULL); ASSERT (p_value == NULL);
@@ -926,6 +961,7 @@ test_getopt_long (void)
argv[argc++] = "duck"; argv[argc++] = "duck";
argv[argc++] = "-a"; argv[argc++] = "-a";
argv[argc++] = "bar"; argv[argc++] = "bar";
argv[argc] = NULL;
optind = start; optind = start;
getopt_long_loop (argc, argv, "abp:q:+", long_options_required, getopt_long_loop (argc, argv, "abp:q:+", long_options_required,
&p_value, &q_value, &p_value, &q_value,
@@ -937,6 +973,7 @@ test_getopt_long (void)
ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[4], "donald") == 0);
ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[5], "duck") == 0);
ASSERT (strcmp (argv[6], "bar") == 0); ASSERT (strcmp (argv[6], "bar") == 0);
ASSERT (argv[7] == NULL);
ASSERT (a_seen == 1); ASSERT (a_seen == 1);
ASSERT (b_seen == 0); ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
@@ -954,16 +991,67 @@ test_getopt_long (void)
static void static void
test_getopt_long_posix (void) test_getopt_long_posix (void)
{ {
int c = 3;
const char *v[4] = {"test", "-r", "foo", NULL};
struct option l[] = {{NULL, 0, NULL, 0}};
int start; int start;
int result;
/* Check that POSIXLY_CORRECT doesn't change optional arguments. */
for (start = OPTIND_MIN; start <= 1; start++) for (start = OPTIND_MIN; start <= 1; start++)
{ {
const char *p_value = NULL;
const char *q_value = NULL;
int non_options_count = 0;
const char *non_options[10];
int unrecognized = 0;
int argc = 0;
const char *argv[10];
a_seen = 0;
b_seen = 0;
argv[argc++] = "program";
argv[argc++] = "-p";
argv[argc++] = "billy";
argv[argc] = NULL;
optind = start; optind = start;
result = do_getopt_long (c, v, "r::", l, NULL); getopt_long_loop (argc, argv, "p::", long_options_required,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
ASSERT (a_seen == 0);
ASSERT (b_seen == 0);
ASSERT (p_value == NULL);
ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0);
ASSERT (optind == 2);
}
/* Check that leading - still sees options after non-options. */
for (start = OPTIND_MIN; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
int non_options_count = 0;
const char *non_options[10];
int unrecognized = 0;
int argc = 0;
const char *argv[10];
a_seen = 0;
b_seen = 0;
argv[argc++] = "program";
argv[argc++] = "-a";
argv[argc++] = "billy";
argv[argc++] = "-b";
argv[argc] = NULL;
optind = start;
getopt_long_loop (argc, argv, "-ab", long_options_required,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
ASSERT (a_seen == 1);
ASSERT (b_seen == 1);
ASSERT (p_value == NULL);
ASSERT (q_value == NULL);
ASSERT (non_options_count == 1);
ASSERT (strcmp (non_options[0], "billy") == 0);
ASSERT (unrecognized == 0);
ASSERT (optind == 4);
} }
ASSERT (result == 'r');
ASSERT (optarg == NULL);
} }