On FreeBSD 12.0 and Cygwin 2.9, I'm seeing test failures of test-strfmon_l.
The cause is that on these platforms, the function ignores its locale_t argument and instead uses the per-thread locale. Worse than on older glibc systems, where only the number formatting used the per-thread locale. This patch activates the gnulib replacement and thus makes the test succeed. 2019-12-22 Bruno Haible <[email protected]> strfmon_l: Fix test failures on FreeBSD and Cygwin. * m4/strfmon_l.m4 (gl_FUNC_STRFMON_L): Require gt_LOCALE_FR_UTF8. Add an AC_RUN_IFELSE test. * modules/strfmon_l (Files): Add locale-fr.m4, codeset.m4. * doc/posix-functions/strfmon_l.texi: Mention the FreeBSD and Cygwin problem. diff --git a/doc/posix-functions/strfmon_l.texi b/doc/posix-functions/strfmon_l.texi index 9e94f63..bd88e2b 100644 --- a/doc/posix-functions/strfmon_l.texi +++ b/doc/posix-functions/strfmon_l.texi @@ -9,6 +9,9 @@ Gnulib module: strfmon_l Portability problems fixed by Gnulib: @itemize @item +This function ignores the locale argument on some platforms: +FreeBSD 12.0, Cygwin 2.9. +@item This function uses a wrong locale for the numbers on some platforms: glibc 2.23. @end itemize diff --git a/m4/strfmon_l.m4 b/m4/strfmon_l.m4 index 6f9a61d..2a71c8d 100644 --- a/m4/strfmon_l.m4 +++ b/m4/strfmon_l.m4 @@ -1,4 +1,4 @@ -# strfmon_l.m4 serial 1 +# strfmon_l.m4 serial 2 dnl Copyright (C) 2017-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,6 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_STRFMON_L], [ AC_REQUIRE([gl_MONETARY_H_DEFAULTS]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) dnl Persuade glibc <monetary.h> to declare strfmon_l(). AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) @@ -20,17 +21,65 @@ AC_DEFUN([gl_FUNC_STRFMON_L], dnl which was fixed in glibc-2.24. AC_CACHE_CHECK([whether strfmon_l works], [gl_cv_strfmon_l_works], - [AC_EGREP_CPP([Unlucky], - [ + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. + case "$host_os" in + # Guess no on glibc versions < 2.24. + *-gnu* | gnu*) + AC_EGREP_CPP([Unlucky], + [ #include <features.h> #ifdef __GNU_LIBRARY__ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24) Unlucky GNU user #endif #endif - ], - [gl_cv_strfmon_l_works=no], - [gl_cv_strfmon_l_works="guessing yes"]) + ], + [gl_cv_strfmon_l_works="guessing no"], + [gl_cv_strfmon_l_works="guessing yes"]) + ;; + # Guess no on FreeBSD and Cygwin. + freebsd* | cygwin*) gl_cv_strfmon_l_works="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_strfmon_l_works="guessing yes" ;; + esac + if test $LOCALE_FR_UTF8 != none; then + AC_CHECK_HEADERS_ONCE([xlocale.h]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include <monetary.h> +#include <locale.h> +#if HAVE_XLOCALE_H +# include <xlocale.h> +#endif +#include <string.h> +int main () +{ + /* On older glibc systems: expected_buf="$123.50" buf="$123,50" + On FreeBSD 12.0, Cygwin 2.9: expected_buf="$123.50" buf="123,50 $" + */ + if (setlocale (LC_ALL, "en_US.UTF-8") != NULL) + { + char expected_buf[80]; + if (strfmon (expected_buf, sizeof (expected_buf), "%.2n", 123.5) >= 0) + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + locale_t loc = newlocale (LC_ALL_MASK, "en_US.UTF-8", NULL); + if (loc != (locale_t) 0) + { + char buf[80]; + if (strfmon_l (buf, sizeof (buf), loc, "%.2n", 123.5) >= 0) + return strcmp (buf, expected_buf) != 0; + } + } + } + return 0; +}]])], + [gl_cv_strfmon_l_works=yes], + [gl_cv_strfmon_l_works=no], + [:]) + fi ]) if test "$gl_cv_strfmon_l_works" = no; then REPLACE_STRFMON_L=1 diff --git a/modules/strfmon_l b/modules/strfmon_l index 16c339c..62f665f 100644 --- a/modules/strfmon_l +++ b/modules/strfmon_l @@ -4,6 +4,8 @@ strfmon_l() function: formatted conversion of monetary value to string. Files: lib/strfmon_l.c m4/strfmon_l.m4 +m4/locale-fr.m4 +m4/codeset.m4 Depends-on: monetary
