Re: vasnwprintf-posix: Work around %La bug in glibc 2.15 and Haiku

2023-04-09 Thread Bruno Haible
I wrote:
> On the glibc side, the bug is fixed in glibc 2.17 and newer.

The Haiku people found out more details about this bug. In particular,
it's fixed in glibc 2.16 already.


2023-04-09  Bruno Haible  

vasnwprintf-posix: More details about the glibc bug.
* doc/posix-functions/swprintf.texi: Add comment.
* m4/printf.m4 (gl_SWPRINTF_DIRECTIVE_LA): Update cross-compilation
guess.

diff --git a/doc/posix-functions/swprintf.texi 
b/doc/posix-functions/swprintf.texi
index fe36bc215a..649b541ed0 100644
--- a/doc/posix-functions/swprintf.texi
+++ b/doc/posix-functions/swprintf.texi
@@ -38,6 +38,7 @@
 @item
 This function produces wrong values for the @samp{La} directive
 on some platforms:
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=13726
 glibc 2.15,
 @c https://dev.haiku-os.org/ticket/18353
 Haiku.
diff --git a/m4/printf.m4 b/m4/printf.m4
index f513da0c84..efb85a57af 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 81
+# printf.m4 serial 82
 dnl Copyright (C) 2003, 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,
@@ -1988,7 +1988,7 @@ AC_DEFUN([gl_SWPRINTF_DIRECTIVE_LA]
  AC_EGREP_CPP([Unlucky], [
#include 
#ifdef __GNU_LIBRARY__
-#if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) || (__GLIBC__ > 
2)) && !defined __UCLIBC__
+#if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16) || (__GLIBC__ > 
2)) && !defined __UCLIBC__
  Unlucky
 #endif
#endif






Re: vasnwprintf-posix: Work around %La bug in glibc 2.15 and Haiku

2023-04-08 Thread Bruno Haible
Oops, there was a small bug in this patch. Corrected like this:


2023-04-08  Bruno Haible  

vasnwprintf-posix: Really work around %La bug in glibc 2.15 and Haiku.
* m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF): Fix a copy bug.

diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4
index ca14ce49b4..639b29a1f3 100644
--- a/m4/vasnprintf.m4
+++ b/m4/vasnprintf.m4
@@ -115,7 +115,7 @@ AC_DEFUN_ONCE([gl_PREREQ_VASNWPRINTF],
   ;;
   esac
   gl_SWPRINTF_DIRECTIVE_LA
-  case "$gl_cv_func_printf_directive_a" in
+  case "$gl_cv_func_swprintf_directive_la" in
 *yes) ;;
 *)
   AC_DEFINE([NEED_WPRINTF_DIRECTIVE_LA], [1],






vasnwprintf-posix: Work around %La bug in glibc 2.15 and Haiku

2023-04-07 Thread Bruno Haible
On glibc 2.15 and Haiku (2022), I am seeing a test failure:

../../gltests/test-vasnwprintf-posix.c:521: assertion 'wcscmp (result, 
L"0x1.922p+1 33") == 0 || wcscmp (result, L"0x3.244p+0 33") == 0 || wcscmp 
(result, L"0x6.488p-1 33") == 0 || wcscmp (result, L"0xc.91p-2 33") == 0' failed
FAIL test-vasnwprintf-posix (exit status: 134)

Here, instead of L"0xc.91p-2 33", the result is L"0xc.c9p-2 33", which is
off by more than 2%.

The value is wrong for many more 'long double' arguments, as can be seen
from the attached test program and output.

Interestingly, for %a and %La in narrow format strings, and for %a in wide
format strings, there is no bug.

On the glibc side, the bug is fixed in glibc 2.17 and newer. Nevertheless,
I am adding the workaround since it affects many argument values and a
recent Haiku as well.


2023-04-07  Bruno Haible  

    vasnwprintf-posix: Work around %La bug in glibc 2.15 and Haiku.
* m4/printf.m4 (gl_SWPRINTF_DIRECTIVE_LA): New macro.
* m4/vasnprintf.m4 (gl_PREREQ_VASNWPRINTF): Invoke
gl_SWPRINTF_DIRECTIVE_LA and define NEED_WPRINTF_DIRECTIVE_LA
accordingly.
* lib/vasnprintf.c: When compiling vasnwprintf, if
NEED_WPRINTF_DIRECTIVE_LA, handle the %La and %LA directives ourselves.
* doc/posix-functions/swprintf.texi: Mention the %La bug.

diff --git a/doc/posix-functions/swprintf.texi 
b/doc/posix-functions/swprintf.texi
index cd20d0e702..fe36bc215a 100644
--- a/doc/posix-functions/swprintf.texi
+++ b/doc/posix-functions/swprintf.texi
@@ -36,6 +36,12 @@ accommodate all Unicode characters.
 @item
 On Windows, this function does not take a buffer size as second argument.
 @item
+This function produces wrong values for the @samp{La} directive
+on some platforms:
+glibc 2.15,
+@c https://dev.haiku-os.org/ticket/18353
+Haiku.
+@item
 This function does not support size specifiers as in C23 (@code{w8},
 @code{w16}, @code{w32}, @code{w64}, @code{wf8}, @code{wf16}, @code{wf32},
 @code{wf64}) on some platforms:
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 6eb056d0e9..efd610ebe4 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -103,7 +103,7 @@
 
 #include "attribute.h"
 
-#if NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE
+#if NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE || 
(NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
 # include 
 # include "float+.h"
 #endif
@@ -113,7 +113,7 @@
 # include "isnand-nolibm.h"
 #endif
 
-#if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
+#if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || 
(NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
 # include 
 # include "isnanl-nolibm.h"
 # include "fpucw.h"
@@ -125,7 +125,7 @@
 # include "printf-frexp.h"
 #endif
 
-#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
+#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || 
(NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
 # include 
 # include "isnanl-nolibm.h"
 # include "printf-frexpl.h"
@@ -357,7 +357,7 @@ local_wctomb (char *s, wchar_t wc)
 # endif
 #endif
 
-#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || 
NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || 
NEED_PRINTF_INFINITE_DOUBLE
+#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || 
NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || 
NEED_PRINTF_INFINITE_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
 /* Determine the decimal-point character according to the current locale.  */
 # ifndef decimal_point_char_defined
 #  define decimal_point_char_defined 1
@@ -3929,14 +3929,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 length += count;
   }
 #endif
-#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE
+#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE 
|| (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
 else if ((dp->conversion == 'a' || dp->conversion == 'A')
 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && 
NEED_PRINTF_DOUBLE))
  && (0
 #  if NEED_PRINTF_DOUBLE
  || a.arg[dp->arg_index].type == TYPE_DOUBLE
 #  endif
-#  if NEED_PRINTF_LONG_DOUBLE
+#  if NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && 
WIDE_CHAR_VERSION)
  || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
 #  endif
 )
@@ -4056,7 +4056,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 p = tmp;
 if (type == TYPE_LONGDOUBLE)
   {
-# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
+# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || 
(NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)