From c0c5acfbe255f5542bc1c81c7aec223d95e504a6 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 27 Nov 2009 17:47:21 -0700 Subject: [PATCH] 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 --- ChangeLog | 15 ++ doc/glibc-functions/getopt_long.texi | 24 ++- doc/glibc-functions/getopt_long_only.texi | 25 ++- doc/posix-functions/getopt.texi | 18 +- m4/getopt.m4 | 60 ++++-- modules/getopt-posix-tests | 1 + tests/test-getopt.c | 12 +- tests/test-getopt.h | 342 ++++++++++++++++-------------- tests/test-getopt_long.h | 102 ++++++++- 9 files changed, 408 insertions(+), 191 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05c7c46c8..036bf072a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-11-27 Eric Blake + + 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 * modules/idpriv-droptemp-tests (Notice): Fix text. diff --git a/doc/glibc-functions/getopt_long.texi b/doc/glibc-functions/getopt_long.texi index 6a0935188..c9843ea50 100644 --- a/doc/glibc-functions/getopt_long.texi +++ b/doc/glibc-functions/getopt_long.texi @@ -2,15 +2,33 @@ @subsection @code{getopt_long} @findex getopt_long -Gnulib module: --- +Gnulib module: getopt-gnu Portability problems fixed by Gnulib: @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 Portability problems not fixed by Gnulib: @itemize @item -This function is missing on some platforms: -AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Interix 3.5. +The glibc implementation allows a complete reset of the environment, +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 diff --git a/doc/glibc-functions/getopt_long_only.texi b/doc/glibc-functions/getopt_long_only.texi index c257b3650..ed6cd7bad 100644 --- a/doc/glibc-functions/getopt_long_only.texi +++ b/doc/glibc-functions/getopt_long_only.texi @@ -2,15 +2,34 @@ @subsection @code{getopt_long_only} @findex getopt_long_only -Gnulib module: --- +Gnulib module: getopt-gnu Portability problems fixed by Gnulib: @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 Portability problems not fixed by Gnulib: @itemize @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. +The glibc implementation allows a complete reset of the environment, +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 diff --git a/doc/posix-functions/getopt.texi b/doc/posix-functions/getopt.texi index 004b6e89a..85f5289f1 100644 --- a/doc/posix-functions/getopt.texi +++ b/doc/posix-functions/getopt.texi @@ -25,6 +25,10 @@ The function @code{getopt} does not support the @samp{+} flag in the options string on some platforms: MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10. @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 on some platforms: 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 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. +@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 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. Other implementations, such as the one in Cygwin, enforce strict POSIX 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 -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. +The glibc implementation allows a complete reset of the environment, +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 diff --git a/m4/getopt.m4 b/m4/getopt.m4 index 8f0c36c51..264b57f9f 100644 --- a/m4/getopt.m4 +++ b/m4/getopt.m4 @@ -1,4 +1,4 @@ -# getopt.m4 serial 23 +# getopt.m4 serial 24 dnl Copyright (C) 2002-2006, 2008-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation 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]) fi - 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. - if false && test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then - AC_CHECK_DECL([optreset], [gl_replace_getopt=yes], [], - [#include ]) + dnl BSD getopt_long uses an incompatible method to reset option processing. + dnl Existence of the variable, in and of itself, is not a reason to replace + dnl getopt, but knowledge of the variable is needed to determine how to + dnl reset and whether a reset reparses the environment. + if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then + AC_CHECK_DECLS([optreset], [], [], + [[#include ]]) fi dnl mingw's getopt (in libmingwex.a) does weird things when the options @@ -96,9 +98,7 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS], #include #include -/* The glibc implementation of getopt supports setting optind = 0 as a means - of clearing the internal state, but other implementations don't. */ -#if (__GLIBC__ >= 2) +#if !HAVE_DECL_OPTRESET # define OPTIND_MIN 0 #else # define OPTIND_MIN 1 @@ -116,6 +116,7 @@ main () argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = OPTIND_MIN; opterr = 0; @@ -141,6 +142,7 @@ main () argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = OPTIND_MIN; opterr = 0; @@ -182,11 +184,22 @@ main () 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_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 #include - #include ]], - [[ + #include +#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, and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10. */ @@ -201,9 +214,9 @@ main () } /* This code succeeds on glibc 2.8, mingw, 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; if (getopt (4, argv, "p::") != 'p') @@ -215,16 +228,29 @@ main () if (optind != 2) 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; ]])], [gl_cv_func_getopt_gnu=yes], [gl_cv_func_getopt_gnu=no], [dnl Cross compiling. Guess based on host and declarations. - case "$host_os" in - *-gnu* | mingw*) gl_cv_func_getopt_gnu=no;; - *) gl_cv_func_getopt_gnu=yes;; + case $host_os:$ac_cv_have_decl_optreset in + *-gnu*:* | mingw*:*) gl_cv_func_getopt_gnu=no;; + *:yes) gl_cv_func_getopt_gnu=no;; + *) gl_cv_func_getopt_gnu=yes;; esac ]) + if test "$gl_had_POSIXLY_CORRECT" != yes; then + AS_UNSET([POSIXLY_CORRECT]) + fi ]) if test "$gl_cv_func_getopt_gnu" = "no"; then gl_replace_getopt=yes diff --git a/modules/getopt-posix-tests b/modules/getopt-posix-tests index 3499b5a3e..be828cfee 100644 --- a/modules/getopt-posix-tests +++ b/modules/getopt-posix-tests @@ -5,6 +5,7 @@ tests/test-getopt_long.h Depends-on: setenv +stdbool unistd unsetenv diff --git a/tests/test-getopt.c b/tests/test-getopt.c index 6c59d4753..cc87f3272 100644 --- a/tests/test-getopt.c +++ b/tests/test-getopt.c @@ -55,14 +55,18 @@ int main (void) { - unsetenv ("POSIXLY_CORRECT"); + setenv ("POSIXLY_CORRECT", "1", 1); + test_getopt (); + +#if GNULIB_GETOPT_GNU + test_getopt_long_posix (); +#endif + unsetenv ("POSIXLY_CORRECT"); test_getopt (); + #if GNULIB_GETOPT_GNU test_getopt_long (); - - setenv ("POSIXLY_CORRECT", "1", 0); - test_getopt_long_posix (); #endif return 0; diff --git a/tests/test-getopt.h b/tests/test-getopt.h index 4efec4bc7..be47b53e0 100644 --- a/tests/test-getopt.h +++ b/tests/test-getopt.h @@ -16,6 +16,8 @@ /* Written by Bruno Haible , 2009. */ +#include + static void getopt_loop (int argc, const char **argv, const char *options, @@ -62,6 +64,14 @@ static void test_getopt (void) { 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. */ for (start = OPTIND_MIN; start <= 1; start++) @@ -80,6 +90,7 @@ test_getopt (void) argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "ab", &a_seen, &b_seen, &p_value, &q_value, @@ -109,6 +120,7 @@ test_getopt (void) argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "ab", &a_seen, &b_seen, &p_value, &q_value, @@ -137,6 +149,7 @@ test_getopt (void) argv[argc++] = "-ba"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "ab", &a_seen, &b_seen, &p_value, &q_value, @@ -166,6 +179,7 @@ test_getopt (void) argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "ab", &a_seen, &b_seen, &p_value, &q_value, @@ -195,6 +209,7 @@ test_getopt (void) argv[argc++] = "program"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "p:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -223,6 +238,7 @@ test_getopt (void) argv[argc++] = "-p"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "p:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -253,6 +269,7 @@ test_getopt (void) argv[argc++] = "baz"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "abp:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -283,6 +300,7 @@ test_getopt (void) argv[argc++] = "program"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "p::q::", &a_seen, &b_seen, &p_value, &q_value, @@ -311,6 +329,7 @@ test_getopt (void) argv[argc++] = "-p"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "p::q::", &a_seen, &b_seen, &p_value, &q_value, @@ -339,6 +358,7 @@ test_getopt (void) argv[argc++] = "-p"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "abp::q::", &a_seen, &b_seen, &p_value, &q_value, @@ -372,6 +392,7 @@ test_getopt (void) argv[argc++] = "-x"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "abp:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -405,46 +426,47 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "abp:q:", &a_seen, &b_seen, &p_value, &q_value, &non_options_count, non_options, &unrecognized); - /* 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. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "donald") == 0); - ASSERT (strcmp (argv[2], "-p") == 0); - ASSERT (strcmp (argv[3], "billy") == 0); - ASSERT (strcmp (argv[4], "duck") == 0); - ASSERT (strcmp (argv[5], "-a") == 0); - ASSERT (strcmp (argv[6], "bar") == 0); - 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 == 1); -#else - /* Using getopt from glibc. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "-p") == 0); - ASSERT (strcmp (argv[2], "billy") == 0); - ASSERT (strcmp (argv[3], "-a") == 0); - ASSERT (strcmp (argv[4], "donald") == 0); - ASSERT (strcmp (argv[5], "duck") == 0); - ASSERT (strcmp (argv[6], "bar") == 0); - ASSERT (a_seen == 1); - ASSERT (b_seen == 0); - ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); - ASSERT (q_value == NULL); - ASSERT (non_options_count == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 4); -#endif + if (posixly) + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "donald") == 0); + ASSERT (strcmp (argv[2], "-p") == 0); + ASSERT (strcmp (argv[3], "billy") == 0); + ASSERT (strcmp (argv[4], "duck") == 0); + ASSERT (strcmp (argv[5], "-a") == 0); + ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); + 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 == 1); + } + else + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "-p") == 0); + ASSERT (strcmp (argv[2], "billy") == 0); + ASSERT (strcmp (argv[3], "-a") == 0); + ASSERT (strcmp (argv[4], "donald") == 0); + ASSERT (strcmp (argv[5], "duck") == 0); + ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 0); + ASSERT (optind == 4); + } } /* Check that '--' ends the argument processing. */ @@ -472,56 +494,57 @@ test_getopt (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "abp:q:", &a_seen, &b_seen, &p_value, &q_value, &non_options_count, non_options, &unrecognized); - /* 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. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "donald") == 0); - ASSERT (strcmp (argv[2], "-p") == 0); - ASSERT (strcmp (argv[3], "billy") == 0); - ASSERT (strcmp (argv[4], "duck") == 0); - ASSERT (strcmp (argv[5], "-a") == 0); - ASSERT (strcmp (argv[6], "--") == 0); - ASSERT (strcmp (argv[7], "-b") == 0); - ASSERT (strcmp (argv[8], "foo") == 0); - ASSERT (strcmp (argv[9], "-q") == 0); - ASSERT (strcmp (argv[10], "johnny") == 0); - ASSERT (strcmp (argv[11], "bar") == 0); - 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 == 1); -#else - /* Using getopt from glibc. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "-p") == 0); - ASSERT (strcmp (argv[2], "billy") == 0); - ASSERT (strcmp (argv[3], "-a") == 0); - ASSERT (strcmp (argv[4], "--") == 0); - ASSERT (strcmp (argv[5], "donald") == 0); - ASSERT (strcmp (argv[6], "duck") == 0); - ASSERT (strcmp (argv[7], "-b") == 0); - ASSERT (strcmp (argv[8], "foo") == 0); - ASSERT (strcmp (argv[9], "-q") == 0); - ASSERT (strcmp (argv[10], "johnny") == 0); - ASSERT (strcmp (argv[11], "bar") == 0); - ASSERT (a_seen == 1); - ASSERT (b_seen == 0); - ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); - ASSERT (q_value == NULL); - ASSERT (non_options_count == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 5); -#endif + if (posixly) + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "donald") == 0); + ASSERT (strcmp (argv[2], "-p") == 0); + ASSERT (strcmp (argv[3], "billy") == 0); + ASSERT (strcmp (argv[4], "duck") == 0); + ASSERT (strcmp (argv[5], "-a") == 0); + ASSERT (strcmp (argv[6], "--") == 0); + ASSERT (strcmp (argv[7], "-b") == 0); + ASSERT (strcmp (argv[8], "foo") == 0); + ASSERT (strcmp (argv[9], "-q") == 0); + ASSERT (strcmp (argv[10], "johnny") == 0); + ASSERT (strcmp (argv[11], "bar") == 0); + ASSERT (argv[12] == NULL); + 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 == 1); + } + else + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "-p") == 0); + ASSERT (strcmp (argv[2], "billy") == 0); + ASSERT (strcmp (argv[3], "-a") == 0); + ASSERT (strcmp (argv[4], "--") == 0); + ASSERT (strcmp (argv[5], "donald") == 0); + ASSERT (strcmp (argv[6], "duck") == 0); + ASSERT (strcmp (argv[7], "-b") == 0); + ASSERT (strcmp (argv[8], "foo") == 0); + ASSERT (strcmp (argv[9], "-q") == 0); + ASSERT (strcmp (argv[10], "johnny") == 0); + ASSERT (strcmp (argv[11], "bar") == 0); + ASSERT (argv[12] == NULL); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 0); + ASSERT (optind == 5); + } } #if GNULIB_GETOPT_GNU @@ -545,6 +568,7 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "-abp:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -556,6 +580,7 @@ test_getopt (void) ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -593,6 +618,7 @@ test_getopt (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "-abp:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -609,6 +635,7 @@ test_getopt (void) ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[11], "bar") == 0); + ASSERT (argv[12] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -659,46 +686,47 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "abp:q:-", &a_seen, &b_seen, &p_value, &q_value, &non_options_count, non_options, &unrecognized); - /* 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. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "donald") == 0); - ASSERT (strcmp (argv[2], "-p") == 0); - ASSERT (strcmp (argv[3], "billy") == 0); - ASSERT (strcmp (argv[4], "duck") == 0); - ASSERT (strcmp (argv[5], "-a") == 0); - ASSERT (strcmp (argv[6], "bar") == 0); - 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 == 1); -#else - /* Using getopt from glibc. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "-p") == 0); - ASSERT (strcmp (argv[2], "billy") == 0); - ASSERT (strcmp (argv[3], "-a") == 0); - ASSERT (strcmp (argv[4], "donald") == 0); - ASSERT (strcmp (argv[5], "duck") == 0); - ASSERT (strcmp (argv[6], "bar") == 0); - ASSERT (a_seen == 1); - ASSERT (b_seen == 0); - ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); - ASSERT (q_value == NULL); - ASSERT (non_options_count == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 4); -#endif + if (posixly) + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "donald") == 0); + ASSERT (strcmp (argv[2], "-p") == 0); + ASSERT (strcmp (argv[3], "billy") == 0); + ASSERT (strcmp (argv[4], "duck") == 0); + ASSERT (strcmp (argv[5], "-a") == 0); + ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); + 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 == 1); + } + else + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "-p") == 0); + ASSERT (strcmp (argv[2], "billy") == 0); + ASSERT (strcmp (argv[3], "-a") == 0); + ASSERT (strcmp (argv[4], "donald") == 0); + ASSERT (strcmp (argv[5], "duck") == 0); + ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 0); + ASSERT (optind == 4); + } } /* Check that the '+' flag causes the first non-option to terminate the @@ -722,6 +750,7 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "+abp:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -733,6 +762,7 @@ test_getopt (void) ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -755,6 +785,7 @@ test_getopt (void) argv[argc++] = "program"; argv[argc++] = "-+"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "+abp:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -793,6 +824,7 @@ test_getopt (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "+abp:q:", &a_seen, &b_seen, &p_value, &q_value, @@ -809,6 +841,7 @@ test_getopt (void) ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[11], "bar") == 0); + ASSERT (argv[12] == NULL); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -838,45 +871,46 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_loop (argc, argv, "abp:q:+", &a_seen, &b_seen, &p_value, &q_value, &non_options_count, non_options, &unrecognized); - /* 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. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "donald") == 0); - ASSERT (strcmp (argv[2], "-p") == 0); - ASSERT (strcmp (argv[3], "billy") == 0); - ASSERT (strcmp (argv[4], "duck") == 0); - ASSERT (strcmp (argv[5], "-a") == 0); - ASSERT (strcmp (argv[6], "bar") == 0); - 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 == 1); -#else - /* Using getopt from glibc. */ - ASSERT (strcmp (argv[0], "program") == 0); - ASSERT (strcmp (argv[1], "-p") == 0); - ASSERT (strcmp (argv[2], "billy") == 0); - ASSERT (strcmp (argv[3], "-a") == 0); - ASSERT (strcmp (argv[4], "donald") == 0); - ASSERT (strcmp (argv[5], "duck") == 0); - ASSERT (strcmp (argv[6], "bar") == 0); - ASSERT (a_seen == 1); - ASSERT (b_seen == 0); - ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); - ASSERT (q_value == NULL); - ASSERT (non_options_count == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 4); -#endif + if (posixly) + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "donald") == 0); + ASSERT (strcmp (argv[2], "-p") == 0); + ASSERT (strcmp (argv[3], "billy") == 0); + ASSERT (strcmp (argv[4], "duck") == 0); + ASSERT (strcmp (argv[5], "-a") == 0); + ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); + 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 == 1); + } + else + { + ASSERT (strcmp (argv[0], "program") == 0); + ASSERT (strcmp (argv[1], "-p") == 0); + ASSERT (strcmp (argv[2], "billy") == 0); + ASSERT (strcmp (argv[3], "-a") == 0); + ASSERT (strcmp (argv[4], "donald") == 0); + ASSERT (strcmp (argv[5], "duck") == 0); + ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 0); + ASSERT (optind == 4); + } } } diff --git a/tests/test-getopt_long.h b/tests/test-getopt_long.h index d0d16fa67..63cc5c708 100644 --- a/tests/test-getopt_long.h +++ b/tests/test-getopt_long.h @@ -111,6 +111,7 @@ test_getopt_long (void) argv[argc++] = "program"; argv[argc++] = "--x"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xt"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xtr"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xtra"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xtre"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xtrem"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xtreme"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xtremel"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "--xtremely"; + argv[argc] = NULL; optind = 1; opterr = 0; 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++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "ab", long_options_required, &p_value, &q_value, @@ -272,6 +282,7 @@ test_getopt_long (void) argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "ab", long_options_required, &p_value, &q_value, @@ -300,6 +311,7 @@ test_getopt_long (void) argv[argc++] = "-ba"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "ab", long_options_required, &p_value, &q_value, @@ -329,6 +341,7 @@ test_getopt_long (void) argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "ab", long_options_required, &p_value, &q_value, @@ -358,6 +371,7 @@ test_getopt_long (void) argv[argc++] = "program"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "p:q:", long_options_required, &p_value, &q_value, @@ -386,6 +400,7 @@ test_getopt_long (void) argv[argc++] = "-p"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "p:q:", long_options_required, &p_value, &q_value, @@ -416,6 +431,7 @@ test_getopt_long (void) argv[argc++] = "baz"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "abp:q:", long_options_required, &p_value, &q_value, @@ -445,6 +461,7 @@ test_getopt_long (void) argv[argc++] = "program"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "p::q::", long_options_optional, &p_value, &q_value, @@ -473,6 +490,7 @@ test_getopt_long (void) argv[argc++] = "-p"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "p::q::", long_options_optional, &p_value, &q_value, @@ -501,6 +519,7 @@ test_getopt_long (void) argv[argc++] = "-p"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "abp::q::", long_options_optional, &p_value, &q_value, @@ -533,6 +552,7 @@ test_getopt_long (void) argv[argc++] = "-x"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "abp:q:", long_options_required, &p_value, &q_value, @@ -566,6 +586,7 @@ test_getopt_long (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "abp:q:", long_options_required, &p_value, &q_value, @@ -577,6 +598,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -611,6 +633,7 @@ test_getopt_long (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "abp:q:", long_options_required, &p_value, &q_value, @@ -627,6 +650,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[11], "bar") == 0); + ASSERT (argv[12] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -656,6 +680,7 @@ test_getopt_long (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "-abp:q:", long_options_required, &p_value, &q_value, @@ -667,6 +692,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -704,6 +730,7 @@ test_getopt_long (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "-abp:q:", long_options_required, &p_value, &q_value, @@ -720,6 +747,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[11], "bar") == 0); + ASSERT (argv[12] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -769,6 +797,7 @@ test_getopt_long (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "abp:q:-", long_options_required, &p_value, &q_value, @@ -780,6 +809,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -810,6 +840,7 @@ test_getopt_long (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "+abp:q:", long_options_required, &p_value, &q_value, @@ -821,6 +852,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[4], "duck") == 0); ASSERT (strcmp (argv[5], "-a") == 0); ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -843,6 +875,7 @@ test_getopt_long (void) argv[argc++] = "program"; argv[argc++] = "-+"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "+abp:q:", long_options_required, &p_value, &q_value, @@ -881,6 +914,7 @@ test_getopt_long (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "+abp:q:", long_options_required, &p_value, &q_value, @@ -897,6 +931,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[9], "-q") == 0); ASSERT (strcmp (argv[10], "johnny") == 0); ASSERT (strcmp (argv[11], "bar") == 0); + ASSERT (argv[12] == NULL); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -926,6 +961,7 @@ test_getopt_long (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; getopt_long_loop (argc, argv, "abp:q:+", long_options_required, &p_value, &q_value, @@ -937,6 +973,7 @@ test_getopt_long (void) ASSERT (strcmp (argv[4], "donald") == 0); ASSERT (strcmp (argv[5], "duck") == 0); ASSERT (strcmp (argv[6], "bar") == 0); + ASSERT (argv[7] == NULL); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); @@ -954,16 +991,67 @@ test_getopt_long (void) static 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 result; + + /* Check that POSIXLY_CORRECT doesn't change optional arguments. */ + 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; + 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; - result = do_getopt_long (c, v, "r::", l, NULL); + 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); } -- 2.11.0