[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
*c32*: Inline most functions on glibc and musl libc
From: |
Bruno Haible |
Subject: |
*c32*: Inline most functions on glibc and musl libc |
Date: |
Tue, 04 Apr 2023 21:22:26 +0200 |
The type 'char32_t' is a more modern alternative to 'wchar_t', because it
solves the problems mentioned in
<https://www.gnu.org/software/libunistring/manual/html_node/The-wchar_005ft-mess.html>.
To make a migration from 'wchar_t' to 'char32_t' attractive, it is
important that on glibc and musl libc systems the 'char32_t' functions
are not slower than the 'wchar_t' functions.
This is achieved through the patch below, by inlining many functions.
At first, I wanted to use the common idiom for _GL_INLINE.
But it turns out that the idiom with
#define _GL_UCHAR_INLINE _GL_INLINE
and a uchar.c file that defines
#define _GL_UCHAR_INLINE _GL_EXTERN_INLINE
works only if all functions marked with _GL_UCHAR_INLINE belong to the
same module. If the .h file makes use of @GNULIB_xxx@ module indicators,
this idiom does not work:
Suppose function A is needed in lib, and function B is only needed in tests.
@GNULIB_A@ expands to 1, @GNULIB_B@ expands to IN_GNULIB_TESTS, i.e.
0 in lib/, 1 in tests/. When uchar.c is compiled, it therefore defines
A but not B in uchar.o. In tests/ uchar.c is not being compiled a second time.
So, we have no global definition of B, and the result is a link error.
The idiom that works is to keep each function in its own compilation unit.
2023-04-04 Bruno Haible <bruno@clisp.org>
*c32*: Inline most functions on glibc and musl libc.
* lib/uchar.in.h: Invoke _GL_INLINE_HEADER_BEGIN, _GL_INLINE_HEADER_END.
(btoc32): Inline if _GL_WCHAR_T_IS_UCS4.
(c32isalnum, c32isalpha, c32isblank, c32iscntrl, c32isdigit, c32isgraph,
c32islower, c32isprint, c32ispunct, c32isspace, c32isupper,
c32isxdigit): Inline if
_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t.
(c32snrtombs, c32srtombs, c32stombs, c32tob, mbsnrtoc32s, mbsrtoc32s,
mbstoc32s): Inline if _GL_WCHAR_T_IS_UCS4.
* lib/btoc32.c: Define compilation unit marker.
(btoc32): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32isalnum.c: Define compilation unit marker.
* lib/c32isalpha.c: Likewise.
* lib/c32isblank.c: Likewise.
* lib/c32iscntrl.c: Likewise.
* lib/c32isdigit.c: Likewise.
* lib/c32isgraph.c: Likewise.
* lib/c32islower.c: Likewise.
* lib/c32isprint.c: Likewise.
* lib/c32ispunct.c: Likewise.
* lib/c32isspace.c: Likewise.
* lib/c32isupper.c: Likewise.
* lib/c32isxdigit.c: Likewise.
* lib/c32is-impl.h (FUNC): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32snrtombs.c: Define compilation unit marker.
(c32snrtombs): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32srtombs.c: Define compilation unit marker.
(c32srtombs): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32stombs.c: Define compilation unit marker.
(c32stombs): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32tob.c: Define compilation unit marker.
(c32tob): Conditionally mark as _GL_EXTERN_INLINE.
* lib/mbsnrtoc32s.c: Define compilation unit marker.
(mbsnrtoc32s): Conditionally mark as _GL_EXTERN_INLINE.
* lib/mbsrtoc32s.c: Define compilation unit marker.
(mbsrtoc32s): Conditionally mark as _GL_EXTERN_INLINE.
* lib/mbstoc32s.c: Define compilation unit marker.
(mbstoc32s): Conditionally mark as _GL_EXTERN_INLINE.
* modules/uchar (Depends-on): Add extern-inline.
diff --git a/lib/btoc32.c b/lib/btoc32.c
index 9ba8fb5a5e..07fbe194b6 100644
--- a/lib/btoc32.c
+++ b/lib/btoc32.c
@@ -18,12 +18,16 @@
#include <config.h>
+#define IN_BTOC32
/* Specification. */
#include <uchar.h>
#include <stdio.h>
#include <string.h>
+#if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+#endif
wint_t
btoc32 (int c)
{
diff --git a/lib/c32is-impl.h b/lib/c32is-impl.h
index d5e5362c0b..8682a6897e 100644
--- a/lib/c32is-impl.h
+++ b/lib/c32is-impl.h
@@ -38,6 +38,9 @@
#include "unictype.h"
+#if _GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t
+_GL_EXTERN_INLINE
+#endif
int
FUNC (wint_t wc)
{
diff --git a/lib/c32isalnum.c b/lib/c32isalnum.c
index 6127d99148..c3ab2b8299 100644
--- a/lib/c32isalnum.c
+++ b/lib/c32isalnum.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISALNUM
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isalpha.c b/lib/c32isalpha.c
index 4041bed605..1462cf7083 100644
--- a/lib/c32isalpha.c
+++ b/lib/c32isalpha.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISALPHA
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isblank.c b/lib/c32isblank.c
index cae38e29f9..edd79e8963 100644
--- a/lib/c32isblank.c
+++ b/lib/c32isblank.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISBLANK
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32iscntrl.c b/lib/c32iscntrl.c
index 48288eb112..b067aacb1b 100644
--- a/lib/c32iscntrl.c
+++ b/lib/c32iscntrl.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISCNTRL
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isdigit.c b/lib/c32isdigit.c
index 8381937334..70ed5ff5f7 100644
--- a/lib/c32isdigit.c
+++ b/lib/c32isdigit.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISDIGIT
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isgraph.c b/lib/c32isgraph.c
index 4c0677105e..f23d191735 100644
--- a/lib/c32isgraph.c
+++ b/lib/c32isgraph.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISGRAPH
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32islower.c b/lib/c32islower.c
index 55b689e818..3a3d6bc336 100644
--- a/lib/c32islower.c
+++ b/lib/c32islower.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISLOWER
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isprint.c b/lib/c32isprint.c
index fd98088c31..f19e53dd6c 100644
--- a/lib/c32isprint.c
+++ b/lib/c32isprint.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISPRINT
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32ispunct.c b/lib/c32ispunct.c
index aba446d73e..f06d79f0c6 100644
--- a/lib/c32ispunct.c
+++ b/lib/c32ispunct.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISPUNCT
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isspace.c b/lib/c32isspace.c
index 84c4fcfe6a..115d0fb2a1 100644
--- a/lib/c32isspace.c
+++ b/lib/c32isspace.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISSPACE
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isupper.c b/lib/c32isupper.c
index 5dc3a3d3ea..5fdc2c4dae 100644
--- a/lib/c32isupper.c
+++ b/lib/c32isupper.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISUPPER
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32isxdigit.c b/lib/c32isxdigit.c
index b78fdc9d04..8dcd91427e 100644
--- a/lib/c32isxdigit.c
+++ b/lib/c32isxdigit.c
@@ -24,6 +24,7 @@
#include <config.h>
+#define IN_C32ISXDIGIT
/* Specification. */
#include <uchar.h>
diff --git a/lib/c32snrtombs.c b/lib/c32snrtombs.c
index fd10fc1595..e47df6bf8e 100644
--- a/lib/c32snrtombs.c
+++ b/lib/c32snrtombs.c
@@ -18,6 +18,7 @@
#include <config.h>
+#define IN_C32SNRTOMBS
/* Specification. */
#include <uchar.h>
@@ -44,6 +45,9 @@ extern mbstate_t _gl_c32srtombs_state;
static_assert (sizeof (char32_t) == sizeof (wchar_t));
+# if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+# endif
size_t
c32snrtombs (char *dest, const char32_t **srcp, size_t srclen, size_t len,
mbstate_t *ps)
diff --git a/lib/c32srtombs.c b/lib/c32srtombs.c
index 50db58c3d3..306c75ae43 100644
--- a/lib/c32srtombs.c
+++ b/lib/c32srtombs.c
@@ -18,6 +18,7 @@
#include <config.h>
+#define IN_C32SRTOMBS
/* Specification. */
#include <uchar.h>
@@ -44,6 +45,9 @@ extern mbstate_t _gl_c32srtombs_state;
static_assert (sizeof (char32_t) == sizeof (wchar_t));
+# if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+# endif
size_t
c32srtombs (char *dest, const char32_t **srcp, size_t len, mbstate_t *ps)
{
diff --git a/lib/c32stombs.c b/lib/c32stombs.c
index f469d3bb52..86e84b2fe7 100644
--- a/lib/c32stombs.c
+++ b/lib/c32stombs.c
@@ -17,12 +17,16 @@
#include <config.h>
+#define IN_C32STOMBS
/* Specification. */
#include <uchar.h>
#include <string.h>
#include <wchar.h>
+#if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+#endif
size_t
c32stombs (char *dest, const char32_t *src, size_t len)
{
diff --git a/lib/c32tob.c b/lib/c32tob.c
index a18aac6efc..7b164352c5 100644
--- a/lib/c32tob.c
+++ b/lib/c32tob.c
@@ -18,6 +18,7 @@
#include <config.h>
+#define IN_C32TOB
/* Specification. */
#include <uchar.h>
@@ -25,6 +26,9 @@
#include <string.h>
#include <wchar.h>
+#if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+#endif
int
c32tob (wint_t wc)
{
diff --git a/lib/mbsnrtoc32s.c b/lib/mbsnrtoc32s.c
index c8084da3d9..d52e9934e0 100644
--- a/lib/mbsnrtoc32s.c
+++ b/lib/mbsnrtoc32s.c
@@ -17,6 +17,7 @@
#include <config.h>
+#define IN_MBSNRTOC32S
/* Specification. */
#include <uchar.h>
@@ -53,6 +54,9 @@ extern mbstate_t _gl_mbsrtoc32s_state;
static_assert (sizeof (char32_t) == sizeof (wchar_t));
+# if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+# endif
size_t
mbsnrtoc32s (char32_t *dest, const char **srcp, size_t srclen, size_t len,
mbstate_t *ps)
diff --git a/lib/mbsrtoc32s.c b/lib/mbsrtoc32s.c
index 9c5a5d096a..32306a50e7 100644
--- a/lib/mbsrtoc32s.c
+++ b/lib/mbsrtoc32s.c
@@ -17,6 +17,7 @@
#include <config.h>
+#define IN_MBSRTOC32S
/* Specification. */
#include <uchar.h>
@@ -45,6 +46,9 @@ extern mbstate_t _gl_mbsrtoc32s_state;
static_assert (sizeof (char32_t) == sizeof (wchar_t));
+# if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+# endif
size_t
mbsrtoc32s (char32_t *dest, const char **srcp, size_t len, mbstate_t *ps)
{
diff --git a/lib/mbstoc32s.c b/lib/mbstoc32s.c
index 24564152dc..0dac80e8b0 100644
--- a/lib/mbstoc32s.c
+++ b/lib/mbstoc32s.c
@@ -17,12 +17,16 @@
#include <config.h>
+#define IN_MBSTOC32S
/* Specification. */
#include <uchar.h>
#include <string.h>
#include <wchar.h>
+#if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+#endif
size_t
mbstoc32s (char32_t *dest, const char *src, size_t len)
{
diff --git a/lib/uchar.in.h b/lib/uchar.in.h
index 46b4be4f6d..bd1c5441cc 100644
--- a/lib/uchar.in.h
+++ b/lib/uchar.in.h
@@ -58,6 +58,12 @@
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+
+
#if !(@HAVE_UCHAR_H@ || (defined __cplusplus && @CXX_HAS_CHAR8_TYPE@))
/* An 8-bit variant of wchar_t.
@@ -123,10 +129,22 @@ typedef uint_least32_t gl_char32_t;
/* glibc, musl libc */
# define _GL_WCHAR_T_IS_UCS4 1
#endif
+#if _GL_WCHAR_T_IS_UCS4
+static_assert (sizeof (char32_t) == sizeof (wchar_t));
+#endif
+
/* Convert a single-byte character to a 32-bit wide character. */
#if @GNULIB_BTOC32@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_BTOC32
+_GL_INLINE _GL_ATTRIBUTE_PURE wint_t
+btoc32 (int c)
+{
+ return btowc (c);
+}
+# else
_GL_FUNCDECL_SYS (btoc32, wint_t, (int c) _GL_ATTRIBUTE_PURE);
+# endif
_GL_CXXALIAS_SYS (btoc32, wint_t, (int c));
_GL_CXXALIASWARN (btoc32);
#endif
@@ -134,62 +152,158 @@ _GL_CXXALIASWARN (btoc32);
/* Test a specific property of a 32-bit wide character. */
#if @GNULIB_C32ISALNUM@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISALNUM
+_GL_INLINE int
+c32isalnum (wint_t wc)
+{
+ return iswalnum (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isalnum, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isalnum, int, (wint_t wc));
_GL_CXXALIASWARN (c32isalnum);
#endif
#if @GNULIB_C32ISALPHA@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISALPHA
+_GL_INLINE int
+c32isalpha (wint_t wc)
+{
+ return iswalpha (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isalpha, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isalpha, int, (wint_t wc));
_GL_CXXALIASWARN (c32isalpha);
#endif
#if @GNULIB_C32ISBLANK@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISBLANK
+_GL_INLINE int
+c32isblank (wint_t wc)
+{
+ return iswblank (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isblank, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isblank, int, (wint_t wc));
_GL_CXXALIASWARN (c32isblank);
#endif
#if @GNULIB_C32ISCNTRL@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISCNTRL
+_GL_INLINE int
+c32iscntrl (wint_t wc)
+{
+ return iswcntrl (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32iscntrl, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32iscntrl, int, (wint_t wc));
_GL_CXXALIASWARN (c32iscntrl);
#endif
#if @GNULIB_C32ISDIGIT@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISDIGIT
+_GL_INLINE int
+c32isdigit (wint_t wc)
+{
+ return iswdigit (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isdigit, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isdigit, int, (wint_t wc));
_GL_CXXALIASWARN (c32isdigit);
#endif
#if @GNULIB_C32ISGRAPH@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISGRAPH
+_GL_INLINE int
+c32isgraph (wint_t wc)
+{
+ return iswgraph (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isgraph, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isgraph, int, (wint_t wc));
_GL_CXXALIASWARN (c32isgraph);
#endif
#if @GNULIB_C32ISLOWER@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISLOWER
+_GL_INLINE int
+c32islower (wint_t wc)
+{
+ return iswlower (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32islower, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32islower, int, (wint_t wc));
_GL_CXXALIASWARN (c32islower);
#endif
#if @GNULIB_C32ISPRINT@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISPRINT
+_GL_INLINE int
+c32isprint (wint_t wc)
+{
+ return iswprint (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isprint, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isprint, int, (wint_t wc));
_GL_CXXALIASWARN (c32isprint);
#endif
#if @GNULIB_C32ISPUNCT@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISPUNCT
+_GL_INLINE int
+c32ispunct (wint_t wc)
+{
+ return iswpunct (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32ispunct, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32ispunct, int, (wint_t wc));
_GL_CXXALIASWARN (c32ispunct);
#endif
#if @GNULIB_C32ISSPACE@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISSPACE
+_GL_INLINE int
+c32isspace (wint_t wc)
+{
+ return iswspace (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isspace, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isspace, int, (wint_t wc));
_GL_CXXALIASWARN (c32isspace);
#endif
#if @GNULIB_C32ISUPPER@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISUPPER
+_GL_INLINE int
+c32isupper (wint_t wc)
+{
+ return iswupper (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isupper, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isupper, int, (wint_t wc));
_GL_CXXALIASWARN (c32isupper);
#endif
#if @GNULIB_C32ISXDIGIT@
+# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined
IN_C32ISXDIGIT
+_GL_INLINE int
+c32isxdigit (wint_t wc)
+{
+ return iswxdigit (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32isxdigit, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32isxdigit, int, (wint_t wc));
_GL_CXXALIASWARN (c32isxdigit);
#endif
@@ -224,10 +338,19 @@ _GL_WARN_ON_USE (c32rtomb, "c32rtomb is not portable - "
/* Convert a 32-bit wide string to a string. */
#if @GNULIB_C32SNRTOMBS@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SNRTOMBS
+_GL_INLINE _GL_ARG_NONNULL ((2)) size_t
+c32snrtombs (char *dest, const char32_t **srcp, size_t srclen, size_t len,
+ mbstate_t *ps)
+{
+ return wcsnrtombs (dest, (const wchar_t **) srcp, srclen, len, ps);
+}
+# else
_GL_FUNCDECL_SYS (c32snrtombs, size_t,
(char *dest, const char32_t **srcp, size_t srclen, size_t
len,
mbstate_t *ps)
_GL_ARG_NONNULL ((2)));
+# endif
_GL_CXXALIAS_SYS (c32snrtombs, size_t,
(char *dest, const char32_t **srcp, size_t srclen, size_t
len,
mbstate_t *ps));
@@ -237,9 +360,17 @@ _GL_CXXALIASWARN (c32snrtombs);
/* Convert a 32-bit wide string to a string. */
#if @GNULIB_C32SRTOMBS@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SRTOMBS
+_GL_INLINE _GL_ARG_NONNULL ((2)) size_t
+c32srtombs (char *dest, const char32_t **srcp, size_t len, mbstate_t *ps)
+{
+ return wcsrtombs (dest, (const wchar_t **) srcp, len, ps);
+}
+# else
_GL_FUNCDECL_SYS (c32srtombs, size_t,
(char *dest, const char32_t **srcp, size_t len, mbstate_t
*ps)
_GL_ARG_NONNULL ((2)));
+# endif
_GL_CXXALIAS_SYS (c32srtombs, size_t,
(char *dest, const char32_t **srcp, size_t len,
mbstate_t *ps));
@@ -249,9 +380,20 @@ _GL_CXXALIASWARN (c32srtombs);
/* Convert a 32-bit wide string to a string. */
#if @GNULIB_C32STOMBS@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32STOMBS
+_GL_INLINE _GL_ARG_NONNULL ((2)) size_t
+c32stombs (char *dest, const char32_t *src, size_t len)
+{
+ mbstate_t state;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ return c32srtombs (dest, &src, len, &state);
+}
+# else
_GL_FUNCDECL_SYS (c32stombs, size_t,
(char *dest, const char32_t *src, size_t len)
_GL_ARG_NONNULL ((2)));
+# endif
_GL_CXXALIAS_SYS (c32stombs, size_t,
(char *dest, const char32_t *src, size_t len));
_GL_CXXALIASWARN (c32stombs);
@@ -262,7 +404,15 @@ _GL_CXXALIASWARN (c32stombs);
Returns the single-byte representation of WC if it exists,
or EOF otherwise. */
#if @GNULIB_C32TOB@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32TOB
+_GL_INLINE int
+c32tob (wint_t wc)
+{
+ return wctob (wc);
+}
+# else
_GL_FUNCDECL_SYS (c32tob, int, (wint_t wc));
+# endif
_GL_CXXALIAS_SYS (c32tob, int, (wint_t wc));
_GL_CXXALIASWARN (c32tob);
#endif
@@ -301,10 +451,19 @@ _GL_WARN_ON_USE (mbrtoc32, "mbrtoc32 is not portable - "
/* Convert a string to a 32-bit wide string. */
#if @GNULIB_MBSNRTOC32S@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSNRTOC32S
+_GL_INLINE _GL_ARG_NONNULL ((2)) size_t
+mbsnrtoc32s (char32_t *dest, const char **srcp, size_t srclen, size_t len,
+ mbstate_t *ps)
+{
+ return mbsnrtowcs ((wchar_t *) dest, srcp, srclen, len, ps);
+}
+# else
_GL_FUNCDECL_SYS (mbsnrtoc32s, size_t,
(char32_t *dest, const char **srcp, size_t srclen, size_t
len,
mbstate_t *ps)
_GL_ARG_NONNULL ((2)));
+# endif
_GL_CXXALIAS_SYS (mbsnrtoc32s, size_t,
(char32_t *dest, const char **srcp, size_t srclen, size_t
len,
mbstate_t *ps));
@@ -314,9 +473,17 @@ _GL_CXXALIASWARN (mbsnrtoc32s);
/* Convert a string to a 32-bit wide string. */
#if @GNULIB_MBSRTOC32S@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSRTOC32S
+_GL_INLINE _GL_ARG_NONNULL ((2)) size_t
+mbsrtoc32s (char32_t *dest, const char **srcp, size_t len, mbstate_t *ps)
+{
+ return mbsrtowcs ((wchar_t *) dest, srcp, len, ps);
+}
+# else
_GL_FUNCDECL_SYS (mbsrtoc32s, size_t,
(char32_t *dest, const char **srcp, size_t len, mbstate_t
*ps)
_GL_ARG_NONNULL ((2)));
+# endif
_GL_CXXALIAS_SYS (mbsrtoc32s, size_t,
(char32_t *dest, const char **srcp, size_t len,
mbstate_t *ps));
@@ -326,13 +493,26 @@ _GL_CXXALIASWARN (mbsrtoc32s);
/* Convert a string to a 32-bit wide string. */
#if @GNULIB_MBSTOC32S@
+# if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSTOC32S
+_GL_INLINE _GL_ARG_NONNULL ((2)) size_t
+mbstoc32s (char32_t *dest, const char *src, size_t len)
+{
+ mbstate_t state;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ return mbsrtoc32s (dest, &src, len, &state);
+}
+# else
_GL_FUNCDECL_SYS (mbstoc32s, size_t,
(char32_t *dest, const char *src, size_t len)
_GL_ARG_NONNULL ((2)));
+# endif
_GL_CXXALIAS_SYS (mbstoc32s, size_t,
(char32_t *dest, const char *src, size_t len));
_GL_CXXALIASWARN (mbstoc32s);
#endif
+_GL_INLINE_HEADER_END
+
#endif /* _@GUARD_PREFIX@_UCHAR_H */
diff --git a/modules/uchar b/modules/uchar
index 8cf4cfb5cf..985b58206f 100644
--- a/modules/uchar
+++ b/modules/uchar
@@ -10,6 +10,8 @@ Depends-on:
gen-header
include_next
snippet/c++defs
+extern-inline
+assert-h
stdint
wchar
- *c32*: Inline most functions on glibc and musl libc,
Bruno Haible <=