* lib/stdio.in.h (_PRINTF_NAN_LEN_MAX): New macro.
* m4/stdio_h.m4 (gl_STDIO_H): Invoke gl_MUSL_LIBC.
* modules/stdio (Files): Add m4/musl.m4.
* tests/test-stdio.c: Check that _PRINTF_NAN_LEN_MAX is defined.
Include nan.h, macros.h.
(main): Check the value of _PRINTF_NAN_LEN_MAX.
* modules/stdio-tests (Files): Add tests/nan.h, tests/macros.h,
m4/exponentd.m4.
(configure.ac): Invoke gl_DOUBLE_EXPONENT_LOCATION.
+2023-03-25 Bruno Haible <bruno@clisp.org>
+
+ stdio: ISO C 23: Define _PRINTF_NAN_LEN_MAX.
+ * lib/stdio.in.h (_PRINTF_NAN_LEN_MAX): New macro.
+ * m4/stdio_h.m4 (gl_STDIO_H): Invoke gl_MUSL_LIBC.
+ * modules/stdio (Files): Add m4/musl.m4.
+ * tests/test-stdio.c: Check that _PRINTF_NAN_LEN_MAX is defined.
+ Include nan.h, macros.h.
+ (main): Check the value of _PRINTF_NAN_LEN_MAX.
+ * modules/stdio-tests (Files): Add tests/nan.h, tests/macros.h,
+ m4/exponentd.m4.
+ (configure.ac): Invoke gl_DOUBLE_EXPONENT_LOCATION.
+
2023-03-25 Bruno Haible <bruno@clisp.org>
Make some header file tests a bit stronger.
# undef putc_unlocked
#endif
+
+/* Maximum number of characters produced by printing a NaN value. */
+#ifndef _PRINTF_NAN_LEN_MAX
+# if defined __FreeBSD__ || defined __DragonFly__ \
+ || defined __NetBSD__ \
+ || defined __OpenBSD__ \
+ || (defined __APPLE__ && defined __MACH__)
+/* On BSD systems, a NaN value prints as just "nan", without a sign. */
+# define _PRINTF_NAN_LEN_MAX 3
+# elif (__GLIBC__ >= 2) || MUSL_LIBC || defined __sun || defined __CYGWIN__
+/* glibc, musl libc, Solaris libc, and Cygwin produce "[-]nan". */
+# define _PRINTF_NAN_LEN_MAX 4
+# elif defined _AIX
+/* AIX produces "[-]NaNQ". */
+# define _PRINTF_NAN_LEN_MAX 5
+# elif defined _WIN32 && !defined __CYGWIN__
+/* On native Windows, the output can be:
+ - with MSVC ucrt: "[-]nan" or "[-]nan(ind)" or "[-]nan(snan)",
+ - with mingw: "[-]1.#IND" or "[-]1.#QNAN". */
+# define _PRINTF_NAN_LEN_MAX 10
+# elif defined __sgi
+/* On IRIX, the output typically is "[-]nan0xNNNNNNNN" with 8 hexadecimal
+ digits. */
+# define _PRINTF_NAN_LEN_MAX 14
+# else
+/* We don't know, but 32 should be a safe maximum. */
+# define _PRINTF_NAN_LEN_MAX 32
+# endif
+#endif
+
+
#if @GNULIB_DPRINTF@
# if @REPLACE_DPRINTF@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# stdio_h.m4 serial 61
+# stdio_h.m4 serial 62
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
attribute "__gnu_printf__" instead of "__printf__"])
fi
+ dnl For defining _PRINTF_NAN_LEN_MAX.
+ gl_MUSL_LIBC
+
dnl This ifdef is an optimization, to avoid performing a configure check whose
dnl result is not used. But it does not make the test of
dnl GNULIB_STDIO_H_NONBLOCKING or GNULIB_NONBLOCKING redundant.
lib/stdio-read.c
lib/stdio-write.c
m4/stdio_h.m4
+m4/musl.m4
Depends-on:
extensions
Files:
tests/test-stdio.c
+tests/nan.h
+tests/macros.h
+m4/exponentd.m4
Depends-on:
assert-h
fwrite-tests
configure.ac:
+gl_DOUBLE_EXPONENT_LOCATION
Makefile.am:
TESTS += test-stdio
/* Check that the various SEEK_* macros are defined. */
int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
+/* Check that the _PRINTF_NAN_LEN_MAX macro is defined. */
+int pnlm[] = { _PRINTF_NAN_LEN_MAX };
+
/* Check that NULL can be passed through varargs as a pointer type,
per POSIX 2008. */
static_assert (sizeof NULL == sizeof (void *));
ssize_t t4;
va_list t5;
+#include <string.h>
+
+#include "nan.h"
+#include "macros.h"
+
int
main (void)
{
+#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+ /* Check the value of _PRINTF_NAN_LEN_MAX. */
+ {
+ #define NWORDS \
+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ typedef union { double value; unsigned int word[NWORDS]; } memory_double;
+
+ double value1;
+ memory_double value2;
+ char buf[64];
+
+ value1 = NaNd();
+ sprintf (buf, "%g", value1);
+ ASSERT (strlen (buf) <= _PRINTF_NAN_LEN_MAX);
+
+ value2.value = NaNd ();
+ #if DBL_EXPBIT0_BIT == 20
+ value2.word[DBL_EXPBIT0_WORD] ^= 0x54321;
+ #endif
+ sprintf (buf, "%g", value2.value);
+ ASSERT (strlen (buf) <= _PRINTF_NAN_LEN_MAX);
+ }
+#endif
+
return 0;
}