diff --git a/ChangeLog b/ChangeLog index bb85ba9d0f..c2ce3a994a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-04-07 Ulrich Drepper + + * posix/bug-getopt1.c: New file. + * posix/bug-getopt2.c: New file. + * posix/bug-getopt3.c: New file. + * posix/bug-getopt4.c: New file. + * posix/bug-getopt5.c: New file. + 2009-12-01 Eric Blake [BZ #11039] diff --git a/posix/Makefile b/posix/Makefile index 1a369ddf84..df0e6f1053 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -92,7 +92,9 @@ tests := tstgetopt testfnm runtests runptests \ tst-execve1 tst-execve2 tst-execle1 tst-execle2 \ tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \ tst-rfc3484-3 \ - tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset + tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \ + bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \ + bug-getopt5 xtests := bug-ga2 ifeq (yes,$(build-shared)) test-srcs := globtest diff --git a/posix/bug-getopt1.c b/posix/bug-getopt1.c new file mode 100644 index 0000000000..a47dc7e229 --- /dev/null +++ b/posix/bug-getopt1.c @@ -0,0 +1,73 @@ +/* BZ 11039 */ +#include +#include + +static int +one_test (const char *fmt, int argc, char *argv[], int expected[argc - 1]) +{ + optind = 1; + + int res = 0; + for (int i = 0; i < argc - 1; ++i) + { + rewind (stderr); + if (ftruncate (fileno (stderr), 0) != 0) + { + puts ("cannot truncate file"); + return 1; + } + + int c = getopt (argc, argv, fmt); + if (c != expected[i]) + { + printf ("format '%s' test %d failed: expected '%c', got '%c'\n", + fmt, i, expected[i], c); + res = 1; + } + if (ftell (stderr) != 0) + { + printf ("format '%s' test %d failed: printed to stderr\n", + fmt, i); + res = 1; + } + } + + return res; +} + + +static int +do_test (void) +{ + char *fname = tmpnam (NULL); + if (fname == NULL) + { + puts ("cannot generate name for temporary file"); + return 1; + } + + if (freopen (fname, "w+", stderr) == NULL) + { + puts ("cannot redirect stderr"); + return 1; + } + + remove (fname); + + int ret = one_test ("+:a:b", 2, + (char *[2]) { (char *) "bug-getopt1", (char *) "-a" }, + (int [1]) { ':' }); + + ret |= one_test ("+:a:b", 3, + (char *[3]) { (char *) "bug-getopt1", (char *) "-b", + (char *) "-a" }, + (int [2]) { 'b', ':' }); + + if (ret == 0) + puts ("all OK"); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/posix/bug-getopt2.c b/posix/bug-getopt2.c new file mode 100644 index 0000000000..93c3035ccd --- /dev/null +++ b/posix/bug-getopt2.c @@ -0,0 +1,72 @@ +/* BZ 11039 */ +#include +#include + +static int +one_test (const char *fmt, int argc, char *argv[], int expected[argc - 1]) +{ + int res = 0; + for (int i = 0; i < argc - 1; ++i) + { + rewind (stderr); + if (ftruncate (fileno (stderr), 0) != 0) + { + puts ("cannot truncate file"); + return 1; + } + + int c = getopt (argc, argv, fmt); + if (c != expected[i]) + { + printf ("format '%s' test %d failed: expected '%c', got '%c'\n", + fmt, i, expected[i], c); + res = 1; + } + if (ftell (stderr) == 0) + { + printf ("format '%s' test %d failed: not printed to stderr\n", + fmt, i); + res = 1; + } + } + + return res; +} + + +static int +do_test (void) +{ + char *fname = tmpnam (NULL); + if (fname == NULL) + { + puts ("cannot generate name for temporary file"); + return 1; + } + + if (freopen (fname, "w+", stderr) == NULL) + { + puts ("cannot redirect stderr"); + return 1; + } + + remove (fname); + + optind = 0; + int ret = one_test ("+a", 2, + (char *[2]) { (char *) "bug-getopt2", (char *) "-+" }, + (int [1]) { '?' }); + + optind = 1; + ret |= one_test ("+a", 2, + (char *[2]) { (char *) "bug-getopt2", (char *) "-+" }, + (int [1]) { '?' }); + + if (ret == 0) + puts ("all OK"); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/posix/bug-getopt3.c b/posix/bug-getopt3.c new file mode 100644 index 0000000000..c3a8cb225b --- /dev/null +++ b/posix/bug-getopt3.c @@ -0,0 +1,81 @@ +/* BZ 11040 */ +#include +#include +#include + +static const struct option opts[] = + { + { "alpha", no_argument, NULL, 'a' }, + { "beta", required_argument, NULL, 'b' }, + { NULL, 0, NULL, 0 } + }; + +static int +one_test (const char *fmt, int argc, char *argv[], int n, int expected[n], + int out[n]) +{ + optind = 1; + + int res = 0; + for (int i = 0; i < n; ++i) + { + rewind (stderr); + if (ftruncate (fileno (stderr), 0) != 0) + { + puts ("cannot truncate file"); + return 1; + } + + int c = getopt_long (argc, argv, fmt, opts, NULL); + if (c != expected[i]) + { + printf ("format '%s' test %d failed: expected '%c', got '%c'\n", + fmt, i, expected[i], c); + res = 1; + } + if ((ftell (stderr) != 0) != out[i]) + { + printf ("format '%s' test %d failed: %sprinted to stderr\n", + fmt, i, out[i] ? "not " : ""); + res = 1; + } + } + + return res; +} + + +static int +do_test (void) +{ + char *fname = tmpnam (NULL); + if (fname == NULL) + { + puts ("cannot generate name for temporary file"); + return 1; + } + + if (freopen (fname, "w+", stderr) == NULL) + { + puts ("cannot redirect stderr"); + return 1; + } + + remove (fname); + + int ret = one_test ("ab:W;", 2, + (char *[2]) { (char *) "bug-getopt3", (char *) "-a;" }, + 2, (int [2]) { 'a', '?' }, (int [2]) { 0, 1 }); + + ret |= one_test ("ab:W;", 2, + (char *[2]) { (char *) "bug-getopt3", (char *) "-a:" }, 2, + (int [2]) { 'a', '?' }, (int [2]) { 0, 1 }); + + if (ret == 0) + puts ("all OK"); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/posix/bug-getopt4.c b/posix/bug-getopt4.c new file mode 100644 index 0000000000..1daffd1d34 --- /dev/null +++ b/posix/bug-getopt4.c @@ -0,0 +1,86 @@ +/* BZ 11041 */ +#include +#include +#include + +static const struct option opts[] = + { + { "alpha", optional_argument, NULL, 'a' }, + { NULL, 0, NULL, 0 } + }; + +static int +one_test (const char *fmt, int argc, char *argv[], int n, int expected[n]) +{ + optind = 1; + + int res = 0; + for (int i = 0; i < n; ++i) + { + rewind (stderr); + if (ftruncate (fileno (stderr), 0) != 0) + { + puts ("cannot truncate file"); + return 1; + } + + int c = getopt_long (argc, argv, fmt, opts, NULL); + if (c != expected[i]) + { + printf ("format '%s' test %d failed: expected '%c', got '%c'\n", + fmt, i, expected[i], c); + res = 1; + } + else if (optarg != NULL) + { + printf ("format '%s' test %d failed: optarg is \"%s\", not NULL\n", + fmt, i, optarg); + res = 1; + } + if (ftell (stderr) != 0) + { + printf ("format '%s' test %d failed: printed to stderr\n", + fmt, i); + res = 1; + } + } + + return res; +} + + +static int +do_test (void) +{ + char *fname = tmpnam (NULL); + if (fname == NULL) + { + puts ("cannot generate name for temporary file"); + return 1; + } + + if (freopen (fname, "w+", stderr) == NULL) + { + puts ("cannot redirect stderr"); + return 1; + } + + remove (fname); + + int ret = one_test ("W;", 2, + (char *[2]) { (char *) "bug-getopt4", (char *) "--a" }, + 1, (int [1]) { 'a' }); + + ret |= one_test ("W;", 3, + (char *[3]) { (char *) "bug-getopt4", (char *) "-W", + (char *) "a" }, + 1, (int [1]) { 'a' }); + + if (ret == 0) + puts ("all OK"); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/posix/bug-getopt5.c b/posix/bug-getopt5.c new file mode 100644 index 0000000000..ed2639d35b --- /dev/null +++ b/posix/bug-getopt5.c @@ -0,0 +1,81 @@ +/* BZ 11041 */ +#include +#include +#include + +static const struct option opts[] = + { + { "a1", no_argument, NULL, 'a' }, + { "a2", no_argument, NULL, 'a' }, + { NULL, 0, NULL, 0 } + }; + +static int +one_test (const char *fmt, int argc, char *argv[], int n, int expected[n]) +{ + optind = 1; + + int res = 0; + for (int i = 0; i < n; ++i) + { + rewind (stderr); + if (ftruncate (fileno (stderr), 0) != 0) + { + puts ("cannot truncate file"); + return 1; + } + + int c = getopt_long (argc, argv, fmt, opts, NULL); + if (c != expected[i]) + { + printf ("format '%s' test %d failed: expected '%c', got '%c'\n", + fmt, i, expected[i], c); + res = 1; + } + if (ftell (stderr) != 0) + { + printf ("format '%s' test %d failed: printed to stderr\n", + fmt, i); + res = 1; + } + } + + return res; +} + + +static int +do_test (void) +{ + char *fname = tmpnam (NULL); + if (fname == NULL) + { + puts ("cannot generate name for temporary file"); + return 1; + } + + if (freopen (fname, "w+", stderr) == NULL) + { + puts ("cannot redirect stderr"); + return 1; + } + + remove (fname); + + int ret = one_test (":W;", 2, + (char *[2]) { (char *) "bug-getopt5", (char *) "--a" }, + 1, (int [1]) { 'a' }); + + ret |= one_test (":W;", 3, + (char *[3]) { (char *) "bug-getopt5", (char *) "-W", + (char *) "a" }, + 1, (int [1]) { 'a' }); + + if (ret == 0) + puts ("all OK"); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c"