/* Checked size_t computations. */
#include "xsize.h"
-#if NEED_PRINTF_INFINITE && !defined IN_LIBINTL
+#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
+# include <math.h>
+# include "float+.h"
+#endif
+
+#if NEED_PRINTF_INFINITE_DOUBLE && !defined IN_LIBINTL
# include <math.h>
# include "isnan.h"
#endif
-#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
+#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !defined IN_LIBINTL
# include <math.h>
-# include "float+.h"
+# include "isnanl-nolibm.h"
#endif
#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
# endif
#endif
-#if NEED_PRINTF_INFINITE && !defined IN_LIBINTL
+#if NEED_PRINTF_INFINITE_DOUBLE && !defined IN_LIBINTL
/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
static int
#endif
+#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !defined IN_LIBINTL
+
+/* Equivalent to !isfinite(x), but does not require libm. */
+static int
+is_infinitel (long double x)
+{
+ return isnanl (x) || (x + x == x && x != 0.0L);
+}
+
+#endif
+
#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
/* Converting 'long double' to decimal without rare rounding bugs requires
abort ();
}
}
-#if (NEED_PRINTF_INFINITE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
+#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
else if ((dp->conversion == 'f' || dp->conversion == 'F'
|| dp->conversion == 'e' || dp->conversion == 'E'
|| dp->conversion == 'g' || dp->conversion == 'G')
&& (0
-# if NEED_PRINTF_INFINITE
+# 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
+ /* Some systems produce wrong output for Inf,
+ -Inf, and NaN. */
+ && is_infinitel (a.arg[dp->arg_index].a.a_longdouble))
# endif
))
{
-# if NEED_PRINTF_INFINITE && NEED_PRINTF_LONG_DOUBLE
+# if NEED_PRINTF_INFINITE_DOUBLE && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
arg_type type = a.arg[dp->arg_index].type;
# endif
int flags = dp->flags;
precision = 6;
/* Allocate a temporary buffer of sufficient size. */
-# if NEED_PRINTF_INFINITE && NEED_PRINTF_LONG_DOUBLE
+# if NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
# elif NEED_PRINTF_LONG_DOUBLE
tmp_length = LDBL_DIG + 1;
-# elif NEED_PRINTF_INFINITE
+# else
tmp_length = 0;
# endif
if (tmp_length < precision)
tmp_length = precision;
# if NEED_PRINTF_LONG_DOUBLE
-# if NEED_PRINTF_INFINITE
+# if NEED_PRINTF_INFINITE_DOUBLE
if (type == TYPE_LONGDOUBLE)
# endif
if (dp->conversion == 'f' || dp->conversion == 'F')
pad_ptr = NULL;
p = tmp;
-# if NEED_PRINTF_LONG_DOUBLE
-# if NEED_PRINTF_INFINITE
+# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
+# if NEED_PRINTF_INFINITE_DOUBLE
if (type == TYPE_LONGDOUBLE)
# endif
{
}
else
{
+# if NEED_PRINTF_LONG_DOUBLE
pad_ptr = p;
if (dp->conversion == 'f' || dp->conversion == 'F')
}
*p++ = dp->conversion; /* 'e' or 'E' */
-# if WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
{
static const wchar_t decimal_format[] =
{ '%', '+', '.', '2', 'd', '\0' };
SNPRINTF (p, 6 + 1, decimal_format, exponent);
}
-# else
+# else
sprintf (p, "%+.2d", exponent);
-# endif
+# endif
while (*p != '\0')
p++;
}
}
}
*p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
-# if WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
{
static const wchar_t decimal_format[] =
{ '%', '+', '.', '2', 'd', '\0' };
SNPRINTF (p, 6 + 1, decimal_format, exponent);
}
-# else
+# else
sprintf (p, "%+.2d", exponent);
-# endif
+# endif
while (*p != '\0')
p++;
}
}
else
abort ();
+# else
+ /* arg is finite. */
+ abort ();
+# endif
}
END_LONG_DOUBLE_ROUNDING ();
}
}
-# if NEED_PRINTF_INFINITE
+# if NEED_PRINTF_INFINITE_DOUBLE
else
# endif
# endif
-# if NEED_PRINTF_INFINITE
+# if NEED_PRINTF_INFINITE_DOUBLE
{
/* Simpler than above: handle only NaN, Infinity, zero. */
double arg = a.arg[dp->arg_index].a.a_double;
*p++ = '+';
/* Produce the same number of exponent digits as
the native printf implementation. */
-# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
*p++ = '0';
-# endif
+# endif
*p++ = '0';
*p++ = '0';
}