X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=tests%2Ftest-getopt.h;h=450cf0d31ac75bd54f23b177262284f907f0f75c;hb=8b40415718be86c3a37388ba35804be74b8f376e;hp=352fe3231af7d888b1fc460ff550382753b0be86;hpb=ae2e7ad5890fe4442cbd14e589091c07abd10883;p=gnulib.git diff --git a/tests/test-getopt.h b/tests/test-getopt.h index 352fe3231..450cf0d31 100644 --- a/tests/test-getopt.h +++ b/tests/test-getopt.h @@ -1,5 +1,5 @@ /* Test of command line argument processing. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,52 +16,81 @@ /* Written by Bruno Haible , 2009. */ +#include + +/* The glibc/gnulib implementation of getopt supports setting optind = + 0, but not all other implementations do. This matters for getopt. + But for getopt_long, we require GNU compatibility. */ +#if defined __GETOPT_PREFIX || (__GLIBC__ >= 2 && !defined __UCLIBC__) +# define OPTIND_MIN 0 +#elif HAVE_DECL_OPTRESET +# define OPTIND_MIN (optreset = 1) +#else +# define OPTIND_MIN 1 +#endif + static void -getopt_loop (int argc, char **argv, - const char *options, - int *a_seen, int *b_seen, - const char **p_value, const char **q_value, - int *non_options_count, const char **non_options, - int *unrecognized) +getopt_loop (int argc, const char **argv, + const char *options, + int *a_seen, int *b_seen, + const char **p_value, const char **q_value, + int *non_options_count, const char **non_options, + int *unrecognized, bool *message_issued) { int c; + int pos = ftell (stderr); - opterr = 0; - while ((c = getopt (argc, argv, options)) != -1) + while ((c = getopt (argc, (char **) argv, options)) != -1) { switch (c) - { - case 'a': - (*a_seen)++; - break; - case 'b': - (*b_seen)++; - break; - case 'p': - *p_value = optarg; - break; - case 'q': - *q_value = optarg; - break; - case '\1': - /* Must only happen with option '-' at the beginning. */ - ASSERT (options[0] == '-'); - non_options[(*non_options_count)++] = optarg; - break; - case '?': - *unrecognized = optopt; - break; - default: - *unrecognized = c; - break; - } + { + case 'a': + (*a_seen)++; + break; + case 'b': + (*b_seen)++; + break; + case 'p': + *p_value = optarg; + break; + case 'q': + *q_value = optarg; + break; + case '\1': + /* Must only happen with option '-' at the beginning. */ + ASSERT (options[0] == '-'); + non_options[(*non_options_count)++] = optarg; + break; + case ':': + /* Must only happen with option ':' at the beginning. */ + ASSERT (options[0] == ':' + || ((options[0] == '-' || options[0] == '+') + && options[1] == ':')); + /* fall through */ + case '?': + *unrecognized = optopt; + break; + default: + *unrecognized = c; + break; + } } + + *message_issued = pos < ftell (stderr); } 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++) @@ -73,17 +102,20 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "ab", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -91,6 +123,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 2); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -101,18 +134,21 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-b"; argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "ab", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 1); ASSERT (b_seen == 1); ASSERT (p_value == NULL); @@ -120,6 +156,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 3); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -130,17 +167,20 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-ba"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "ab", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 1); ASSERT (b_seen == 1); ASSERT (p_value == NULL); @@ -148,6 +188,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 2); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -158,18 +199,21 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-ab"; argv[argc++] = "-a"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "ab", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 2); ASSERT (b_seen == 1); ASSERT (p_value == NULL); @@ -177,6 +221,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 3); + ASSERT (!output); } /* Test processing of options with arguments. */ @@ -189,16 +234,19 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "p:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); @@ -206,6 +254,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 2); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -216,17 +265,20 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-p"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "p:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); @@ -234,6 +286,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 3); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -244,8 +297,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-ab"; @@ -253,10 +307,12 @@ test_getopt (void) argv[argc++] = "baz"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "abp:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 1); ASSERT (b_seen == 1); ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); @@ -264,9 +320,10 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 5); + ASSERT (!output); } -#if GNULIB_GETOPT_GNU +#if GNULIB_TEST_GETOPT_GNU /* Test processing of options with optional arguments. */ for (start = OPTIND_MIN; start <= 1; start++) { @@ -277,16 +334,19 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-pfoo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "p::q::", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); @@ -294,6 +354,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 2); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -304,17 +365,20 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-p"; argv[argc++] = "foo"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "p::q::", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -322,6 +386,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 2); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -332,17 +397,20 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-p"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "abp::q::", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -350,10 +418,12 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 3); + ASSERT (!output); } -#endif +#endif /* GNULIB_TEST_GETOPT_GNU */ - /* Check that invalid options are recognized. */ + /* Check that invalid options are recognized; and that both opterr + and leading ':' can silence output. */ for (start = OPTIND_MIN; start <= 1; start++) { int a_seen = 0; @@ -363,8 +433,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-p"; @@ -372,10 +443,12 @@ test_getopt (void) argv[argc++] = "-x"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 42; getopt_loop (argc, argv, "abp:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 1); ASSERT (b_seen == 0); ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); @@ -383,9 +456,42 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 'x'); ASSERT (optind == 5); + ASSERT (output); } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; - /* Check that by default, non-options arguments are moved to the end. */ + argv[argc++] = "program"; + argv[argc++] = "-p"; + argv[argc++] = "foo"; + argv[argc++] = "-x"; + argv[argc++] = "-a"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = start; + opterr = 0; + getopt_loop (argc, argv, "abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 'x'); + ASSERT (optind == 5); + ASSERT (!output); + } for (start = OPTIND_MIN; start <= 1; start++) { int a_seen = 0; @@ -395,56 +501,291 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; - argv[argc++] = "donald"; argv[argc++] = "-p"; - argv[argc++] = "billy"; - argv[argc++] = "duck"; + argv[argc++] = "foo"; + argv[argc++] = "-x"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; + getopt_loop (argc, argv, ":abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 'x'); + ASSERT (optind == 5); + ASSERT (!output); + } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-p"; + argv[argc++] = "foo"; + argv[argc++] = "-:"; + argv[argc++] = "-a"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = start; + opterr = 42; 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); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == ':'); + ASSERT (optind == 5); + ASSERT (output); + } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-p"; + argv[argc++] = "foo"; + argv[argc++] = "-:"; + argv[argc++] = "-a"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = start; + opterr = 0; + getopt_loop (argc, argv, "abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == ':'); + ASSERT (optind == 5); + ASSERT (!output); + } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-p"; + argv[argc++] = "foo"; + argv[argc++] = "-:"; + argv[argc++] = "-a"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = start; + opterr = 1; + getopt_loop (argc, argv, ":abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == ':'); + ASSERT (optind == 5); + ASSERT (!output); + } + + /* Check for missing argument behavior. */ + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-ap"; + argv[argc] = NULL; + optind = start; + opterr = 1; + getopt_loop (argc, argv, "abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + ASSERT (a_seen == 1); 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 (unrecognized == 'p'); + ASSERT (optind == 2); + ASSERT (output); + } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-ap"; + argv[argc] = NULL; + optind = start; + opterr = 0; + getopt_loop (argc, argv, "abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 1); ASSERT (b_seen == 0); - ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); + ASSERT (p_value == NULL); ASSERT (q_value == NULL); ASSERT (non_options_count == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 4); -#endif + ASSERT (unrecognized == 'p'); + ASSERT (optind == 2); + ASSERT (!output); + } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-ap"; + argv[argc] = NULL; + optind = start; + opterr = 1; + getopt_loop (argc, argv, ":abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + ASSERT (a_seen == 1); + ASSERT (b_seen == 0); + ASSERT (p_value == NULL); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 'p'); + ASSERT (optind == 2); + ASSERT (!output); + } + + /* Check that by default, non-options arguments are moved to the end. */ + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "donald"; + argv[argc++] = "-p"; + argv[argc++] = "billy"; + argv[argc++] = "duck"; + argv[argc++] = "-a"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = start; + opterr = 1; + getopt_loop (argc, argv, "abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + 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); + ASSERT (!output); + } + 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); + ASSERT (!output); + } } /* Check that '--' ends the argument processing. */ @@ -457,8 +798,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[20]; + const char *argv[20]; argv[argc++] = "program"; argv[argc++] = "donald"; @@ -472,59 +814,63 @@ test_getopt (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; 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 + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + 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); + ASSERT (!output); + } + 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); + ASSERT (!output); + } } -#if GNULIB_GETOPT_GNU +#if GNULIB_TEST_GETOPT_GNU /* Check that the '-' flag causes non-options to be returned in order. */ for (start = OPTIND_MIN; start <= 1; start++) { @@ -535,8 +881,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "donald"; @@ -545,10 +892,12 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "-abp:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[2], "-p") == 0); @@ -556,6 +905,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); @@ -566,6 +916,7 @@ test_getopt (void) ASSERT (strcmp (non_options[2], "bar") == 0); ASSERT (unrecognized == 0); ASSERT (optind == 7); + ASSERT (!output); } /* Check that '--' ends the argument processing. */ @@ -578,8 +929,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[20]; + const char *argv[20]; argv[argc++] = "program"; argv[argc++] = "donald"; @@ -593,10 +945,12 @@ test_getopt (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "-abp:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[2], "-p") == 0); @@ -609,35 +963,36 @@ 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); ASSERT (q_value == NULL); + ASSERT (!output); if (non_options_count == 2) { - /* glibc behaviour. */ - ASSERT (non_options_count == 2); - ASSERT (strcmp (non_options[0], "donald") == 0); - ASSERT (strcmp (non_options[1], "duck") == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 7); + /* glibc behaviour. */ + ASSERT (non_options_count == 2); + ASSERT (strcmp (non_options[0], "donald") == 0); + ASSERT (strcmp (non_options[1], "duck") == 0); + ASSERT (unrecognized == 0); + ASSERT (optind == 7); } else { - /* Another valid behaviour. */ - ASSERT (non_options_count == 7); - ASSERT (strcmp (non_options[0], "donald") == 0); - ASSERT (strcmp (non_options[1], "duck") == 0); - ASSERT (strcmp (non_options[2], "-b") == 0); - ASSERT (strcmp (non_options[3], "foo") == 0); - ASSERT (strcmp (non_options[4], "-q") == 0); - ASSERT (strcmp (non_options[5], "johnny") == 0); - ASSERT (strcmp (non_options[6], "bar") == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 12); + /* Another valid behaviour. */ + ASSERT (non_options_count == 7); + ASSERT (strcmp (non_options[0], "donald") == 0); + ASSERT (strcmp (non_options[1], "duck") == 0); + ASSERT (strcmp (non_options[2], "-b") == 0); + ASSERT (strcmp (non_options[3], "foo") == 0); + ASSERT (strcmp (non_options[4], "-q") == 0); + ASSERT (strcmp (non_options[5], "johnny") == 0); + ASSERT (strcmp (non_options[6], "bar") == 0); + ASSERT (unrecognized == 0); + ASSERT (optind == 12); } } -#endif /* Check that the '-' flag has to come first. */ for (start = OPTIND_MIN; start <= 1; start++) @@ -649,8 +1004,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "donald"; @@ -659,46 +1015,50 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; 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 + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + 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); + ASSERT (!output); + } + 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); + ASSERT (!output); + } } /* Check that the '+' flag causes the first non-option to terminate the @@ -712,8 +1072,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "donald"; @@ -722,10 +1083,12 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "+abp:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[2], "-p") == 0); @@ -733,6 +1096,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); @@ -740,6 +1104,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); ASSERT (optind == 1); + ASSERT (!output); } for (start = OPTIND_MIN; start <= 1; start++) { @@ -750,15 +1115,17 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "-+"; + 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); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (a_seen == 0); ASSERT (b_seen == 0); ASSERT (p_value == NULL); @@ -766,6 +1133,7 @@ test_getopt (void) ASSERT (non_options_count == 0); ASSERT (unrecognized == '+'); ASSERT (optind == 2); + ASSERT (output); } /* Check that '--' ends the argument processing. */ @@ -778,8 +1146,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[20]; + const char *argv[20]; argv[argc++] = "program"; argv[argc++] = "donald"; @@ -793,10 +1162,12 @@ test_getopt (void) argv[argc++] = "-q"; argv[argc++] = "johnny"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; getopt_loop (argc, argv, "+abp:q:", - &a_seen, &b_seen, &p_value, &q_value, - &non_options_count, non_options, &unrecognized); + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[2], "-p") == 0); @@ -809,14 +1180,17 @@ 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); ASSERT (q_value == NULL); ASSERT (non_options_count == 0); ASSERT (unrecognized == 0); - ASSERT (optind = 1); + ASSERT (optind == 1); + ASSERT (!output); } +#endif /* GNULIB_TEST_GETOPT_GNU */ /* Check that the '+' flag has to come first. */ for (start = OPTIND_MIN; start <= 1; start++) @@ -828,8 +1202,9 @@ test_getopt (void) int non_options_count = 0; const char *non_options[10]; int unrecognized = 0; + bool output; int argc = 0; - char *argv[10]; + const char *argv[10]; argv[argc++] = "program"; argv[argc++] = "donald"; @@ -838,15 +1213,82 @@ test_getopt (void) argv[argc++] = "duck"; argv[argc++] = "-a"; argv[argc++] = "bar"; + argv[argc] = NULL; optind = start; + opterr = 1; 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. */ + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); + 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); + ASSERT (!output); + } + 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); + ASSERT (!output); + } + } + +#if GNULIB_TEST_GETOPT_GNU + /* If GNU extensions are supported, require compliance with POSIX + interpretation on leading '+' behavior. + http://austingroupbugs.net/view.php?id=191 */ + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "donald"; + argv[argc++] = "-p"; + argv[argc++] = "billy"; + argv[argc++] = "duck"; + argv[argc++] = "-a"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = start; + opterr = 1; + getopt_loop (argc, argv, "+:abp:q:", + &a_seen, &b_seen, &p_value, &q_value, + &non_options_count, non_options, &unrecognized, &output); ASSERT (strcmp (argv[0], "program") == 0); ASSERT (strcmp (argv[1], "donald") == 0); ASSERT (strcmp (argv[2], "-p") == 0); @@ -854,6 +1296,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); @@ -861,22 +1304,88 @@ test_getopt (void) 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 (!output); + } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-p"; + 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, &output); + ASSERT (a_seen == 0); ASSERT (b_seen == 0); - ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0); + ASSERT (p_value == NULL); ASSERT (q_value == NULL); ASSERT (non_options_count == 0); - ASSERT (unrecognized == 0); - ASSERT (optind == 4); -#endif + ASSERT (unrecognized == 'p'); + ASSERT (optind == 2); + ASSERT (!output); + } + for (start = OPTIND_MIN; start <= 1; start++) + { + int a_seen = 0; + int b_seen = 0; + const char *p_value = NULL; + const char *q_value = NULL; + int non_options_count = 0; + const char *non_options[10]; + int unrecognized = 0; + bool output; + int argc = 0; + const char *argv[10]; + + argv[argc++] = "program"; + argv[argc++] = "-b"; + argv[argc++] = "-p"; + 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, &output); + ASSERT (a_seen == 0); + ASSERT (b_seen == 1); + ASSERT (p_value == NULL); + ASSERT (q_value == NULL); + ASSERT (non_options_count == 0); + ASSERT (unrecognized == 'p'); + ASSERT (optind == 3); + ASSERT (!output); + } + + /* Check that 'W' does not dump core: + http://sourceware.org/bugzilla/show_bug.cgi?id=12922 + Technically, POSIX says the presence of ';' in the opt-string + gives unspecified behavior, so we only test this when GNU compliance + is desired. */ + for (start = OPTIND_MIN; start <= 1; start++) + { + int argc = 0; + const char *argv[10]; + int pos = ftell (stderr); + + argv[argc++] = "program"; + argv[argc++] = "-W"; + argv[argc++] = "dummy"; + argv[argc] = NULL; + optind = start; + opterr = 1; + ASSERT (getopt (argc, (char **) argv, "W;") == 'W'); + ASSERT (ftell (stderr) == pos); + ASSERT (optind == 2); } +#endif /* GNULIB_TEST_GETOPT_GNU */ }