]> Savannah Git Hosting - gnulib.git/commitdiff
stdio: ISO C 23: Define _PRINTF_NAN_LEN_MAX.
authorBruno Haible <bruno@clisp.org>
Sat, 25 Mar 2023 18:36:31 +0000 (19:36 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 25 Mar 2023 18:49:21 +0000 (19:49 +0100)
* 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.

ChangeLog
lib/stdio.in.h
m4/stdio_h.m4
modules/stdio
modules/stdio-tests
tests/test-stdio.c

index 99664b24c18fb4ce4220be0a301c2808394b3295..9dd1b50086f7f6d652f75ae8a7f40f4519d8c2a0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+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.
index 098f841738c950eface0f84a08c261d4315e866e..0ed3e7595cb6fbcd78b65fcb4f8c404ea3e3945b 100644 (file)
 # 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)
index 07569961f8b104156b3436be288cf810b712fac9..342b7d1f20125e46cf435b46f286cb329c4feba2 100644 (file)
@@ -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.
index b8662ef0a9381512638eaded84eaa61886a39a30..b4d866df9d5a4f64bdcc4381662a81b66ca012ad 100644 (file)
@@ -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
index 5368a2c64c03ab9a9cffb00c1c83d15b3ae6e055..52b753e2f7f8a5a3d32e937f4c0de54754ac72b9 100644 (file)
@@ -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
index a3b0a3e2baeb7a13f93ffc0d09fce18dd5cb8a51..9794f4d856580ca5ff3bef41878d5c735c641014 100644 (file)
@@ -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;
 }