summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2007-11-03 17:00:19 +0100
committerBruno Haible <bruno@clisp.org>2007-11-03 17:00:19 +0100
commit7926b0fc363afde51a861a5aea4a8e93476c5526 (patch)
treeb8ca2f9cc7a9bc131584f6efe25640b853ac45ce
parent7cd87873c8336cb43c0452df4b11238f014be8a1 (diff)
downloadgnulib-7926b0fc363afde51a861a5aea4a8e93476c5526.tar.gz
New tests for modules 'test-fprintf-posix' and 'test-printf-posix'.
-rw-r--r--ChangeLog55
-rw-r--r--modules/fprintf-posix-tests7
-rw-r--r--modules/printf-posix-tests7
-rw-r--r--tests/test-fprintf-posix2.c112
-rwxr-xr-xtests/test-fprintf-posix2.sh34
-rw-r--r--tests/test-printf-posix2.c112
-rwxr-xr-xtests/test-printf-posix2.sh34
7 files changed, 357 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index ede86ddbde..e976094331 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,60 @@
2007-11-03 Bruno Haible <bruno@clisp.org>
+ * tests/test-fprintf-posix2.sh: New file.
+ * tests/test-fprintf-posix2.c: New file.
+ * modules/fprintf-posix-tests (Files): Add them.
+ (TESTS): Add test-fprintf-posix2.sh.
+ (configure.ac): Check for getrlimit and setrlimit.
+ (check_PROGRAMS): Add test-fprintf-posix2.
+
+ * tests/test-printf-posix2.sh: New file.
+ * tests/test-printf-posix2.c: New file.
+ * modules/printf-posix-tests (Files): Add them.
+ (TESTS): Add test-printf-posix2.sh.
+ (configure.ac): Check for getrlimit and setrlimit.
+ (check_PROGRAMS): Add test-printf-posix2.
+
+ Fix *printf behaviour in out-of-memory situations on MacOS X and *BSD.
+ * m4/printf.m4 (gl_PRINTF_ENOMEM): New macro.
+ * lib/vasnprintf.c: Implement NEED_PRINTF_DOUBLE.
+ (decode_double): New function, copied from decode_long_double.
+ (scale10_round_decimal_decoded): New function, extracted from
+ scale10_round_decimal_long_double.
+ (scale10_round_decimal_long_double): Use it.
+ (scale10_round_decimal_double): New function.
+ (floorlog10): New function.
+ (VASNPRINTF): Handle NEED_PRINTF_DOUBLE case.
+ * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_ENOMEM): New macro.
+ (gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it.
+ * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Invoke
+ gl_PRINTF_ENOMEM and test its result. Invoke
+ gl_PREREQ_VASNPRINTF_ENOMEM.
+ * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise.
+ * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise.
+ * m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise.
+ * m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise.
+ * m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise.
+ * m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise.
+ * m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise.
+ * modules/fprintf-posix (Depends-on): Add frexp-nolibm.
+ * modules/snprintf-posix (Depends-on): Likewise.
+ * modules/sprintf-posix (Depends-on): Likewise.
+ * modules/vasnprintf-posix (Depends-on): Likewise.
+ * modules/vasprintf-posix (Depends-on): Likewise.
+ * modules/vfprintf-posix (Depends-on): Likewise.
+ * modules/vsnprintf-posix (Depends-on): Likewise.
+ * modules/vsprintf-posix (Depends-on): Likewise.
+ * doc/functions/fprintf.texi: Update.
+ * doc/functions/printf.texi: Update.
+ * doc/functions/snprintf.texi: Update.
+ * doc/functions/sprintf.texi: Update.
+ * doc/functions/vfprintf.texi: Update.
+ * doc/functions/vprintf.texi: Update.
+ * doc/functions/vsnprintf.texi: Update.
+ * doc/functions/vsprintf.texi: Update.
+
+2007-11-03 Bruno Haible <bruno@clisp.org>
+
* modules/frexp-nolibm-tests: New file.
* modules/frexp-nolibm: New file.
diff --git a/modules/fprintf-posix-tests b/modules/fprintf-posix-tests
index 6d87969be0..b3fdea75ae 100644
--- a/modules/fprintf-posix-tests
+++ b/modules/fprintf-posix-tests
@@ -3,13 +3,16 @@ tests/test-fprintf-posix.sh
tests/test-fprintf-posix.c
tests/test-fprintf-posix.h
tests/test-printf-posix.output
+tests/test-fprintf-posix2.sh
+tests/test-fprintf-posix2.c
Depends-on:
stdint
configure.ac:
+AC_CHECK_FUNCS_ONCE([getrlimit setrlimit])
Makefile.am:
-TESTS += test-fprintf-posix.sh
+TESTS += test-fprintf-posix.sh test-fprintf-posix2.sh
TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' srcdir='$(srcdir)'
-check_PROGRAMS += test-fprintf-posix
+check_PROGRAMS += test-fprintf-posix test-fprintf-posix2
diff --git a/modules/printf-posix-tests b/modules/printf-posix-tests
index 8d4157f261..30ced62970 100644
--- a/modules/printf-posix-tests
+++ b/modules/printf-posix-tests
@@ -3,13 +3,16 @@ tests/test-printf-posix.sh
tests/test-printf-posix.c
tests/test-printf-posix.h
tests/test-printf-posix.output
+tests/test-printf-posix2.sh
+tests/test-printf-posix2.c
Depends-on:
stdint
configure.ac:
+AC_CHECK_FUNCS_ONCE([getrlimit setrlimit])
Makefile.am:
-TESTS += test-printf-posix.sh
+TESTS += test-printf-posix.sh test-printf-posix2.sh
TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' srcdir='$(srcdir)'
-check_PROGRAMS += test-printf-posix
+check_PROGRAMS += test-printf-posix test-printf-posix2
diff --git a/tests/test-fprintf-posix2.c b/tests/test-fprintf-posix2.c
new file mode 100644
index 0000000000..6d6dc08206
--- /dev/null
+++ b/tests/test-fprintf-posix2.c
@@ -0,0 +1,112 @@
+/* Test of POSIX compatible fprintf() function.
+ Copyright (C) 2007 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
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#if HAVE_GETRLIMIT && HAVE_SETRLIMIT
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <string.h>
+#include <errno.h>
+
+int
+main (int argc, char *argv[])
+{
+ struct rlimit limit;
+ int arg;
+ int ret;
+
+ /* Some printf implementations allocate temporary space with malloc. */
+ /* On BSD systems, malloc() is limited by RLIMIT_DATA. */
+#ifdef RLIMIT_DATA
+ if (getrlimit (RLIMIT_DATA, &limit) < 0)
+ return 77;
+ if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+ limit.rlim_max = 5000000;
+ limit.rlim_cur = limit.rlim_max;
+ if (setrlimit (RLIMIT_DATA, &limit) < 0)
+ return 77;
+#endif
+ /* On Linux systems, malloc() is limited by RLIMIT_AS. */
+#ifdef RLIMIT_AS
+ if (getrlimit (RLIMIT_AS, &limit) < 0)
+ return 77;
+ if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+ limit.rlim_max = 5000000;
+ limit.rlim_cur = limit.rlim_max;
+ if (setrlimit (RLIMIT_AS, &limit) < 0)
+ return 77;
+#endif
+ /* Some printf implementations allocate temporary space on the stack. */
+#ifdef RLIMIT_STACK
+ if (getrlimit (RLIMIT_STACK, &limit) < 0)
+ return 77;
+ if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+ limit.rlim_max = 5000000;
+ limit.rlim_cur = limit.rlim_max;
+ if (setrlimit (RLIMIT_STACK, &limit) < 0)
+ return 77;
+#endif
+
+ arg = atoi (argv[1]);
+ switch (arg)
+ {
+ case 0:
+ {
+ void *memory = malloc (5000000);
+ if (memory == NULL)
+ return 1;
+ memset (memory, 17, 5000000);
+ return 78;
+ }
+ case 1:
+ ret = fprintf (stdout, "%.5000000f", 1.0);
+ return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
+ case 2:
+ ret = fprintf (stdout, "%.5000000f", -1.0);
+ return !(ret == 5000003 || (ret < 0 && errno == ENOMEM));
+ case 3:
+ ret = fprintf (stdout, "%.5000000e", 1.0);
+ return !(ret >= 5000006 || (ret < 0 && errno == ENOMEM));
+ case 4:
+ ret = fprintf (stdout, "%.5000000d", 1);
+ return !(ret == 5000000 || (ret < 0 && errno == ENOMEM));
+ case 5:
+ ret = fprintf (stdout, "%.5000000d", -1);
+ return !(ret == 5000001 || (ret < 0 && errno == ENOMEM));
+ case 6:
+ ret = fprintf (stdout, "%.5000000u", 1);
+ return !(ret == 5000000 || (ret < 0 && errno == ENOMEM));
+ }
+ return 0;
+}
+
+#else
+
+int
+main (int argc, char *argv[])
+{
+ return 77;
+}
+
+#endif
diff --git a/tests/test-fprintf-posix2.sh b/tests/test-fprintf-posix2.sh
new file mode 100755
index 0000000000..79d92af30d
--- /dev/null
+++ b/tests/test-fprintf-posix2.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Test out-of-memory handling.
+
+(./test-fprintf-posix2${EXEEXT} 0
+ result=$?
+ if test $result != 77 && test $result != 78; then result=1; fi
+ exit $result
+) 2>/dev/null
+malloc_result=$?
+if test $malloc_result = 77; then
+ echo "Skipping test: getrlimit and setrlimit don't work"
+ exit 77
+fi
+
+for arg in 1 2 3 4 5 6
+do
+ ./test-fprintf-posix2${EXEEXT} $arg > /dev/null
+ result=$?
+ if test $result = 77; then
+ echo "Skipping test: getrlimit and setrlimit don't work"
+ exit 77
+ fi
+ if test $result != 0; then
+ exit 1
+ fi
+done
+
+if test $malloc_result = 78; then
+ echo "Skipping test: getrlimit and setrlimit don't work"
+ exit 77
+fi
+
+exit 0
diff --git a/tests/test-printf-posix2.c b/tests/test-printf-posix2.c
new file mode 100644
index 0000000000..b6e4fcc550
--- /dev/null
+++ b/tests/test-printf-posix2.c
@@ -0,0 +1,112 @@
+/* Test of POSIX compatible printf() function.
+ Copyright (C) 2007 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
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#if HAVE_GETRLIMIT && HAVE_SETRLIMIT
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <string.h>
+#include <errno.h>
+
+int
+main (int argc, char *argv[])
+{
+ struct rlimit limit;
+ int arg;
+ int ret;
+
+ /* Some printf implementations allocate temporary space with malloc. */
+ /* On BSD systems, malloc() is limited by RLIMIT_DATA. */
+#ifdef RLIMIT_DATA
+ if (getrlimit (RLIMIT_DATA, &limit) < 0)
+ return 77;
+ if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+ limit.rlim_max = 5000000;
+ limit.rlim_cur = limit.rlim_max;
+ if (setrlimit (RLIMIT_DATA, &limit) < 0)
+ return 77;
+#endif
+ /* On Linux systems, malloc() is limited by RLIMIT_AS. */
+#ifdef RLIMIT_AS
+ if (getrlimit (RLIMIT_AS, &limit) < 0)
+ return 77;
+ if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+ limit.rlim_max = 5000000;
+ limit.rlim_cur = limit.rlim_max;
+ if (setrlimit (RLIMIT_AS, &limit) < 0)
+ return 77;
+#endif
+ /* Some printf implementations allocate temporary space on the stack. */
+#ifdef RLIMIT_STACK
+ if (getrlimit (RLIMIT_STACK, &limit) < 0)
+ return 77;
+ if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
+ limit.rlim_max = 5000000;
+ limit.rlim_cur = limit.rlim_max;
+ if (setrlimit (RLIMIT_STACK, &limit) < 0)
+ return 77;
+#endif
+
+ arg = atoi (argv[1]);
+ switch (arg)
+ {
+ case 0:
+ {
+ void *memory = malloc (5000000);
+ if (memory == NULL)
+ return 1;
+ memset (memory, 17, 5000000);
+ return 78;
+ }
+ case 1:
+ ret = printf ("%.5000000f", 1.0);
+ return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
+ case 2:
+ ret = printf ("%.5000000f", -1.0);
+ return !(ret == 5000003 || (ret < 0 && errno == ENOMEM));
+ case 3:
+ ret = printf ("%.5000000e", 1.0);
+ return !(ret >= 5000006 || (ret < 0 && errno == ENOMEM));
+ case 4:
+ ret = printf ("%.5000000d", 1);
+ return !(ret == 5000000 || (ret < 0 && errno == ENOMEM));
+ case 5:
+ ret = printf ("%.5000000d", -1);
+ return !(ret == 5000001 || (ret < 0 && errno == ENOMEM));
+ case 6:
+ ret = printf ("%.5000000u", 1);
+ return !(ret == 5000000 || (ret < 0 && errno == ENOMEM));
+ }
+ return 0;
+}
+
+#else
+
+int
+main (int argc, char *argv[])
+{
+ return 77;
+}
+
+#endif
diff --git a/tests/test-printf-posix2.sh b/tests/test-printf-posix2.sh
new file mode 100755
index 0000000000..893c3c9a0c
--- /dev/null
+++ b/tests/test-printf-posix2.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Test out-of-memory handling.
+
+(./test-printf-posix2${EXEEXT} 0
+ result=$?
+ if test $result != 77 && test $result != 78; then result=1; fi
+ exit $result
+) 2>/dev/null
+malloc_result=$?
+if test $malloc_result = 77; then
+ echo "Skipping test: getrlimit and setrlimit don't work"
+ exit 77
+fi
+
+for arg in 1 2 3 4 5 6
+do
+ ./test-printf-posix2${EXEEXT} $arg > /dev/null
+ result=$?
+ if test $result = 77; then
+ echo "Skipping test: getrlimit and setrlimit don't work"
+ exit 77
+ fi
+ if test $result != 0; then
+ exit 1
+ fi
+done
+
+if test $malloc_result = 78; then
+ echo "Skipping test: getrlimit and setrlimit don't work"
+ exit 77
+fi
+
+exit 0