* stdio: ISO C 23: Define _PRINTF_NAN_LEN_MAX
@ 2023-03-25 18:50 Bruno Haible
0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2023-03-25 18:50 UTC (permalink / raw)
To: bug-gnulib
ISO C 23 specifies a new macro, to be defined in <stdio.h>: _PRINTF_NAN_LEN_MAX.
This patch implements it.
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.
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index 098f841738..0ed3e7595c 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -204,6 +204,37 @@
# 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)
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index 07569961f8..342b7d1f20 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -1,4 +1,4 @@
-# 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,
@@ -40,6 +40,9 @@ AC_DEFUN_ONCE([gl_STDIO_H]
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.
diff --git a/modules/stdio b/modules/stdio
index b8662ef0a9..b4d866df9d 100644
--- a/modules/stdio
+++ b/modules/stdio
@@ -6,6 +6,7 @@ lib/stdio.in.h
lib/stdio-read.c
lib/stdio-write.c
m4/stdio_h.m4
+m4/musl.m4
Depends-on:
extensions
diff --git a/modules/stdio-tests b/modules/stdio-tests
index 5368a2c64c..52b753e2f7 100644
--- a/modules/stdio-tests
+++ b/modules/stdio-tests
@@ -1,5 +1,8 @@
Files:
tests/test-stdio.c
+tests/nan.h
+tests/macros.h
+m4/exponentd.m4
Depends-on:
assert-h
@@ -10,6 +13,7 @@ fread-tests
fwrite-tests
configure.ac:
+gl_DOUBLE_EXPONENT_LOCATION
Makefile.am:
TESTS += test-stdio
diff --git a/tests/test-stdio.c b/tests/test-stdio.c
index a3b0a3e2ba..9794f4d856 100644
--- a/tests/test-stdio.c
+++ b/tests/test-stdio.c
@@ -23,6 +23,9 @@
/* 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 *));
@@ -34,8 +37,37 @@ size_t t3;
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;
}
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2023-03-25 18:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-25 18:50 stdio: ISO C 23: Define _PRINTF_NAN_LEN_MAX Bruno Haible
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).