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 <br...@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