/* substitute - 16-bit and 32-bit wide character types. Copyright (C) 2019-2023 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Written by Bruno Haible , 2019. */ /* * ISO C 23 for platforms that lack it. */ #ifndef _@GUARD_PREFIX@_UCHAR_H #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ #endif @PRAGMA_COLUMNS@ #if @HAVE_UCHAR_H@ # if defined __HAIKU__ /* Work around . */ # include # endif /* On AIX 7.2 with xlclang++, /usr/include/uchar.h produces compilation errors because it contains typedef definitions of char16_t and char32_t, however char16_t and char32_t are keywords in this situation. To work around it, define char16_t and char32_t as macros. */ # if defined __cplusplus && defined _AIX && defined __ibmxl__ && defined __clang__ # define char16_t gl_char16_t # define char32_t gl_char32_t # endif # @INCLUDE_NEXT@ @NEXT_UCHAR_H@ #endif /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _GL_BEGIN_C_LINKAGE, _GL_ATTRIBUTE_PURE, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif /* Get uint_least16_t, uint_least32_t. */ #include /* Get mbstate_t, size_t. */ #include /* For the inline functions. */ #include #include /* The __attribute__ feature is available in gcc versions 2.5 and later. The attribute __pure__ was added in gcc 2.96. */ #ifndef _GL_ATTRIBUTE_PURE # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define _GL_ATTRIBUTE_PURE /* empty */ # endif #endif /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ _GL_INLINE_HEADER_BEGIN #if !(@HAVE_UCHAR_H@ || (defined __cplusplus && @CXX_HAS_CHAR8_TYPE@)) /* An 8-bit variant of wchar_t. Note: This type is only mandated by ISO C 23 or newer, and it does denote UTF-8 units. */ typedef unsigned char char8_t; #elif @GNULIBHEADERS_OVERRIDE_CHAR8_T@ typedef unsigned char gl_char8_t; # define char8_t gl_char8_t #endif #if !(@HAVE_UCHAR_H@ || (defined __cplusplus && @CXX_HAS_UCHAR_TYPES@)) /* A 16-bit variant of wchar_t. Note: This type is only mandated by ISO C 11 or newer. In ISO C 23 and newer, it denotes UTF-16 units; in older versions of ISO C it did so only on platforms on which __STDC_UTF_16__ was defined. */ typedef uint_least16_t char16_t; #elif @GNULIBHEADERS_OVERRIDE_CHAR16_T@ typedef uint_least16_t gl_char16_t; # define char16_t gl_char16_t #endif #if !(@HAVE_UCHAR_H@ || (defined __cplusplus && @CXX_HAS_UCHAR_TYPES@)) /* A 32-bit variant of wchar_t. Note: This type is only mandated by ISO C 11 or newer. In ISO C 23 and newer, it denotes UTF-32 code points; in older versions of ISO C it did so only on platforms on which __STDC_UTF_32__ was defined. */ typedef uint_least32_t char32_t; #elif @GNULIBHEADERS_OVERRIDE_CHAR32_T@ typedef uint_least32_t gl_char32_t; # define char32_t gl_char32_t #endif /* Define if a 'char32_t' can hold more characters than a 'wchar_t'. */ #if @SMALL_WCHAR_T@ /* 32-bit AIX, Cygwin, native Windows */ # 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 . */ #if defined __STDC_ISO_10646__ && !_GL_SMALL_WCHAR_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_BEGIN_C_LINKAGE _GL_INLINE _GL_ATTRIBUTE_PURE wint_t btoc32 (int c) { return btowc (c); } _GL_END_C_LINKAGE # 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 /* 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_BEGIN_C_LINKAGE _GL_INLINE int c32isalnum (wint_t wc) { return iswalnum (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isalpha (wint_t wc) { return iswalpha (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isblank (wint_t wc) { return iswblank (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32iscntrl (wint_t wc) { return iswcntrl (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isdigit (wint_t wc) { return iswdigit (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isgraph (wint_t wc) { return iswgraph (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32islower (wint_t wc) { return iswlower (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isprint (wint_t wc) { return iswprint (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32ispunct (wint_t wc) { return iswpunct (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isspace (wint_t wc) { return iswspace (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isupper (wint_t wc) { return iswupper (wc); } _GL_END_C_LINKAGE # 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_BEGIN_C_LINKAGE _GL_INLINE int c32isxdigit (wint_t wc) { return iswxdigit (wc); } _GL_END_C_LINKAGE # else _GL_FUNCDECL_SYS (c32isxdigit, int, (wint_t wc)); # endif _GL_CXXALIAS_SYS (c32isxdigit, int, (wint_t wc)); _GL_CXXALIASWARN (c32isxdigit); #endif /* Case mapping of a 32-bit wide character. */ #if @GNULIB_C32TOLOWER@ # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32TOLOWER _GL_BEGIN_C_LINKAGE _GL_INLINE wint_t c32tolower (wint_t wc) { return towlower (wc); } _GL_END_C_LINKAGE # else _GL_FUNCDECL_SYS (c32tolower, wint_t, (wint_t wc)); # endif _GL_CXXALIAS_SYS (c32tolower, wint_t, (wint_t wc)); _GL_CXXALIASWARN (c32tolower); #endif #if @GNULIB_C32TOUPPER@ # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32TOUPPER _GL_BEGIN_C_LINKAGE _GL_INLINE wint_t c32toupper (wint_t wc) { return towupper (wc); } _GL_END_C_LINKAGE # else _GL_FUNCDECL_SYS (c32toupper, wint_t, (wint_t wc)); # endif _GL_CXXALIAS_SYS (c32toupper, wint_t, (wint_t wc)); _GL_CXXALIASWARN (c32toupper); #endif /* Number of screen columns needed for a 32-bit wide character. */ #if @GNULIB_C32WIDTH@ # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32WIDTH _GL_BEGIN_C_LINKAGE _GL_INLINE int c32width (char32_t wc) { return wcwidth (wc); } _GL_END_C_LINKAGE # else _GL_FUNCDECL_SYS (c32width, int, (char32_t wc)); # endif _GL_CXXALIAS_SYS (c32width, int, (char32_t wc)); _GL_CXXALIASWARN (c32width); #endif /* Converts a 32-bit wide character to a multibyte character. */ #if @GNULIB_C32RTOMB@ # if @REPLACE_C32RTOMB@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef c32rtomb # define c32rtomb rpl_c32rtomb # endif _GL_FUNCDECL_RPL (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); _GL_CXXALIAS_RPL (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); # else # if !@HAVE_C32RTOMB@ _GL_FUNCDECL_SYS (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); # endif _GL_CXXALIAS_SYS (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); # endif # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 _GL_CXXALIASWARN (c32rtomb); # endif #elif defined GNULIB_POSIXCHECK # undef c32rtomb # if HAVE_RAW_DECL_C32RTOMB _GL_WARN_ON_USE (c32rtomb, "c32rtomb is not portable - " "use gnulib module c32rtomb for portability"); # endif #endif /* Convert a 32-bit wide string to a string. */ #if @GNULIB_C32SNRTOMBS@ # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SNRTOMBS _GL_BEGIN_C_LINKAGE _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); } _GL_END_C_LINKAGE # 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)); _GL_CXXALIASWARN (c32snrtombs); #endif /* Convert a 32-bit wide string to a string. */ #if @GNULIB_C32SRTOMBS@ # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SRTOMBS _GL_BEGIN_C_LINKAGE _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); } _GL_END_C_LINKAGE # 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)); _GL_CXXALIASWARN (c32srtombs); #endif /* Convert a 32-bit wide string to a string. */ #if @GNULIB_C32STOMBS@ # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32STOMBS _GL_BEGIN_C_LINKAGE _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); } _GL_END_C_LINKAGE # 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); #endif /* Number of screen columns needed for a size-bounded 32-bit wide string. */ #if @GNULIB_C32SWIDTH@ # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32SWIDTH _GL_BEGIN_C_LINKAGE _GL_INLINE _GL_ARG_NONNULL ((1)) int c32swidth (const char32_t *s, size_t n) { return wcswidth ((const wchar_t *) s, n); } _GL_END_C_LINKAGE # else _GL_FUNCDECL_SYS (c32swidth, int, (const char32_t *s, size_t n) _GL_ARG_NONNULL ((1))); # endif _GL_CXXALIAS_SYS (c32swidth, int, (const char32_t *s, size_t n)); _GL_CXXALIASWARN (c32swidth); #endif /* Converts a 32-bit wide character to unibyte character. 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_BEGIN_C_LINKAGE _GL_INLINE int c32tob (wint_t wc) { return wctob (wc); } _GL_END_C_LINKAGE # else _GL_FUNCDECL_SYS (c32tob, int, (wint_t wc)); # endif _GL_CXXALIAS_SYS (c32tob, int, (wint_t wc)); _GL_CXXALIASWARN (c32tob); #endif /* Converts a multibyte character to a 32-bit wide character. */ #if @GNULIB_MBRTOC32@ # if @REPLACE_MBRTOC32@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef mbrtoc32 # define mbrtoc32 rpl_mbrtoc32 # endif _GL_FUNCDECL_RPL (mbrtoc32, size_t, (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); _GL_CXXALIAS_RPL (mbrtoc32, size_t, (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); # else # if !@HAVE_MBRTOC32@ _GL_FUNCDECL_SYS (mbrtoc32, size_t, (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); # endif _GL_CXXALIAS_SYS (mbrtoc32, size_t, (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); # endif # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 _GL_CXXALIASWARN (mbrtoc32); # endif #elif defined GNULIB_POSIXCHECK # undef mbrtoc32 # if HAVE_RAW_DECL_MBRTOC32 _GL_WARN_ON_USE (mbrtoc32, "mbrtoc32 is not portable - " "use gnulib module mbrtoc32 for portability"); # endif #endif /* Convert a string to a 32-bit wide string. */ #if @GNULIB_MBSNRTOC32S@ # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSNRTOC32S _GL_BEGIN_C_LINKAGE _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); } _GL_END_C_LINKAGE # 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)); _GL_CXXALIASWARN (mbsnrtoc32s); #endif /* Convert a string to a 32-bit wide string. */ #if @GNULIB_MBSRTOC32S@ # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSRTOC32S _GL_BEGIN_C_LINKAGE _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); } _GL_END_C_LINKAGE # 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)); _GL_CXXALIASWARN (mbsrtoc32s); #endif /* Convert a string to a 32-bit wide string. */ #if @GNULIB_MBSTOC32S@ # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSTOC32S _GL_BEGIN_C_LINKAGE _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); } _GL_END_C_LINKAGE # 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 */