+2007-05-21 Bruno Haible <bruno@clisp.org>
+
+ * m4/printf.m4 (gl_PRINTF_INFINITE, gl_PRINTF_INFINITE_LONG_DOUBLE):
+ Check also the output for NaN arguments. When cross-compiling, guess
+ no on IRIX.
+ * lib/vasnprintf.c: Update comments.
+ * tests/test-vasnprintf-posix.c (strisnan): New function.
+ (test_function): Use it.
+ * tests/test-vasprintf-posix.c (strisnan): New function.
+ (test_function): Use it.
+ * tests/test-snprintf-posix.h (strisnan): New function.
+ (test_function): Use it.
+ * tests/test-sprintf-posix.h (strisnan): New function.
+ (test_function): Use it.
+ Reported by Eric Blake.
+
2007-05-20 Bruno Haible <bruno@clisp.org>
* m4/frexpl.m4 (gl_FUNC_FREXPL_WORKS): Add test for large finite
# if NEED_PRINTF_INFINITE_DOUBLE
|| (a.arg[dp->arg_index].type == TYPE_DOUBLE
/* The systems (mingw) which produce wrong output
- for Inf and -Inf also do so for NaN and -0.0.
- Therefore we treat these cases here as well. */
+ for Inf, -Inf, and NaN also do so for -0.0.
+ Therefore we treat this case here as well. */
&& is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
# endif
# if NEED_PRINTF_LONG_DOUBLE
|| a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
# elif NEED_PRINTF_INFINITE_LONG_DOUBLE
|| (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
- /* The systems which produce wrong output for Inf
- and -Inf also do so for NaN. Therefore treat
- this case here as well. */
+ /* Some systems produce wrong output for Inf,
+ -Inf, and NaN. */
&& is_infinitel (a.arg[dp->arg_index].a.a_longdouble))
# endif
))
-# printf.m4 serial 12
+# printf.m4 serial 13
dnl Copyright (C) 2003, 2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
])
])
-dnl Test whether the *printf family of functions supports infinite 'double'
-dnl arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
+dnl Test whether the *printf family of functions supports infinite and NaN
+dnl 'double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
dnl Result is gl_cv_func_printf_infinite.
AC_DEFUN([gl_PRINTF_INFINITE],
AC_TRY_RUN([
#include <stdio.h>
#include <string.h>
+static int
+strisnan (const char *string, size_t start_index, size_t end_index)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
static char buf[100];
+static double zero = 0.0;
int main ()
{
if (sprintf (buf, "%f", 1.0 / 0.0) < 0
if (sprintf (buf, "%f", -1.0 / 0.0) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
return 1;
+ if (sprintf (buf, "%f", zero / zero) < 0
+ || !strisnan (buf, 0, strlen (buf)))
+ return 1;
if (sprintf (buf, "%e", 1.0 / 0.0) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
return 1;
if (sprintf (buf, "%e", -1.0 / 0.0) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
return 1;
+ if (sprintf (buf, "%e", zero / zero) < 0
+ || !strisnan (buf, 0, strlen (buf)))
+ return 1;
if (sprintf (buf, "%g", 1.0 / 0.0) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
return 1;
if (sprintf (buf, "%g", -1.0 / 0.0) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
return 1;
+ if (sprintf (buf, "%g", zero / zero) < 0
+ || !strisnan (buf, 0, strlen (buf)))
+ return 1;
return 0;
}], [gl_cv_func_printf_infinite=yes], [gl_cv_func_printf_infinite=no],
[
# Guess yes on HP-UX >= 11.
hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";;
hpux*) gl_cv_func_printf_infinite="guessing yes";;
- # Guess yes on IRIX >= 6.5.
- irix6.5) gl_cv_func_printf_infinite="guessing yes";;
# Guess yes on NetBSD >= 3.
netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
gl_cv_func_printf_infinite="guessing no";;
])
])
-dnl Test whether the *printf family of functions supports infinite 'long double'
-dnl arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
+dnl Test whether the *printf family of functions supports infinite and NaN
+dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
dnl Result is gl_cv_func_printf_infinite_long_double.
AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE],
AC_TRY_RUN([
#include <stdio.h>
#include <string.h>
+static int
+strisnan (const char *string, size_t start_index, size_t end_index)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
static char buf[100];
+static long double zeroL = 0.0L;
int main ()
{
if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0
if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
return 1;
+ if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
+ || !strisnan (buf, 0, strlen (buf)))
+ return 1;
if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
return 1;
if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
return 1;
+ if (sprintf (buf, "%Le", zeroL / zeroL) < 0
+ || !strisnan (buf, 0, strlen (buf)))
+ return 1;
if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
return 1;
if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
return 1;
+ if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
+ || !strisnan (buf, 0, strlen (buf)))
+ return 1;
return 0;
}],
[gl_cv_func_printf_infinite_long_double=yes],
# Guess yes on HP-UX >= 11.
hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";;
hpux*) gl_cv_func_printf_infinite_long_double="guessing yes";;
- # Guess yes on IRIX >= 6.5.
- irix6.5) gl_cv_func_printf_infinite_long_double="guessing yes";;
# Guess yes on NetBSD >= 3.
netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*)
gl_cv_func_printf_infinite_long_double="guessing no";;
dnl AIX 4.3.2, 5.1 # . # # # # . . . # . . . . .
dnl HP-UX 11.31 . . . . # . . . . # . . # # .
dnl HP-UX 10.20, 11.{00,11,23} # . . . # # . . . # . . # # #
-dnl IRIX 6.5 # . . . # # . . . # . . # . .
+dnl IRIX 6.5 # . # # # # . . . # . . # . .
dnl OSF/1 5.1 # . # # # # . . . # . . # . #
dnl OSF/1 4.0d # . # # # # . . . # # # # # #
dnl NetBSD 4.0 . ? ? ? ? ? . . ? ? . . . ? ?
return 1;
}
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void
test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
{
int retval =
my_snprintf (result, sizeof (result), "%a %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%La %d", 0.0L / 0.0L, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%f %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%020f %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%Lf %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%020Lf %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%F %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%LF %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%e %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%020e %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%Le %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%020Le %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%g %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%020g %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%Lg %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_snprintf (result, sizeof (result), "%020Lg %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
return 1;
}
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void
test_function (int (*my_sprintf) (char *, const char *, ...))
{
int retval =
my_sprintf (result, "%a %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%La %d", 0.0L / 0.0L, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%f %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%020f %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%Lf %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%020Lf %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%F %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%LF %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%e %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%020e %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%Le %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%020Le %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%g %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%020g %d", NaN (), 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%Lg %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
int retval =
my_sprintf (result, "%020Lg %d", zero / zero, 33, 44, 55);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
}
return 1;
}
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void
test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
{
my_asnprintf (NULL, &length, "%a %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%La %d", 0.0L / 0.0L, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%f %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%020f %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%Lf %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%020Lf %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%F %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%LF %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%e %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%020e %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%Le %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%020Le %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%g %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%020g %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%Lg %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
my_asnprintf (NULL, &length, "%020Lg %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (length == strlen (result));
free (result);
return 1;
}
+/* Test whether string[start_index..end_index-1] is a valid textual
+ representation of NaN. */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+ if (start_index < end_index)
+ {
+ if (string[start_index] == '-')
+ start_index++;
+ if (start_index + 3 <= end_index
+ && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+ {
+ start_index += 3;
+ if (start_index == end_index
+ || (string[start_index] == '(' && string[end_index - 1] == ')'))
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void
test_function (int (*my_asprintf) (char **, const char *, ...))
{
my_asprintf (&result, "%a %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%La %d", 0.0L / 0.0L, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
/* "0000000nan 33" is not a valid result; see
<http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%f %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%020f %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%Lf %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%020Lf %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%F %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%LF %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "NAN", 3) == 0
- || memcmp (result, "-NAN", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 1)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%e %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%020e %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%Le %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%020Le %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%g %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%020g %d", NaN (), 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%Lg %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) >= 3 + 3
- && (memcmp (result, "nan", 3) == 0
- || memcmp (result, "-nan", 4) == 0)
+ && strisnan (result, 0, strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);
my_asprintf (&result, "%020Lg %d", zero / zero, 33, 44, 55);
ASSERT (result != NULL);
ASSERT (strlen (result) == 20 + 3
- && (memcmp (result + strspn (result, " "), "nan", 3) == 0
- || memcmp (result + strspn (result, " "), "-nan", 4) == 0)
+ && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
&& strcmp (result + strlen (result) - 3, " 33") == 0);
ASSERT (retval == strlen (result));
free (result);