Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/unistr.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
0002 /* Elementary Unicode string functions.
0003    Copyright (C) 2001-2002, 2005-2026 Free Software Foundation, Inc.
0004 
0005    This file is free software: you can redistribute it and/or modify
0006    it under the terms of the GNU Lesser General Public License as
0007    published by the Free Software Foundation; either version 2.1 of the
0008    License, or (at your option) any later version.
0009 
0010    This file is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013    GNU Lesser General Public License for more details.
0014 
0015    You should have received a copy of the GNU Lesser General Public License
0016    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
0017 
0018 #ifndef _UNISTR_H
0019 #define _UNISTR_H
0020 
0021 #include "unitypes.h"
0022 
0023 /* Get common macros for C.  */
0024 #include <unistring/cdefs.h>
0025 
0026 /* Get inline if available.  */
0027 #include <unistring/inline.h>
0028 
0029 /* Get bool.  */
0030 #include <stdbool.h>
0031 
0032 /* Get size_t, ptrdiff_t.  */
0033 #include <stddef.h>
0034 
0035 /* Get free().  */
0036 #include <stdlib.h>
0037 
0038 #ifdef __cplusplus
0039 extern "C" {
0040 #endif
0041 
0042 
0043 /* Conventions:
0044 
0045    All functions prefixed with u8_ operate on UTF-8 encoded strings.
0046    Their unit is an uint8_t (1 byte).
0047 
0048    All functions prefixed with u16_ operate on UTF-16 encoded strings.
0049    Their unit is an uint16_t (a 2-byte word).
0050 
0051    All functions prefixed with u32_ operate on UCS-4 encoded strings.
0052    Their unit is an uint32_t (a 4-byte word).
0053 
0054    All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly
0055    n units.
0056 
0057    All arguments starting with "str" and the arguments of functions starting
0058    with u8_str/u16_str/u32_str denote a NUL terminated string, i.e. a string
0059    which terminates at the first NUL unit.  This termination unit is
0060    considered part of the string for all memory allocation purposes, but
0061    is not considered part of the string for all other logical purposes.
0062 
0063    Functions returning a string result take a (resultbuf, lengthp) argument
0064    pair.  If resultbuf is not NULL and the result fits into *lengthp units,
0065    it is put in resultbuf, and resultbuf is returned.  Otherwise, a freshly
0066    allocated string is returned.  In both cases, *lengthp is set to the
0067    length (number of units) of the returned string.  In case of error,
0068    NULL is returned and errno is set.  */
0069 
0070 
0071 /* Elementary string checks.  */
0072 
0073 /* Check whether an UTF-8 string is well-formed.
0074    Return NULL if valid, or a pointer to the first invalid unit otherwise.  */
0075 extern const uint8_t *
0076        u8_check (const uint8_t *s, size_t n)
0077        _UC_ATTRIBUTE_PURE;
0078 
0079 /* Check whether an UTF-16 string is well-formed.
0080    Return NULL if valid, or a pointer to the first invalid unit otherwise.  */
0081 extern const uint16_t *
0082        u16_check (const uint16_t *s, size_t n)
0083        _UC_ATTRIBUTE_PURE;
0084 
0085 /* Check whether an UCS-4 string is well-formed.
0086    Return NULL if valid, or a pointer to the first invalid unit otherwise.  */
0087 extern const uint32_t *
0088        u32_check (const uint32_t *s, size_t n)
0089        _UC_ATTRIBUTE_PURE;
0090 
0091 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
0092 # ifdef __cplusplus
0093 }
0094 # endif
0095 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
0096    want compiler warnings for 'const' related mistakes.  */
0097 # ifdef __cplusplus
0098 template <typename T>
0099   T * u8_check_template (T* s, size_t n);
0100 template <>
0101   inline uint8_t * u8_check_template (uint8_t *s, size_t n)
0102   { return const_cast<uint8_t *>(u8_check (s, n)); }
0103 template <>
0104   inline const uint8_t * u8_check_template (const uint8_t *s, size_t n)
0105   { return u8_check (s, n); }
0106 #  undef u8_check
0107 #  define u8_check u8_check_template
0108 # elif !defined u8_check
0109 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0110        || defined __ICC  || defined __TINYC__ \
0111        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0112 #   define u8_check(s,n) \
0113       _Generic ((s), \
0114                 uint8_t *: (uint8_t *) u8_check ((s), (n)), \
0115                 default  :             u8_check ((s), (n)))
0116 #  endif
0117 # endif
0118 # ifdef __cplusplus
0119 template <typename T>
0120   T * u16_check_template (T* s, size_t n);
0121 template <>
0122   inline uint16_t * u16_check_template (uint16_t *s, size_t n)
0123   { return const_cast<uint16_t *>(u16_check (s, n)); }
0124 template <>
0125   inline const uint16_t * u16_check_template (const uint16_t *s, size_t n)
0126   { return u16_check (s, n); }
0127 #  undef u16_check
0128 #  define u16_check u16_check_template
0129 # elif !defined u16_check
0130 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0131        || defined __ICC  || defined __TINYC__ \
0132        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0133 #   define u16_check(s,n) \
0134       _Generic ((s), \
0135                 uint16_t *: (uint16_t *) u16_check ((s), (n)), \
0136                 default   :              u16_check ((s), (n)))
0137 #  endif
0138 # endif
0139 # ifdef __cplusplus
0140 template <typename T>
0141   T * u32_check_template (T* s, size_t n);
0142 template <>
0143   inline uint32_t * u32_check_template (uint32_t *s, size_t n)
0144   { return const_cast<uint32_t *>(u32_check (s, n)); }
0145 template <>
0146   inline const uint32_t * u32_check_template (const uint32_t *s, size_t n)
0147   { return u32_check (s, n); }
0148 #  undef u32_check
0149 #  define u32_check u32_check_template
0150 # elif !defined u32_check
0151 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0152        || defined __ICC  || defined __TINYC__ \
0153        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0154 #   define u32_check(s,n) \
0155       _Generic ((s), \
0156                 uint32_t *: (uint32_t *) u32_check ((s), (n)), \
0157                 default   :              u32_check ((s), (n)))
0158 #  endif
0159 # endif
0160 # ifdef __cplusplus
0161 extern "C" {
0162 # endif
0163 #endif
0164 
0165 
0166 /* Elementary string conversions.  */
0167 
0168 /* Convert an UTF-8 string to an UTF-16 string.  */
0169 extern uint16_t *
0170        u8_to_u16 (const uint8_t *s, size_t n, uint16_t *resultbuf,
0171                   size_t *lengthp);
0172 
0173 /* Convert an UTF-8 string to an UCS-4 string.  */
0174 extern uint32_t *
0175        u8_to_u32 (const uint8_t *s, size_t n, uint32_t *resultbuf,
0176                   size_t *lengthp);
0177 
0178 /* Convert an UTF-16 string to an UTF-8 string.  */
0179 extern uint8_t *
0180        u16_to_u8 (const uint16_t *s, size_t n, uint8_t *resultbuf,
0181                   size_t *lengthp);
0182 
0183 /* Convert an UTF-16 string to an UCS-4 string.  */
0184 extern uint32_t *
0185        u16_to_u32 (const uint16_t *s, size_t n, uint32_t *resultbuf,
0186                    size_t *lengthp);
0187 
0188 /* Convert an UCS-4 string to an UTF-8 string.  */
0189 extern uint8_t *
0190        u32_to_u8 (const uint32_t *s, size_t n, uint8_t *resultbuf,
0191                   size_t *lengthp);
0192 
0193 /* Convert an UCS-4 string to an UTF-16 string.  */
0194 extern uint16_t *
0195        u32_to_u16 (const uint32_t *s, size_t n, uint16_t *resultbuf,
0196                    size_t *lengthp);
0197 
0198 
0199 /* Elementary string functions.  */
0200 
0201 /* Return the length (number of units) of the first character in S, which is
0202    no longer than N.  Return 0 if it is the NUL character.  Return -1 upon
0203    failure.  */
0204 /* Similar to mblen(), except that s must not be NULL.  */
0205 extern int
0206        u8_mblen (const uint8_t *s, size_t n)
0207        _UC_ATTRIBUTE_PURE;
0208 extern int
0209        u16_mblen (const uint16_t *s, size_t n)
0210        _UC_ATTRIBUTE_PURE;
0211 extern int
0212        u32_mblen (const uint32_t *s, size_t n)
0213        _UC_ATTRIBUTE_PURE;
0214 
0215 /* Return the length (number of units) of the first character in S, putting
0216    its 'ucs4_t' representation in *PUC.  Upon failure, *PUC is set to 0xfffd,
0217    and an appropriate number of units is returned.
0218    The number of available units, N, must be > 0.  */
0219 /* Similar to mbtowc(), except that puc and s must not be NULL, n must be > 0,
0220    and the NUL character is not treated specially.  */
0221 /* The variants with _unsafe suffix are for backward compatibility with
0222    libunistring versions < 0.9.7.  */
0223 
0224 #if 1
0225 # if !UNISTRING_HAVE_INLINE
0226 extern int
0227        u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n);
0228 # else
0229 extern int
0230        u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n);
0231 static inline int
0232 u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n)
0233 {
0234   uint8_t c = *s;
0235 
0236   if (c < 0x80)
0237     {
0238       *puc = c;
0239       return 1;
0240     }
0241   else
0242     return u8_mbtouc_unsafe_aux (puc, s, n);
0243 }
0244 # endif
0245 #endif
0246 
0247 #if 1
0248 # if !UNISTRING_HAVE_INLINE
0249 extern int
0250        u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n);
0251 # else
0252 extern int
0253        u16_mbtouc_unsafe_aux (ucs4_t *puc, const uint16_t *s, size_t n);
0254 static inline int
0255 u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n)
0256 {
0257   uint16_t c = *s;
0258 
0259   if (c < 0xd800 || c >= 0xe000)
0260     {
0261       *puc = c;
0262       return 1;
0263     }
0264   else
0265     return u16_mbtouc_unsafe_aux (puc, s, n);
0266 }
0267 # endif
0268 #endif
0269 
0270 #if 1
0271 # if !UNISTRING_HAVE_INLINE
0272 extern int
0273        u32_mbtouc_unsafe (ucs4_t *puc, const uint32_t *s, size_t n);
0274 # else
0275 static inline int
0276 u32_mbtouc_unsafe (ucs4_t *puc,
0277                    const uint32_t *s, size_t _GL_UNNAMED (n))
0278 {
0279   uint32_t c = *s;
0280 
0281   if (c < 0xd800 || (c >= 0xe000 && c < 0x110000))
0282     *puc = c;
0283   else
0284     /* invalid multibyte character */
0285     *puc = 0xfffd;
0286   return 1;
0287 }
0288 # endif
0289 #endif
0290 
0291 #if 1
0292 # if !UNISTRING_HAVE_INLINE
0293 extern int
0294        u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n);
0295 # else
0296 extern int
0297        u8_mbtouc_aux (ucs4_t *puc, const uint8_t *s, size_t n);
0298 static inline int
0299 u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n)
0300 {
0301   uint8_t c = *s;
0302 
0303   if (c < 0x80)
0304     {
0305       *puc = c;
0306       return 1;
0307     }
0308   else
0309     return u8_mbtouc_aux (puc, s, n);
0310 }
0311 # endif
0312 #endif
0313 
0314 #if 1
0315 # if !UNISTRING_HAVE_INLINE
0316 extern int
0317        u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n);
0318 # else
0319 extern int
0320        u16_mbtouc_aux (ucs4_t *puc, const uint16_t *s, size_t n);
0321 static inline int
0322 u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n)
0323 {
0324   uint16_t c = *s;
0325 
0326   if (c < 0xd800 || c >= 0xe000)
0327     {
0328       *puc = c;
0329       return 1;
0330     }
0331   else
0332     return u16_mbtouc_aux (puc, s, n);
0333 }
0334 # endif
0335 #endif
0336 
0337 #if 1
0338 # if !UNISTRING_HAVE_INLINE
0339 extern int
0340        u32_mbtouc (ucs4_t *puc, const uint32_t *s, size_t n);
0341 # else
0342 static inline int
0343 u32_mbtouc (ucs4_t *puc, const uint32_t *s,
0344             size_t _GL_UNNAMED (n))
0345 {
0346   uint32_t c = *s;
0347 
0348   if (c < 0xd800 || (c >= 0xe000 && c < 0x110000))
0349     *puc = c;
0350   else
0351     /* invalid multibyte character */
0352     *puc = 0xfffd;
0353   return 1;
0354 }
0355 # endif
0356 #endif
0357 
0358 /* Return the length (number of units) of the first character in S, putting
0359    its 'ucs4_t' representation in *PUC.  Upon failure, *PUC is set to 0xfffd,
0360    and -1 is returned for an invalid sequence of units, -2 is returned for an
0361    incomplete sequence of units.
0362    The number of available units, N, must be > 0.  */
0363 /* Similar to u*_mbtouc(), except that the return value gives more details
0364    about the failure, similar to mbrtowc().  */
0365 
0366 #if 1
0367 extern int
0368        u8_mbtoucr (ucs4_t *puc, const uint8_t *s, size_t n);
0369 #endif
0370 
0371 #if 1
0372 extern int
0373        u16_mbtoucr (ucs4_t *puc, const uint16_t *s, size_t n);
0374 #endif
0375 
0376 #if 1
0377 extern int
0378        u32_mbtoucr (ucs4_t *puc, const uint32_t *s, size_t n);
0379 #endif
0380 
0381 /* Put the multibyte character represented by UC in S, returning its
0382    length.  Return -1 upon failure, -2 if the number of available units, N,
0383    is too small.  The latter case cannot occur if N >= 6/2/1, respectively.  */
0384 /* Similar to wctomb(), except that s must not be NULL, and the argument n
0385    must be specified.  */
0386 
0387 #if 1
0388 /* Auxiliary function, also used by u8_chr, u8_strchr, u8_strrchr.  */
0389 extern int
0390        u8_uctomb_aux (uint8_t *s, ucs4_t uc, ptrdiff_t n);
0391 # if !UNISTRING_HAVE_INLINE
0392 extern int
0393        u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n);
0394 # else
0395 static inline int
0396 u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n)
0397 {
0398   if (uc < 0x80 && n > 0)
0399     {
0400       s[0] = uc;
0401       return 1;
0402     }
0403   else
0404     return u8_uctomb_aux (s, uc, n);
0405 }
0406 # endif
0407 #endif
0408 
0409 #if 1
0410 /* Auxiliary function, also used by u16_chr, u16_strchr, u16_strrchr.  */
0411 extern int
0412        u16_uctomb_aux (uint16_t *s, ucs4_t uc, ptrdiff_t n);
0413 # if !UNISTRING_HAVE_INLINE
0414 extern int
0415        u16_uctomb (uint16_t *s, ucs4_t uc, ptrdiff_t n);
0416 # else
0417 static inline int
0418 u16_uctomb (uint16_t *s, ucs4_t uc, ptrdiff_t n)
0419 {
0420   if (uc < 0xd800 && n > 0)
0421     {
0422       s[0] = uc;
0423       return 1;
0424     }
0425   else
0426     return u16_uctomb_aux (s, uc, n);
0427 }
0428 # endif
0429 #endif
0430 
0431 #if 1
0432 # if !UNISTRING_HAVE_INLINE
0433 extern int
0434        u32_uctomb (uint32_t *s, ucs4_t uc, ptrdiff_t n);
0435 # else
0436 static inline int
0437 u32_uctomb (uint32_t *s, ucs4_t uc, ptrdiff_t n)
0438 {
0439   if (uc < 0xd800 || (uc >= 0xe000 && uc < 0x110000))
0440     {
0441       if (n > 0)
0442         {
0443           *s = uc;
0444           return 1;
0445         }
0446       else
0447         return -2;
0448     }
0449   else
0450     return -1;
0451 }
0452 # endif
0453 #endif
0454 
0455 /* Copy N units from SRC to DEST.  */
0456 /* Similar to memcpy().  */
0457 extern uint8_t *
0458        u8_cpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
0459 extern uint16_t *
0460        u16_cpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
0461 extern uint32_t *
0462        u32_cpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
0463 
0464 /* Copy N units from SRC to DEST, returning pointer after last written unit.  */
0465 /* Similar to mempcpy().  */
0466 extern uint8_t *
0467        u8_pcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
0468 extern uint16_t *
0469        u16_pcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
0470 extern uint32_t *
0471        u32_pcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
0472 
0473 /* Copy N units from SRC to DEST, guaranteeing correct behavior for
0474    overlapping memory areas.  */
0475 /* Similar to memmove().  */
0476 extern uint8_t *
0477        u8_move (uint8_t *dest, const uint8_t *src, size_t n);
0478 extern uint16_t *
0479        u16_move (uint16_t *dest, const uint16_t *src, size_t n);
0480 extern uint32_t *
0481        u32_move (uint32_t *dest, const uint32_t *src, size_t n);
0482 
0483 /* Set the first N characters of S to UC.  UC should be a character that
0484    occupies only 1 unit.  */
0485 /* Similar to memset().  */
0486 extern uint8_t *
0487        u8_set (uint8_t *s, ucs4_t uc, size_t n);
0488 extern uint16_t *
0489        u16_set (uint16_t *s, ucs4_t uc, size_t n);
0490 extern uint32_t *
0491        u32_set (uint32_t *s, ucs4_t uc, size_t n);
0492 
0493 /* Compare S1 and S2, each of length N.  */
0494 /* Similar to memcmp().  */
0495 extern int
0496        u8_cmp (const uint8_t *s1, const uint8_t *s2, size_t n)
0497        _UC_ATTRIBUTE_PURE;
0498 extern int
0499        u16_cmp (const uint16_t *s1, const uint16_t *s2, size_t n)
0500        _UC_ATTRIBUTE_PURE;
0501 extern int
0502        u32_cmp (const uint32_t *s1, const uint32_t *s2, size_t n)
0503        _UC_ATTRIBUTE_PURE;
0504 
0505 /* Compare S1 and S2.  */
0506 /* Similar to the gnulib function memcmp2().  */
0507 extern int
0508        u8_cmp2 (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2)
0509        _UC_ATTRIBUTE_PURE;
0510 extern int
0511        u16_cmp2 (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2)
0512        _UC_ATTRIBUTE_PURE;
0513 extern int
0514        u32_cmp2 (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2)
0515        _UC_ATTRIBUTE_PURE;
0516 
0517 /* Search the string at S for UC.  */
0518 /* Similar to memchr().  */
0519 extern uint8_t *
0520        u8_chr (const uint8_t *s, size_t n, ucs4_t uc)
0521        _UC_ATTRIBUTE_PURE;
0522 extern uint16_t *
0523        u16_chr (const uint16_t *s, size_t n, ucs4_t uc)
0524        _UC_ATTRIBUTE_PURE;
0525 extern uint32_t *
0526        u32_chr (const uint32_t *s, size_t n, ucs4_t uc)
0527        _UC_ATTRIBUTE_PURE;
0528 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
0529 # ifdef __cplusplus
0530 }
0531 # endif
0532 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
0533    want compiler warnings for 'const' related mistakes.  */
0534 # ifdef __cplusplus
0535 template <typename T>
0536   T * u8_chr_template (T* str, size_t n, ucs4_t uc);
0537 template <>
0538   inline uint8_t * u8_chr_template (uint8_t *str, size_t n, ucs4_t uc)
0539   { return u8_chr (str, n, uc); }
0540 template <>
0541   inline const uint8_t * u8_chr_template (const uint8_t *str, size_t n, ucs4_t uc)
0542   { return u8_chr (str, n, uc); }
0543 #  undef u8_chr
0544 #  define u8_chr u8_chr_template
0545 # elif !defined u8_chr
0546 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0547        || defined __ICC  || defined __TINYC__ \
0548        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0549 #   define u8_chr(s,n,u) \
0550       _Generic ((s), \
0551                 uint8_t const *: (uint8_t const *) u8_chr ((s), (n), (u)), \
0552                 default        :                   u8_chr ((s), (n), (u)))
0553 #  endif
0554 # endif
0555 # ifdef __cplusplus
0556 template <typename T>
0557   T * u16_chr_template (T* str, size_t n, ucs4_t uc);
0558 template <>
0559   inline uint16_t * u16_chr_template (uint16_t *str, size_t n, ucs4_t uc)
0560   { return u16_chr (str, n, uc); }
0561 template <>
0562   inline const uint16_t * u16_chr_template (const uint16_t *str, size_t n, ucs4_t uc)
0563   { return u16_chr (str, n, uc); }
0564 #  undef u16_chr
0565 #  define u16_chr u16_chr_template
0566 # elif !defined u16_chr
0567 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0568        || defined __ICC  || defined __TINYC__ \
0569        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0570 #   define u16_chr(s,n,u) \
0571       _Generic ((s), \
0572                 uint16_t const *: (uint16_t const *) u16_chr ((s), (n), (u)), \
0573                 default         :                    u16_chr ((s), (n), (u)))
0574 #  endif
0575 # endif
0576 # ifdef __cplusplus
0577 template <typename T>
0578   T * u32_chr_template (T* str, size_t n, ucs4_t uc);
0579 template <>
0580   inline uint32_t * u32_chr_template (uint32_t *str, size_t n, ucs4_t uc)
0581   { return u32_chr (str, n, uc); }
0582 template <>
0583   inline const uint32_t * u32_chr_template (const uint32_t *str, size_t n, ucs4_t uc)
0584   { return u32_chr (str, n, uc); }
0585 #  undef u32_chr
0586 #  define u32_chr u32_chr_template
0587 # elif !defined u32_chr
0588 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0589        || defined __ICC  || defined __TINYC__ \
0590        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0591 #   define u32_chr(s,n,u) \
0592       _Generic ((s), \
0593                 uint32_t const *: (uint32_t const *) u32_chr ((s), (n), (u)), \
0594                 default         :                    u32_chr ((s), (n), (u)))
0595 #  endif
0596 # endif
0597 # ifdef __cplusplus
0598 extern "C" {
0599 # endif
0600 #endif
0601 
0602 /* Count the number of Unicode characters in the N units from S.  */
0603 /* Similar to mbsnlen().  */
0604 extern size_t
0605        u8_mbsnlen (const uint8_t *s, size_t n)
0606        _UC_ATTRIBUTE_PURE;
0607 extern size_t
0608        u16_mbsnlen (const uint16_t *s, size_t n)
0609        _UC_ATTRIBUTE_PURE;
0610 extern size_t
0611        u32_mbsnlen (const uint32_t *s, size_t n)
0612        _UC_ATTRIBUTE_PURE;
0613 
0614 /* Elementary string functions with memory allocation.  */
0615 
0616 /* Make a freshly allocated copy of S, of length N.  */
0617 extern uint8_t *
0618        u8_cpy_alloc (const uint8_t *s, size_t n);
0619 extern uint16_t *
0620        u16_cpy_alloc (const uint16_t *s, size_t n);
0621 extern uint32_t *
0622        u32_cpy_alloc (const uint32_t *s, size_t n);
0623 
0624 /* Elementary string functions on NUL terminated strings.  */
0625 
0626 /* Return the length (number of units) of the first character in S.
0627    Return 0 if it is the NUL character.  Return -1 upon failure.  */
0628 extern int
0629        u8_strmblen (const uint8_t *s)
0630        _UC_ATTRIBUTE_PURE;
0631 extern int
0632        u16_strmblen (const uint16_t *s)
0633        _UC_ATTRIBUTE_PURE;
0634 extern int
0635        u32_strmblen (const uint32_t *s)
0636        _UC_ATTRIBUTE_PURE;
0637 
0638 /* Return the length (number of units) of the first character in S, putting
0639    its 'ucs4_t' representation in *PUC.  Return 0 if it is the NUL
0640    character.  Return -1 upon failure.  */
0641 extern int
0642        u8_strmbtouc (ucs4_t *puc, const uint8_t *s);
0643 extern int
0644        u16_strmbtouc (ucs4_t *puc, const uint16_t *s);
0645 extern int
0646        u32_strmbtouc (ucs4_t *puc, const uint32_t *s);
0647 
0648 /* Forward iteration step.  Advances the pointer past the next character,
0649    or returns NULL if the end of the string has been reached.  Puts the
0650    character's 'ucs4_t' representation in *PUC.  */
0651 extern const uint8_t *
0652        u8_next (ucs4_t *puc, const uint8_t *s);
0653 extern const uint16_t *
0654        u16_next (ucs4_t *puc, const uint16_t *s);
0655 extern const uint32_t *
0656        u32_next (ucs4_t *puc, const uint32_t *s);
0657 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
0658 # ifdef __cplusplus
0659 }
0660 # endif
0661 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
0662    want compiler warnings for 'const' related mistakes.  */
0663 # ifdef __cplusplus
0664 template <typename T>
0665   T * u8_next_template (ucs4_t *puc, T* s);
0666 template <>
0667   inline uint8_t * u8_next_template (ucs4_t *puc, uint8_t *s)
0668   { return const_cast<uint8_t *>(u8_next (puc, s)); }
0669 template <>
0670   inline const uint8_t * u8_next_template (ucs4_t *puc, const uint8_t *s)
0671   { return u8_next (puc, s); }
0672 #  undef u8_next
0673 #  define u8_next u8_next_template
0674 # elif !defined u8_next
0675 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0676        || defined __ICC  || defined __TINYC__ \
0677        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0678 #   define u8_next(p,s) \
0679       _Generic ((s), \
0680                 uint8_t *: (uint8_t *) u8_next ((p), (s)), \
0681                 default  :             u8_next ((p), (s)))
0682 #  endif
0683 # endif
0684 # ifdef __cplusplus
0685 template <typename T>
0686   T * u16_next_template (ucs4_t *puc, T* s);
0687 template <>
0688   inline uint16_t * u16_next_template (ucs4_t *puc, uint16_t *s)
0689   { return const_cast<uint16_t *>(u16_next (puc, s)); }
0690 template <>
0691   inline const uint16_t * u16_next_template (ucs4_t *puc, const uint16_t *s)
0692   { return u16_next (puc, s); }
0693 #  undef u16_next
0694 #  define u16_next u16_next_template
0695 # elif !defined u16_next
0696 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0697        || defined __ICC  || defined __TINYC__ \
0698        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0699 #   define u16_next(p,s) \
0700       _Generic ((s), \
0701                 uint16_t *: (uint16_t *) u16_next ((p), (s)), \
0702                 default   :              u16_next ((p), (s)))
0703 #  endif
0704 # endif
0705 # ifdef __cplusplus
0706 template <typename T>
0707   T * u32_next_template (ucs4_t *puc, T* s);
0708 template <>
0709   inline uint32_t * u32_next_template (ucs4_t *puc, uint32_t *s)
0710   { return const_cast<uint32_t *>(u32_next (puc, s)); }
0711 template <>
0712   inline const uint32_t * u32_next_template (ucs4_t *puc, const uint32_t *s)
0713   { return u32_next (puc, s); }
0714 #  undef u32_next
0715 #  define u32_next u32_next_template
0716 # elif !defined u32_next
0717 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0718        || defined __ICC  || defined __TINYC__ \
0719        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0720 #   define u32_next(p,s) \
0721       _Generic ((s), \
0722                 uint32_t *: (uint32_t *) u32_next ((p), (s)), \
0723                 default   :              u32_next ((p), (s)))
0724 #  endif
0725 # endif
0726 # ifdef __cplusplus
0727 extern "C" {
0728 # endif
0729 #endif
0730 
0731 /* Backward iteration step.  Advances the pointer to point to the previous
0732    character, or returns NULL if the beginning of the string had been reached.
0733    Puts the character's 'ucs4_t' representation in *PUC.  */
0734 extern const uint8_t *
0735        u8_prev (ucs4_t *puc, const uint8_t *s, const uint8_t *start);
0736 extern const uint16_t *
0737        u16_prev (ucs4_t *puc, const uint16_t *s, const uint16_t *start);
0738 extern const uint32_t *
0739        u32_prev (ucs4_t *puc, const uint32_t *s, const uint32_t *start);
0740 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
0741 # ifdef __cplusplus
0742 }
0743 # endif
0744 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
0745    want compiler warnings for 'const' related mistakes.  */
0746 # ifdef __cplusplus
0747 template <typename T>
0748   T * u8_prev_template (ucs4_t *puc, T* s, const uint8_t *start);
0749 template <>
0750   inline uint8_t * u8_prev_template (ucs4_t *puc, uint8_t *s, const uint8_t *start)
0751   { return const_cast<uint8_t *>(u8_prev (puc, s, start)); }
0752 template <>
0753   inline const uint8_t * u8_prev_template (ucs4_t *puc, const uint8_t *s, const uint8_t *start)
0754   { return u8_prev (puc, s, start); }
0755 #  undef u8_prev
0756 #  define u8_prev u8_prev_template
0757 # elif !defined u8_prev
0758 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0759        || defined __ICC  || defined __TINYC__ \
0760        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0761 #   define u8_prev(p,s,start) \
0762       _Generic ((s), \
0763                 uint8_t *: (uint8_t *) u8_prev ((p), (s), (start)), \
0764                 default  :             u8_prev ((p), (s), (start)))
0765 #  endif
0766 # endif
0767 # ifdef __cplusplus
0768 template <typename T>
0769   T * u16_prev_template (ucs4_t *puc, T* s, const uint16_t *start);
0770 template <>
0771   inline uint16_t * u16_prev_template (ucs4_t *puc, uint16_t *s, const uint16_t *start)
0772   { return const_cast<uint16_t *>(u16_prev (puc, s, start)); }
0773 template <>
0774   inline const uint16_t * u16_prev_template (ucs4_t *puc, const uint16_t *s, const uint16_t *start)
0775   { return u16_prev (puc, s, start); }
0776 #  undef u16_prev
0777 #  define u16_prev u16_prev_template
0778 # elif !defined u16_prev
0779 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0780        || defined __ICC  || defined __TINYC__ \
0781        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0782 #   define u16_prev(p,s,start) \
0783       _Generic ((s), \
0784                 uint16_t *: (uint16_t *) u16_prev ((p), (s), (start)), \
0785                 default   :              u16_prev ((p), (s), (start)))
0786 #  endif
0787 # endif
0788 # ifdef __cplusplus
0789 template <typename T>
0790   T * u32_prev_template (ucs4_t *puc, T* s, const uint32_t *start);
0791 template <>
0792   inline uint32_t * u32_prev_template (ucs4_t *puc, uint32_t *s, const uint32_t *start)
0793   { return const_cast<uint32_t *>(u32_prev (puc, s, start)); }
0794 template <>
0795   inline const uint32_t * u32_prev_template (ucs4_t *puc, const uint32_t *s, const uint32_t *start)
0796   { return u32_prev (puc, s, start); }
0797 #  undef u32_prev
0798 #  define u32_prev u32_prev_template
0799 # elif !defined u32_prev
0800 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0801        || defined __ICC  || defined __TINYC__ \
0802        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0803 #   define u32_prev(p,s,start) \
0804       _Generic ((s), \
0805                 uint32_t *: (uint32_t *) u32_prev ((p), (s), (start)), \
0806                 default   :              u32_prev ((p), (s), (start)))
0807 #  endif
0808 # endif
0809 # ifdef __cplusplus
0810 extern "C" {
0811 # endif
0812 #endif
0813 
0814 /* Return the number of units in S.  */
0815 /* Similar to strlen(), wcslen().  */
0816 extern size_t
0817        u8_strlen (const uint8_t *s)
0818        _UC_ATTRIBUTE_PURE;
0819 extern size_t
0820        u16_strlen (const uint16_t *s)
0821        _UC_ATTRIBUTE_PURE;
0822 extern size_t
0823        u32_strlen (const uint32_t *s)
0824        _UC_ATTRIBUTE_PURE;
0825 
0826 /* Return the number of units in S, but at most MAXLEN.  */
0827 /* Similar to strnlen(), wcsnlen().  */
0828 extern size_t
0829        u8_strnlen (const uint8_t *s, size_t maxlen)
0830        _UC_ATTRIBUTE_PURE;
0831 extern size_t
0832        u16_strnlen (const uint16_t *s, size_t maxlen)
0833        _UC_ATTRIBUTE_PURE;
0834 extern size_t
0835        u32_strnlen (const uint32_t *s, size_t maxlen)
0836        _UC_ATTRIBUTE_PURE;
0837 
0838 /* Copy SRC to DEST.  */
0839 /* Similar to strcpy(), wcscpy().  */
0840 extern uint8_t *
0841        u8_strcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
0842 extern uint16_t *
0843        u16_strcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
0844 extern uint32_t *
0845        u32_strcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
0846 
0847 /* Copy SRC to DEST, returning the address of the terminating NUL in DEST.  */
0848 /* Similar to stpcpy().  */
0849 extern uint8_t *
0850        u8_stpcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
0851 extern uint16_t *
0852        u16_stpcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
0853 extern uint32_t *
0854        u32_stpcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
0855 
0856 /* Copy no more than N units of SRC to DEST.  */
0857 /* Similar to strncpy(), wcsncpy().  */
0858 extern uint8_t *
0859        u8_strncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
0860 extern uint16_t *
0861        u16_strncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
0862 extern uint32_t *
0863        u32_strncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
0864 
0865 /* Copy no more than N units of SRC to DEST.  Return a pointer past the last
0866    non-NUL unit written into DEST.  */
0867 /* Similar to stpncpy().  */
0868 extern uint8_t *
0869        u8_stpncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
0870 extern uint16_t *
0871        u16_stpncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
0872 extern uint32_t *
0873        u32_stpncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
0874 
0875 /* Append SRC onto DEST.  */
0876 /* Similar to strcat(), wcscat().  */
0877 extern uint8_t *
0878        u8_strcat (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
0879 extern uint16_t *
0880        u16_strcat (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
0881 extern uint32_t *
0882        u32_strcat (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
0883 
0884 /* Append no more than N units of SRC onto DEST.  */
0885 /* Similar to strncat(), wcsncat().  */
0886 extern uint8_t *
0887        u8_strncat (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
0888 extern uint16_t *
0889        u16_strncat (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
0890 extern uint32_t *
0891        u32_strncat (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
0892 
0893 /* Compare S1 and S2.  */
0894 /* Similar to strcmp(), wcscmp().  */
0895 #ifdef __sun
0896 /* Avoid a collision with the u8_strcmp() function in Solaris 11 libc.  */
0897 extern int
0898        u8_strcmp_gnu (const uint8_t *s1, const uint8_t *s2)
0899        _UC_ATTRIBUTE_PURE;
0900 # define u8_strcmp u8_strcmp_gnu
0901 #else
0902 extern int
0903        u8_strcmp (const uint8_t *s1, const uint8_t *s2)
0904        _UC_ATTRIBUTE_PURE;
0905 #endif
0906 extern int
0907        u16_strcmp (const uint16_t *s1, const uint16_t *s2)
0908        _UC_ATTRIBUTE_PURE;
0909 extern int
0910        u32_strcmp (const uint32_t *s1, const uint32_t *s2)
0911        _UC_ATTRIBUTE_PURE;
0912 
0913 /* Compare S1 and S2 using the collation rules of the current locale.
0914    Return -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2.
0915    Upon failure, set errno and return any value.  */
0916 /* Similar to strcoll(), wcscoll().  */
0917 extern int
0918        u8_strcoll (const uint8_t *s1, const uint8_t *s2);
0919 extern int
0920        u16_strcoll (const uint16_t *s1, const uint16_t *s2);
0921 extern int
0922        u32_strcoll (const uint32_t *s1, const uint32_t *s2);
0923 
0924 /* Compare no more than N units of S1 and S2.  */
0925 /* Similar to strncmp(), wcsncmp().  */
0926 extern int
0927        u8_strncmp (const uint8_t *s1, const uint8_t *s2, size_t n)
0928        _UC_ATTRIBUTE_PURE;
0929 extern int
0930        u16_strncmp (const uint16_t *s1, const uint16_t *s2, size_t n)
0931        _UC_ATTRIBUTE_PURE;
0932 extern int
0933        u32_strncmp (const uint32_t *s1, const uint32_t *s2, size_t n)
0934        _UC_ATTRIBUTE_PURE;
0935 
0936 /* Duplicate S, returning an identical malloc'd string.  */
0937 /* Similar to strdup(), wcsdup().  */
0938 extern uint8_t *
0939        u8_strdup (const uint8_t *s)
0940        _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
0941 extern uint16_t *
0942        u16_strdup (const uint16_t *s)
0943        _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
0944 extern uint32_t *
0945        u32_strdup (const uint32_t *s)
0946        _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
0947 
0948 /* Find the first occurrence of UC in STR.  */
0949 /* Similar to strchr(), wcschr().  */
0950 extern uint8_t *
0951        u8_strchr (const uint8_t *str, ucs4_t uc)
0952        _UC_ATTRIBUTE_PURE;
0953 extern uint16_t *
0954        u16_strchr (const uint16_t *str, ucs4_t uc)
0955        _UC_ATTRIBUTE_PURE;
0956 extern uint32_t *
0957        u32_strchr (const uint32_t *str, ucs4_t uc)
0958        _UC_ATTRIBUTE_PURE;
0959 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
0960 # ifdef __cplusplus
0961 }
0962 # endif
0963 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
0964    want compiler warnings for 'const' related mistakes.  */
0965 # ifdef __cplusplus
0966 template <typename T>
0967   T * u8_strchr_template (T* str, ucs4_t uc);
0968 template <>
0969   inline uint8_t * u8_strchr_template (uint8_t *str, ucs4_t uc)
0970   { return u8_strchr (str, uc); }
0971 template <>
0972   inline const uint8_t * u8_strchr_template (const uint8_t *str, ucs4_t uc)
0973   { return u8_strchr (str, uc); }
0974 #  undef u8_strchr
0975 #  define u8_strchr u8_strchr_template
0976 # elif !defined u8_strchr
0977 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0978        || defined __ICC  || defined __TINYC__ \
0979        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
0980 #   define u8_strchr(s,u) \
0981       _Generic ((s), \
0982                 uint8_t const *: (uint8_t const *) u8_strchr ((s), (u)), \
0983                 default        :                   u8_strchr ((s), (u)))
0984 #  endif
0985 # endif
0986 # ifdef __cplusplus
0987 template <typename T>
0988   T * u16_strchr_template (T* str, ucs4_t uc);
0989 template <>
0990   inline uint16_t * u16_strchr_template (uint16_t *str, ucs4_t uc)
0991   { return u16_strchr (str, uc); }
0992 template <>
0993   inline const uint16_t * u16_strchr_template (const uint16_t *str, ucs4_t uc)
0994   { return u16_strchr (str, uc); }
0995 #  undef u16_strchr
0996 #  define u16_strchr u16_strchr_template
0997 # elif !defined u16_strchr
0998 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
0999        || defined __ICC  || defined __TINYC__ \
1000        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1001 #   define u16_strchr(s,u) \
1002       _Generic ((s), \
1003                 uint16_t const *: (uint16_t const *) u16_strchr ((s), (u)), \
1004                 default         :                    u16_strchr ((s), (u)))
1005 #  endif
1006 # endif
1007 # ifdef __cplusplus
1008 template <typename T>
1009   T * u32_strchr_template (T* str, ucs4_t uc);
1010 template <>
1011   inline uint32_t * u32_strchr_template (uint32_t *str, ucs4_t uc)
1012   { return u32_strchr (str, uc); }
1013 template <>
1014   inline const uint32_t * u32_strchr_template (const uint32_t *str, ucs4_t uc)
1015   { return u32_strchr (str, uc); }
1016 #  undef u32_strchr
1017 #  define u32_strchr u32_strchr_template
1018 # elif !defined u32_strchr
1019 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1020        || defined __ICC  || defined __TINYC__ \
1021        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1022 #   define u32_strchr(s,u) \
1023       _Generic ((s), \
1024                 uint32_t const *: (uint32_t const *) u32_strchr ((s), (u)), \
1025                 default         :                    u32_strchr ((s), (u)))
1026 #  endif
1027 # endif
1028 # ifdef __cplusplus
1029 extern "C" {
1030 # endif
1031 #endif
1032 
1033 /* Find the last occurrence of UC in STR.  */
1034 /* Similar to strrchr(), wcsrchr().  */
1035 extern uint8_t *
1036        u8_strrchr (const uint8_t *str, ucs4_t uc)
1037        _UC_ATTRIBUTE_PURE;
1038 extern uint16_t *
1039        u16_strrchr (const uint16_t *str, ucs4_t uc)
1040        _UC_ATTRIBUTE_PURE;
1041 extern uint32_t *
1042        u32_strrchr (const uint32_t *str, ucs4_t uc)
1043        _UC_ATTRIBUTE_PURE;
1044 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
1045 # ifdef __cplusplus
1046 }
1047 # endif
1048 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
1049    want compiler warnings for 'const' related mistakes.  */
1050 # ifdef __cplusplus
1051 template <typename T>
1052   T * u8_strrchr_template (T* str, ucs4_t uc);
1053 template <>
1054   inline uint8_t * u8_strrchr_template (uint8_t *str, ucs4_t uc)
1055   { return u8_strrchr (str, uc); }
1056 template <>
1057   inline const uint8_t * u8_strrchr_template (const uint8_t *str, ucs4_t uc)
1058   { return u8_strrchr (str, uc); }
1059 #  undef u8_strrchr
1060 #  define u8_strrchr u8_strrchr_template
1061 # elif !defined u8_strrchr
1062 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1063        || defined __ICC  || defined __TINYC__ \
1064        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1065 #   define u8_strrchr(s,u) \
1066       _Generic ((s), \
1067                 uint8_t const *: (uint8_t const *) u8_strrchr ((s), (u)), \
1068                 default        :                   u8_strrchr ((s), (u)))
1069 #  endif
1070 # endif
1071 # ifdef __cplusplus
1072 template <typename T>
1073   T * u16_strrchr_template (T* str, ucs4_t uc);
1074 template <>
1075   inline uint16_t * u16_strrchr_template (uint16_t *str, ucs4_t uc)
1076   { return u16_strrchr (str, uc); }
1077 template <>
1078   inline const uint16_t * u16_strrchr_template (const uint16_t *str, ucs4_t uc)
1079   { return u16_strrchr (str, uc); }
1080 #  undef u16_strrchr
1081 #  define u16_strrchr u16_strrchr_template
1082 # elif !defined u16_strrchr
1083 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1084        || defined __ICC  || defined __TINYC__ \
1085        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1086 #   define u16_strrchr(s,u) \
1087       _Generic ((s), \
1088                 uint16_t const *: (uint16_t const *) u16_strrchr ((s), (u)), \
1089                 default         :                    u16_strrchr ((s), (u)))
1090 #  endif
1091 # endif
1092 # ifdef __cplusplus
1093 template <typename T>
1094   T * u32_strrchr_template (T* str, ucs4_t uc);
1095 template <>
1096   inline uint32_t * u32_strrchr_template (uint32_t *str, ucs4_t uc)
1097   { return u32_strrchr (str, uc); }
1098 template <>
1099   inline const uint32_t * u32_strrchr_template (const uint32_t *str, ucs4_t uc)
1100   { return u32_strrchr (str, uc); }
1101 #  undef u32_strrchr
1102 #  define u32_strrchr u32_strrchr_template
1103 # elif !defined u32_strrchr
1104 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1105        || defined __ICC  || defined __TINYC__ \
1106        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1107 #   define u32_strrchr(s,u) \
1108       _Generic ((s), \
1109                 uint32_t const *: (uint32_t const *) u32_strrchr ((s), (u)), \
1110                 default         :                    u32_strrchr ((s), (u)))
1111 #  endif
1112 # endif
1113 # ifdef __cplusplus
1114 extern "C" {
1115 # endif
1116 #endif
1117 
1118 /* Return the length of the initial segment of STR which consists entirely
1119    of Unicode characters not in REJECT.  */
1120 /* Similar to strcspn(), wcscspn().  */
1121 extern size_t
1122        u8_strcspn (const uint8_t *str, const uint8_t *reject)
1123        _UC_ATTRIBUTE_PURE;
1124 extern size_t
1125        u16_strcspn (const uint16_t *str, const uint16_t *reject)
1126        _UC_ATTRIBUTE_PURE;
1127 extern size_t
1128        u32_strcspn (const uint32_t *str, const uint32_t *reject)
1129        _UC_ATTRIBUTE_PURE;
1130 
1131 /* Return the length of the initial segment of STR which consists entirely
1132    of Unicode characters in ACCEPT.  */
1133 /* Similar to strspn(), wcsspn().  */
1134 extern size_t
1135        u8_strspn (const uint8_t *str, const uint8_t *accept)
1136        _UC_ATTRIBUTE_PURE;
1137 extern size_t
1138        u16_strspn (const uint16_t *str, const uint16_t *accept)
1139        _UC_ATTRIBUTE_PURE;
1140 extern size_t
1141        u32_strspn (const uint32_t *str, const uint32_t *accept)
1142        _UC_ATTRIBUTE_PURE;
1143 
1144 /* Find the first occurrence in STR of any character in ACCEPT.  */
1145 /* Similar to strpbrk(), wcspbrk().  */
1146 extern uint8_t *
1147        u8_strpbrk (const uint8_t *str, const uint8_t *accept)
1148        _UC_ATTRIBUTE_PURE;
1149 extern uint16_t *
1150        u16_strpbrk (const uint16_t *str, const uint16_t *accept)
1151        _UC_ATTRIBUTE_PURE;
1152 extern uint32_t *
1153        u32_strpbrk (const uint32_t *str, const uint32_t *accept)
1154        _UC_ATTRIBUTE_PURE;
1155 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
1156 # ifdef __cplusplus
1157 }
1158 # endif
1159 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
1160    want compiler warnings for 'const' related mistakes.  */
1161 # ifdef __cplusplus
1162 template <typename T>
1163   T * u8_strpbrk_template (T* str, const uint8_t *accept);
1164 template <>
1165   inline uint8_t * u8_strpbrk_template (uint8_t *str, const uint8_t *accept)
1166   { return u8_strpbrk (str, accept); }
1167 template <>
1168   inline const uint8_t * u8_strpbrk_template (const uint8_t *str, const uint8_t *accept)
1169   { return u8_strpbrk (str, accept); }
1170 #  undef u8_strpbrk
1171 #  define u8_strpbrk u8_strpbrk_template
1172 # elif !defined u8_strpbrk
1173 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1174        || defined __ICC  || defined __TINYC__ \
1175        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1176 #   define u8_strpbrk(s,a) \
1177       _Generic ((s), \
1178                 uint8_t const *: (uint8_t const *) u8_strpbrk ((s), (a)), \
1179                 default        :                   u8_strpbrk ((s), (a)))
1180 #  endif
1181 # endif
1182 # ifdef __cplusplus
1183 template <typename T>
1184   T * u16_strpbrk_template (T* str, const uint16_t *accept);
1185 template <>
1186   inline uint16_t * u16_strpbrk_template (uint16_t *str, const uint16_t *accept)
1187   { return u16_strpbrk (str, accept); }
1188 template <>
1189   inline const uint16_t * u16_strpbrk_template (const uint16_t *str, const uint16_t *accept)
1190   { return u16_strpbrk (str, accept); }
1191 #  undef u16_strpbrk
1192 #  define u16_strpbrk u16_strpbrk_template
1193 # elif !defined u16_strpbrk
1194 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1195        || defined __ICC  || defined __TINYC__ \
1196        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1197 #   define u16_strpbrk(s,a) \
1198       _Generic ((s), \
1199                 uint16_t const *: (uint16_t const *) u16_strpbrk ((s), (a)), \
1200                 default         :                    u16_strpbrk ((s), (a)))
1201 #  endif
1202 # endif
1203 # ifdef __cplusplus
1204 template <typename T>
1205   T * u32_strpbrk_template (T* str, const uint32_t *accept);
1206 template <>
1207   inline uint32_t * u32_strpbrk_template (uint32_t *str, const uint32_t *accept)
1208   { return u32_strpbrk (str, accept); }
1209 template <>
1210   inline const uint32_t * u32_strpbrk_template (const uint32_t *str, const uint32_t *accept)
1211   { return u32_strpbrk (str, accept); }
1212 #  undef u32_strpbrk
1213 #  define u32_strpbrk u32_strpbrk_template
1214 # elif !defined u32_strpbrk
1215 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1216        || defined __ICC  || defined __TINYC__ \
1217        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1218 #   define u32_strpbrk(s,a) \
1219       _Generic ((s), \
1220                 uint32_t const *: (uint32_t const *) u32_strpbrk ((s), (a)), \
1221                 default         :                    u32_strpbrk ((s), (a)))
1222 #  endif
1223 # endif
1224 # ifdef __cplusplus
1225 extern "C" {
1226 # endif
1227 #endif
1228 
1229 /* Find the first occurrence of NEEDLE in HAYSTACK.  */
1230 /* Similar to strstr(), wcsstr().  */
1231 extern uint8_t *
1232        u8_strstr (const uint8_t *haystack, const uint8_t *needle)
1233        _UC_ATTRIBUTE_PURE;
1234 extern uint16_t *
1235        u16_strstr (const uint16_t *haystack, const uint16_t *needle)
1236        _UC_ATTRIBUTE_PURE;
1237 extern uint32_t *
1238        u32_strstr (const uint32_t *haystack, const uint32_t *needle)
1239        _UC_ATTRIBUTE_PURE;
1240 #ifndef _LIBUNISTRING_NO_CONST_GENERICS
1241 # ifdef __cplusplus
1242 }
1243 # endif
1244 /* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
1245    want compiler warnings for 'const' related mistakes.  */
1246 # ifdef __cplusplus
1247 template <typename T>
1248   T * u8_strstr_template (T* haystack, const uint8_t *needle);
1249 template <>
1250   inline uint8_t * u8_strstr_template (uint8_t *haystack, const uint8_t *needle)
1251   { return u8_strstr (haystack, needle); }
1252 template <>
1253   inline const uint8_t * u8_strstr_template (const uint8_t *haystack, const uint8_t *needle)
1254   { return u8_strstr (haystack, needle); }
1255 #  undef u8_strstr
1256 #  define u8_strstr u8_strstr_template
1257 # elif !defined u8_strstr
1258 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1259        || defined __ICC  || defined __TINYC__ \
1260        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1261 #   define u8_strstr(h,n) \
1262       _Generic ((h), \
1263                 uint8_t const *: (uint8_t const *) u8_strstr ((h), (n)), \
1264                 default        :                   u8_strstr ((h), (n)))
1265 #  endif
1266 # endif
1267 # ifdef __cplusplus
1268 template <typename T>
1269   T * u16_strstr_template (T* haystack, const uint16_t *needle);
1270 template <>
1271   inline uint16_t * u16_strstr_template (uint16_t *haystack, const uint16_t *needle)
1272   { return u16_strstr (haystack, needle); }
1273 template <>
1274   inline const uint16_t * u16_strstr_template (const uint16_t *haystack, const uint16_t *needle)
1275   { return u16_strstr (haystack, needle); }
1276 #  undef u16_strstr
1277 #  define u16_strstr u16_strstr_template
1278 # elif !defined u16_strstr
1279 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1280        || defined __ICC  || defined __TINYC__ \
1281        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1282 #   define u16_strstr(h,n) \
1283       _Generic ((h), \
1284                 uint16_t const *: (uint16_t const *) u16_strstr ((h), (n)), \
1285                 default         :                    u16_strstr ((h), (n)))
1286 #  endif
1287 # endif
1288 # ifdef __cplusplus
1289 template <typename T>
1290   T * u32_strstr_template (T* haystack, const uint32_t *needle);
1291 template <>
1292   inline uint32_t * u32_strstr_template (uint32_t *haystack, const uint32_t *needle)
1293   { return u32_strstr (haystack, needle); }
1294 template <>
1295   inline const uint32_t * u32_strstr_template (const uint32_t *haystack, const uint32_t *needle)
1296   { return u32_strstr (haystack, needle); }
1297 #  undef u32_strstr
1298 #  define u32_strstr u32_strstr_template
1299 # elif !defined u32_strstr
1300 #  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1301        || defined __ICC  || defined __TINYC__ \
1302        || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1303 #   define u32_strstr(h,n) \
1304       _Generic ((h), \
1305                 uint32_t const *: (uint32_t const *) u32_strstr ((h), (n)), \
1306                 default         :                    u32_strstr ((h), (n)))
1307 #  endif
1308 # endif
1309 # ifdef __cplusplus
1310 extern "C" {
1311 # endif
1312 #endif
1313 
1314 /* Test whether STR starts with PREFIX.  */
1315 extern bool
1316        u8_startswith (const uint8_t *str, const uint8_t *prefix)
1317        _UC_ATTRIBUTE_PURE;
1318 extern bool
1319        u16_startswith (const uint16_t *str, const uint16_t *prefix)
1320        _UC_ATTRIBUTE_PURE;
1321 extern bool
1322        u32_startswith (const uint32_t *str, const uint32_t *prefix)
1323        _UC_ATTRIBUTE_PURE;
1324 
1325 /* Test whether STR ends with SUFFIX.  */
1326 extern bool
1327        u8_endswith (const uint8_t *str, const uint8_t *suffix)
1328        _UC_ATTRIBUTE_PURE;
1329 extern bool
1330        u16_endswith (const uint16_t *str, const uint16_t *suffix)
1331        _UC_ATTRIBUTE_PURE;
1332 extern bool
1333        u32_endswith (const uint32_t *str, const uint32_t *suffix)
1334        _UC_ATTRIBUTE_PURE;
1335 
1336 /* Divide STR into tokens separated by characters in DELIM.
1337    This interface is actually more similar to wcstok than to strtok.  */
1338 /* Similar to strtok_r(), wcstok().  */
1339 extern uint8_t *
1340        u8_strtok (uint8_t *_UC_RESTRICT str, const uint8_t *delim,
1341                   uint8_t **ptr);
1342 extern uint16_t *
1343        u16_strtok (uint16_t *_UC_RESTRICT str, const uint16_t *delim,
1344                    uint16_t **ptr);
1345 extern uint32_t *
1346        u32_strtok (uint32_t *_UC_RESTRICT str, const uint32_t *delim,
1347                    uint32_t **ptr);
1348 
1349 
1350 #ifdef __cplusplus
1351 }
1352 #endif
1353 
1354 #endif /* _UNISTR_H */