From 27857e3c09038053c88c4e27210cc229900b5567 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Tue, 4 Apr 2023 13:03:53 +0200 Subject: stdlib: Work around MB_CUR_MAX bug on Solaris 10. * lib/stdlib.in.h (gl_MB_CUR_MAX): New function. (MB_CUR_MAX, GNULIB_defined_MB_CUR_MAX): New macros. * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether MB_CUR_MAX is correct. (gl_STDLIB_H_DEFAULTS): Initialize REPLACE_MB_CUR_MAX. * modules/stdlib (Files): Add m4/locale-fr.m4. (Makefile.am): Substitute REPLACE_MB_CUR_MAX. * doc/posix-headers/stdlib.texi: Mention the Solaris 10 bug. --- ChangeLog | 11 +++++++++++ doc/posix-headers/stdlib.texi | 4 ++++ lib/stdlib.in.h | 15 ++++++++++++++ m4/stdlib_h.m4 | 46 ++++++++++++++++++++++++++++++++++++++++++- modules/stdlib | 2 ++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9a78e7f771..5f64b7c1c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2023-04-04 Bruno Haible + + stdlib: Work around MB_CUR_MAX bug on Solaris 10. + * lib/stdlib.in.h (gl_MB_CUR_MAX): New function. + (MB_CUR_MAX, GNULIB_defined_MB_CUR_MAX): New macros. + * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether MB_CUR_MAX is correct. + (gl_STDLIB_H_DEFAULTS): Initialize REPLACE_MB_CUR_MAX. + * modules/stdlib (Files): Add m4/locale-fr.m4. + (Makefile.am): Substitute REPLACE_MB_CUR_MAX. + * doc/posix-headers/stdlib.texi: Mention the Solaris 10 bug. + 2023-04-04 Bruno Haible *c32*: Inline most functions on glibc and musl libc. diff --git a/doc/posix-headers/stdlib.texi b/doc/posix-headers/stdlib.texi index 612e794068..ac7efbda84 100644 --- a/doc/posix-headers/stdlib.texi +++ b/doc/posix-headers/stdlib.texi @@ -14,6 +14,10 @@ some platforms. Some platforms provide a @code{NULL} macro that cannot be used in arbitrary expressions: NetBSD 5.0 +@item +The value of @code{MB_CUR_MAX} is too small (3 instead of 4) in UTF-8 locales +on some platforms: +Solaris 10. @end itemize Portability problems fixed by the Gnulib module @code{system-posix}: diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 4ecfc96a6f..c18a16bacd 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -589,6 +589,21 @@ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " # endif #endif +/* Return maximum number of bytes of a multibyte character. */ +#if @REPLACE_MB_CUR_MAX@ +# if !GNULIB_defined_MB_CUR_MAX +static inline +int gl_MB_CUR_MAX (void) +{ + /* Turn the value 3 to the value 4, as needed for the UTF-8 encoding. */ + return MB_CUR_MAX + (MB_CUR_MAX == 3); +} +# undef MB_CUR_MAX +# define MB_CUR_MAX gl_MB_CUR_MAX () +# define GNULIB_defined_MB_CUR_MAX 1 +# endif +#endif + /* Convert a string to a wide string. */ #if @GNULIB_MBSTOWCS@ # if @REPLACE_MBSTOWCS@ diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index ac28ed9efc..cef133e051 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 72 +# stdlib_h.m4 serial 73 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, @@ -32,6 +32,49 @@ AC_DEFUN_ONCE([gl_STDLIB_H], AC_REQUIRE([AC_C_RESTRICT]) + dnl Test whether MB_CUR_MAX needs to be overridden. + dnl On Solaris 10, in UTF-8 locales, its value is 3 but needs to be 4. + dnl Fortunately, we can do this because on this platform MB_LEN_MAX is 5. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_CACHE_CHECK([whether MB_CUR_MAX is correct], + [gl_cv_macro_MB_CUR_MAX_good], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on Solaris. + solaris*) gl_cv_macro_MB_CUR_MAX_good="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_macro_MB_CUR_MAX_good="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_FR_UTF8 != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +int main () +{ + int result = 0; + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + if (MB_CUR_MAX < 4) + result |= 1; + } + return result; +}]])], + [gl_cv_macro_MB_CUR_MAX_good=yes], + [gl_cv_macro_MB_CUR_MAX_good=no] + [:]) + fi + ]) + case "$gl_cv_macro_MB_CUR_MAX_good" in + *yes) ;; + *) REPLACE_MB_CUR_MAX=1 ;; + esac + AC_CHECK_DECLS_ONCE([ecvt]) if test $ac_cv_have_decl_ecvt = no; then HAVE_DECL_ECVT=0 @@ -181,6 +224,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], REPLACE_INITSTATE=0; AC_SUBST([REPLACE_INITSTATE]) REPLACE_MALLOC_FOR_MALLOC_GNU=0; AC_SUBST([REPLACE_MALLOC_FOR_MALLOC_GNU]) REPLACE_MALLOC_FOR_MALLOC_POSIX=0; AC_SUBST([REPLACE_MALLOC_FOR_MALLOC_POSIX]) + REPLACE_MB_CUR_MAX=0; AC_SUBST([REPLACE_MB_CUR_MAX]) REPLACE_MBSTOWCS=0; AC_SUBST([REPLACE_MBSTOWCS]) REPLACE_MBTOWC=0; AC_SUBST([REPLACE_MBTOWC]) REPLACE_MKOSTEMP=0; AC_SUBST([REPLACE_MKOSTEMP]) diff --git a/modules/stdlib b/modules/stdlib index efea327794..25593a8a5d 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -4,6 +4,7 @@ A GNU-like . Files: lib/stdlib.in.h m4/stdlib_h.m4 +m4/locale-fr.m4 Depends-on: gen-header @@ -141,6 +142,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''REPLACE_INITSTATE''@|$(REPLACE_INITSTATE)|g' \ -e 's|@''REPLACE_MALLOC_FOR_MALLOC_GNU''@|$(REPLACE_MALLOC_FOR_MALLOC_GNU)|g' \ -e 's|@''REPLACE_MALLOC_FOR_MALLOC_POSIX''@|$(REPLACE_MALLOC_FOR_MALLOC_POSIX)|g' \ + -e 's|@''REPLACE_MB_CUR_MAX''@|$(REPLACE_MB_CUR_MAX)|g' \ -e 's|@''REPLACE_MBSTOWCS''@|$(REPLACE_MBSTOWCS)|g' \ -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ -e 's|@''REPLACE_MKOSTEMP''@|$(REPLACE_MKOSTEMP)|g' \ -- cgit v1.2.1