* lib/uchar.in.h (_GL_WCHAR_T_IS_UCS4): New macro.
* lib/btoc32.c (btoc32): Test _GL_WCHAR_T_IS_UCS4 instead of __GLIBC__.
* lib/mbsrtoc32s.c: Likewise.
* lib/mbsnrtoc32s.c: Likewise.
* lib/c32tob.c (c32tob): Likewise.
* lib/c32srtombs.c: Likewise.
* lib/c32snrtombs.c: Likewise.
* lib/c32is-impl.h (FUNC): Likewise.
+2023-04-04 Bruno Haible <bruno@clisp.org>
+
+ *c32*: Optimize on musl libc like on glibc.
+ * lib/uchar.in.h (_GL_WCHAR_T_IS_UCS4): New macro.
+ * lib/btoc32.c (btoc32): Test _GL_WCHAR_T_IS_UCS4 instead of __GLIBC__.
+ * lib/mbsrtoc32s.c: Likewise.
+ * lib/mbsnrtoc32s.c: Likewise.
+ * lib/c32tob.c (c32tob): Likewise.
+ * lib/c32srtombs.c: Likewise.
+ * lib/c32snrtombs.c: Likewise.
+ * lib/c32is-impl.h (FUNC): Likewise.
+
2023-04-04 Bruno Haible <bruno@clisp.org>
uchar: Rename _GL_LARGE_CHAR32_T to _GL_SMALL_WCHAR_T.
wint_t
btoc32 (int c)
{
-#if HAVE_WORKING_MBRTOC32 && !defined __GLIBC__
+#if HAVE_WORKING_MBRTOC32 && !_GL_WCHAR_T_IS_UCS4
/* The char32_t encoding of a multibyte character may be different than its
wchar_t encoding. */
if (c != EOF)
#elif HAVE_WORKING_MBRTOC32 /* glibc */
/* mbrtoc32() is essentially defined by the system libc. */
-# if defined __GLIBC__
+# if _GL_WCHAR_T_IS_UCS4
/* The char32_t encoding of a multibyte character is known to be the same as
the wchar_t encoding. */
return WCHAR_FUNC (wc);
#include <wchar.h>
-#if (HAVE_WORKING_MBRTOC32 && !defined __GLIBC__) || _GL_SMALL_WCHAR_T
+#if (HAVE_WORKING_MBRTOC32 && !_GL_WCHAR_T_IS_UCS4) || _GL_SMALL_WCHAR_T
/* The char32_t encoding of a multibyte character may be different than its
wchar_t encoding, or char32_t is wider than wchar_t. */
#include <wchar.h>
-#if (HAVE_WORKING_MBRTOC32 && !defined __GLIBC__) || _GL_SMALL_WCHAR_T
+#if (HAVE_WORKING_MBRTOC32 && !_GL_WCHAR_T_IS_UCS4) || _GL_SMALL_WCHAR_T
/* The char32_t encoding of a multibyte character may be different than its
wchar_t encoding, or char32_t is wider than wchar_t. */
int
c32tob (wint_t wc)
{
-#if HAVE_WORKING_MBRTOC32 && !defined __GLIBC__
+#if HAVE_WORKING_MBRTOC32 && !_GL_WCHAR_T_IS_UCS4
/* The char32_t encoding of a multibyte character may be different than its
wchar_t encoding. */
if (wc != WEOF)
#include <wchar.h>
-#if (HAVE_WORKING_MBRTOC32 && !defined __GLIBC__) || _GL_SMALL_WCHAR_T
+#if (HAVE_WORKING_MBRTOC32 && !_GL_WCHAR_T_IS_UCS4) || _GL_SMALL_WCHAR_T
/* The char32_t encoding of a multibyte character may be different than its
wchar_t encoding, or char32_t is wider than wchar_t. */
#include <wchar.h>
-#if (HAVE_WORKING_MBRTOC32 && !defined __GLIBC__) || _GL_SMALL_WCHAR_T
+#if (HAVE_WORKING_MBRTOC32 && !_GL_WCHAR_T_IS_UCS4) || _GL_SMALL_WCHAR_T
/* The char32_t encoding of a multibyte character may be different than its
wchar_t encoding, or char32_t is wider than wchar_t. */
# define _GL_SMALL_WCHAR_T 1
#endif
+/* Define if 'wchar_t', like 'char32_t',
+ - is a 32-bit type, and
+ - represents Unicode code points.
+ For this test, we can use __STDC_ISO_10646__ (defined by glibc, musl libc,
+ Cygwin) but need to consider _GL_SMALL_WCHAR_T, so as to exclude Cygwin.
+ We cannot use __STDC_UTF_16__ or __STDC_UTF_32__
+ - because these macros provide info about char16_t and char32_t (not
+ wchar_t!), and
+ - because GCC >= 4.9 defines these macros on all platforms, even on
+ FreeBSD and Solaris.
+ We should better not use __STD_UTF_16__, __STD_UTF_32__ either, because
+ these macros are misspellings, only defined by Android's <uchar.h>. */
+#if defined __STDC_ISO_10646__ && !_GL_SMALL_WCHAR_T
+/* glibc, musl libc */
+# define _GL_WCHAR_T_IS_UCS4 1
+#endif
/* Convert a single-byte character to a 32-bit wide character. */
#if @GNULIB_BTOC32@