Coverage Report

Created: 2025-07-11 06:23

/src/libidn/lib/gl/unistr.h
Line
Count
Source (jump to first uncovered line)
1
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
2
/* Elementary Unicode string functions.
3
   Copyright (C) 2001-2002, 2005-2025 Free Software Foundation, Inc.
4
5
   This file is free software: you can redistribute it and/or modify
6
   it under the terms of the GNU Lesser General Public License as
7
   published by the Free Software Foundation; either version 2.1 of the
8
   License, or (at your option) any later version.
9
10
   This file is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public License
16
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
17
18
#ifndef _UNISTR_H
19
#define _UNISTR_H
20
21
#include "unitypes.h"
22
23
/* Get bool.  */
24
#include <stdbool.h>
25
26
/* Get size_t, ptrdiff_t.  */
27
#include <stddef.h>
28
29
/* Get free().  */
30
#include <stdlib.h>
31
32
#ifdef __cplusplus
33
extern "C" {
34
#endif
35
36
37
/* Conventions:
38
39
   All functions prefixed with u8_ operate on UTF-8 encoded strings.
40
   Their unit is an uint8_t (1 byte).
41
42
   All functions prefixed with u16_ operate on UTF-16 encoded strings.
43
   Their unit is an uint16_t (a 2-byte word).
44
45
   All functions prefixed with u32_ operate on UCS-4 encoded strings.
46
   Their unit is an uint32_t (a 4-byte word).
47
48
   All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly
49
   n units.
50
51
   All arguments starting with "str" and the arguments of functions starting
52
   with u8_str/u16_str/u32_str denote a NUL terminated string, i.e. a string
53
   which terminates at the first NUL unit.  This termination unit is
54
   considered part of the string for all memory allocation purposes, but
55
   is not considered part of the string for all other logical purposes.
56
57
   Functions returning a string result take a (resultbuf, lengthp) argument
58
   pair.  If resultbuf is not NULL and the result fits into *lengthp units,
59
   it is put in resultbuf, and resultbuf is returned.  Otherwise, a freshly
60
   allocated string is returned.  In both cases, *lengthp is set to the
61
   length (number of units) of the returned string.  In case of error,
62
   NULL is returned and errno is set.  */
63
64
65
/* Elementary string checks.  */
66
67
/* Check whether an UTF-8 string is well-formed.
68
   Return NULL if valid, or a pointer to the first invalid unit otherwise.  */
69
extern const uint8_t *
70
       u8_check (const uint8_t *s, size_t n)
71
       _UC_ATTRIBUTE_PURE;
72
73
/* Check whether an UTF-16 string is well-formed.
74
   Return NULL if valid, or a pointer to the first invalid unit otherwise.  */
75
extern const uint16_t *
76
       u16_check (const uint16_t *s, size_t n)
77
       _UC_ATTRIBUTE_PURE;
78
79
/* Check whether an UCS-4 string is well-formed.
80
   Return NULL if valid, or a pointer to the first invalid unit otherwise.  */
81
extern const uint32_t *
82
       u32_check (const uint32_t *s, size_t n)
83
       _UC_ATTRIBUTE_PURE;
84
85
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
86
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
87
   want compiler warnings for 'const' related mistakes.  */
88
# ifdef __cplusplus
89
template <typename T>
90
  T * u8_check_template (T* s, size_t n);
91
template <>
92
  inline uint8_t * u8_check_template (uint8_t *s, size_t n)
93
  { return const_cast<uint8_t *>(u8_check (s, n)); }
94
template <>
95
  inline const uint8_t * u8_check_template (const uint8_t *s, size_t n)
96
  { return u8_check (s, n); }
97
#  undef u8_check
98
#  define u8_check u8_check_template
99
# elif !defined u8_check
100
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
101
       || defined __ICC  || defined __TINYC__ \
102
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
103
#   define u8_check(s,n) \
104
17.9M
      _Generic ((s), \
105
17.9M
                uint8_t *: (uint8_t *) u8_check ((s), (n)), \
106
17.9M
                default  :             u8_check ((s), (n)))
107
#  endif
108
# endif
109
# ifdef __cplusplus
110
template <typename T>
111
  T * u16_check_template (T* s, size_t n);
112
template <>
113
  inline uint16_t * u16_check_template (uint16_t *s, size_t n)
114
  { return const_cast<uint16_t *>(u16_check (s, n)); }
115
template <>
116
  inline const uint16_t * u16_check_template (const uint16_t *s, size_t n)
117
  { return u16_check (s, n); }
118
#  undef u16_check
119
#  define u16_check u16_check_template
120
# elif !defined u16_check
121
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
122
       || defined __ICC  || defined __TINYC__ \
123
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
124
#   define u16_check(s,n) \
125
      _Generic ((s), \
126
                uint16_t *: (uint16_t *) u16_check ((s), (n)), \
127
                default   :              u16_check ((s), (n)))
128
#  endif
129
# endif
130
# ifdef __cplusplus
131
template <typename T>
132
  T * u32_check_template (T* s, size_t n);
133
template <>
134
  inline uint32_t * u32_check_template (uint32_t *s, size_t n)
135
  { return const_cast<uint32_t *>(u32_check (s, n)); }
136
template <>
137
  inline const uint32_t * u32_check_template (const uint32_t *s, size_t n)
138
  { return u32_check (s, n); }
139
#  undef u32_check
140
#  define u32_check u32_check_template
141
# elif !defined u32_check
142
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
143
       || defined __ICC  || defined __TINYC__ \
144
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
145
#   define u32_check(s,n) \
146
      _Generic ((s), \
147
                uint32_t *: (uint32_t *) u32_check ((s), (n)), \
148
                default   :              u32_check ((s), (n)))
149
#  endif
150
# endif
151
#endif
152
153
154
/* Elementary string conversions.  */
155
156
/* Convert an UTF-8 string to an UTF-16 string.  */
157
extern uint16_t *
158
       u8_to_u16 (const uint8_t *s, size_t n, uint16_t *resultbuf,
159
                  size_t *lengthp);
160
161
/* Convert an UTF-8 string to an UCS-4 string.  */
162
extern uint32_t *
163
       u8_to_u32 (const uint8_t *s, size_t n, uint32_t *resultbuf,
164
                  size_t *lengthp);
165
166
/* Convert an UTF-16 string to an UTF-8 string.  */
167
extern uint8_t *
168
       u16_to_u8 (const uint16_t *s, size_t n, uint8_t *resultbuf,
169
                  size_t *lengthp);
170
171
/* Convert an UTF-16 string to an UCS-4 string.  */
172
extern uint32_t *
173
       u16_to_u32 (const uint16_t *s, size_t n, uint32_t *resultbuf,
174
                   size_t *lengthp);
175
176
/* Convert an UCS-4 string to an UTF-8 string.  */
177
extern uint8_t *
178
       u32_to_u8 (const uint32_t *s, size_t n, uint8_t *resultbuf,
179
                  size_t *lengthp);
180
181
/* Convert an UCS-4 string to an UTF-16 string.  */
182
extern uint16_t *
183
       u32_to_u16 (const uint32_t *s, size_t n, uint16_t *resultbuf,
184
                   size_t *lengthp);
185
186
187
/* Elementary string functions.  */
188
189
/* Return the length (number of units) of the first character in S, which is
190
   no longer than N.  Return 0 if it is the NUL character.  Return -1 upon
191
   failure.  */
192
/* Similar to mblen(), except that s must not be NULL.  */
193
extern int
194
       u8_mblen (const uint8_t *s, size_t n)
195
       _UC_ATTRIBUTE_PURE;
196
extern int
197
       u16_mblen (const uint16_t *s, size_t n)
198
       _UC_ATTRIBUTE_PURE;
199
extern int
200
       u32_mblen (const uint32_t *s, size_t n)
201
       _UC_ATTRIBUTE_PURE;
202
203
/* Return the length (number of units) of the first character in S, putting
204
   its 'ucs4_t' representation in *PUC.  Upon failure, *PUC is set to 0xfffd,
205
   and an appropriate number of units is returned.
206
   The number of available units, N, must be > 0.  */
207
/* Similar to mbtowc(), except that puc and s must not be NULL, n must be > 0,
208
   and the NUL character is not treated specially.  */
209
/* The variants with _unsafe suffix are for backward compatibility with
210
   libunistring versions < 0.9.7.  */
211
212
#if GNULIB_UNISTR_U8_MBTOUC_UNSAFE || HAVE_LIBUNISTRING
213
# if !HAVE_INLINE
214
extern int
215
       u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n);
216
# else
217
extern int
218
       u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n);
219
static inline int
220
u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n)
221
{
222
  uint8_t c = *s;
223
224
  if (c < 0x80)
225
    {
226
      *puc = c;
227
      return 1;
228
    }
229
  else
230
    return u8_mbtouc_unsafe_aux (puc, s, n);
231
}
232
# endif
233
#endif
234
235
#if GNULIB_UNISTR_U16_MBTOUC_UNSAFE || HAVE_LIBUNISTRING
236
# if !HAVE_INLINE
237
extern int
238
       u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n);
239
# else
240
extern int
241
       u16_mbtouc_unsafe_aux (ucs4_t *puc, const uint16_t *s, size_t n);
242
static inline int
243
u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n)
244
{
245
  uint16_t c = *s;
246
247
  if (c < 0xd800 || c >= 0xe000)
248
    {
249
      *puc = c;
250
      return 1;
251
    }
252
  else
253
    return u16_mbtouc_unsafe_aux (puc, s, n);
254
}
255
# endif
256
#endif
257
258
#if GNULIB_UNISTR_U32_MBTOUC_UNSAFE || HAVE_LIBUNISTRING
259
# if !HAVE_INLINE
260
extern int
261
       u32_mbtouc_unsafe (ucs4_t *puc, const uint32_t *s, size_t n);
262
# else
263
static inline int
264
u32_mbtouc_unsafe (ucs4_t *puc,
265
                   const uint32_t *s, _GL_ATTRIBUTE_MAYBE_UNUSED size_t n)
266
{
267
  uint32_t c = *s;
268
269
  if (c < 0xd800 || (c >= 0xe000 && c < 0x110000))
270
    *puc = c;
271
  else
272
    /* invalid multibyte character */
273
    *puc = 0xfffd;
274
  return 1;
275
}
276
# endif
277
#endif
278
279
#if GNULIB_UNISTR_U8_MBTOUC || HAVE_LIBUNISTRING
280
# if !HAVE_INLINE
281
extern int
282
       u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n);
283
# else
284
extern int
285
       u8_mbtouc_aux (ucs4_t *puc, const uint8_t *s, size_t n);
286
static inline int
287
u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n)
288
{
289
  uint8_t c = *s;
290
291
  if (c < 0x80)
292
    {
293
      *puc = c;
294
      return 1;
295
    }
296
  else
297
    return u8_mbtouc_aux (puc, s, n);
298
}
299
# endif
300
#endif
301
302
#if GNULIB_UNISTR_U16_MBTOUC || HAVE_LIBUNISTRING
303
# if !HAVE_INLINE
304
extern int
305
       u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n);
306
# else
307
extern int
308
       u16_mbtouc_aux (ucs4_t *puc, const uint16_t *s, size_t n);
309
static inline int
310
u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n)
311
{
312
  uint16_t c = *s;
313
314
  if (c < 0xd800 || c >= 0xe000)
315
    {
316
      *puc = c;
317
      return 1;
318
    }
319
  else
320
    return u16_mbtouc_aux (puc, s, n);
321
}
322
# endif
323
#endif
324
325
#if GNULIB_UNISTR_U32_MBTOUC || HAVE_LIBUNISTRING
326
# if !HAVE_INLINE
327
extern int
328
       u32_mbtouc (ucs4_t *puc, const uint32_t *s, size_t n);
329
# else
330
static inline int
331
u32_mbtouc (ucs4_t *puc, const uint32_t *s,
332
            _GL_ATTRIBUTE_MAYBE_UNUSED size_t n)
333
{
334
  uint32_t c = *s;
335
336
  if (c < 0xd800 || (c >= 0xe000 && c < 0x110000))
337
    *puc = c;
338
  else
339
    /* invalid multibyte character */
340
    *puc = 0xfffd;
341
  return 1;
342
}
343
# endif
344
#endif
345
346
/* Return the length (number of units) of the first character in S, putting
347
   its 'ucs4_t' representation in *PUC.  Upon failure, *PUC is set to 0xfffd,
348
   and -1 is returned for an invalid sequence of units, -2 is returned for an
349
   incomplete sequence of units.
350
   The number of available units, N, must be > 0.  */
351
/* Similar to u*_mbtouc(), except that the return value gives more details
352
   about the failure, similar to mbrtowc().  */
353
354
#if GNULIB_UNISTR_U8_MBTOUCR || HAVE_LIBUNISTRING
355
extern int
356
       u8_mbtoucr (ucs4_t *puc, const uint8_t *s, size_t n);
357
#endif
358
359
#if GNULIB_UNISTR_U16_MBTOUCR || HAVE_LIBUNISTRING
360
extern int
361
       u16_mbtoucr (ucs4_t *puc, const uint16_t *s, size_t n);
362
#endif
363
364
#if GNULIB_UNISTR_U32_MBTOUCR || HAVE_LIBUNISTRING
365
extern int
366
       u32_mbtoucr (ucs4_t *puc, const uint32_t *s, size_t n);
367
#endif
368
369
/* Put the multibyte character represented by UC in S, returning its
370
   length.  Return -1 upon failure, -2 if the number of available units, N,
371
   is too small.  The latter case cannot occur if N >= 6/2/1, respectively.  */
372
/* Similar to wctomb(), except that s must not be NULL, and the argument n
373
   must be specified.  */
374
375
#if GNULIB_UNISTR_U8_UCTOMB || HAVE_LIBUNISTRING
376
/* Auxiliary function, also used by u8_chr, u8_strchr, u8_strrchr.  */
377
extern int
378
       u8_uctomb_aux (uint8_t *s, ucs4_t uc, ptrdiff_t n);
379
# if !HAVE_INLINE
380
extern int
381
       u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n);
382
# else
383
static inline int
384
u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n)
385
0
{
386
0
  if (uc < 0x80 && n > 0)
387
0
    {
388
0
      s[0] = uc;
389
0
      return 1;
390
0
    }
391
0
  else
392
0
    return u8_uctomb_aux (s, uc, n);
393
0
}
Unexecuted instantiation: nfkc.c:u8_uctomb
Unexecuted instantiation: u8-check.c:u8_uctomb
394
# endif
395
#endif
396
397
#if GNULIB_UNISTR_U16_UCTOMB || HAVE_LIBUNISTRING
398
/* Auxiliary function, also used by u16_chr, u16_strchr, u16_strrchr.  */
399
extern int
400
       u16_uctomb_aux (uint16_t *s, ucs4_t uc, ptrdiff_t n);
401
# if !HAVE_INLINE
402
extern int
403
       u16_uctomb (uint16_t *s, ucs4_t uc, ptrdiff_t n);
404
# else
405
static inline int
406
u16_uctomb (uint16_t *s, ucs4_t uc, ptrdiff_t n)
407
{
408
  if (uc < 0xd800 && n > 0)
409
    {
410
      s[0] = uc;
411
      return 1;
412
    }
413
  else
414
    return u16_uctomb_aux (s, uc, n);
415
}
416
# endif
417
#endif
418
419
#if GNULIB_UNISTR_U32_UCTOMB || HAVE_LIBUNISTRING
420
# if !HAVE_INLINE
421
extern int
422
       u32_uctomb (uint32_t *s, ucs4_t uc, ptrdiff_t n);
423
# else
424
static inline int
425
u32_uctomb (uint32_t *s, ucs4_t uc, ptrdiff_t n)
426
{
427
  if (uc < 0xd800 || (uc >= 0xe000 && uc < 0x110000))
428
    {
429
      if (n > 0)
430
        {
431
          *s = uc;
432
          return 1;
433
        }
434
      else
435
        return -2;
436
    }
437
  else
438
    return -1;
439
}
440
# endif
441
#endif
442
443
/* Copy N units from SRC to DEST.  */
444
/* Similar to memcpy().  */
445
extern uint8_t *
446
       u8_cpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
447
extern uint16_t *
448
       u16_cpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
449
extern uint32_t *
450
       u32_cpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
451
452
/* Copy N units from SRC to DEST, returning pointer after last written unit.  */
453
/* Similar to mempcpy().  */
454
extern uint8_t *
455
       u8_pcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
456
extern uint16_t *
457
       u16_pcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
458
extern uint32_t *
459
       u32_pcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
460
461
/* Copy N units from SRC to DEST, guaranteeing correct behavior for
462
   overlapping memory areas.  */
463
/* Similar to memmove().  */
464
extern uint8_t *
465
       u8_move (uint8_t *dest, const uint8_t *src, size_t n);
466
extern uint16_t *
467
       u16_move (uint16_t *dest, const uint16_t *src, size_t n);
468
extern uint32_t *
469
       u32_move (uint32_t *dest, const uint32_t *src, size_t n);
470
471
/* Set the first N characters of S to UC.  UC should be a character that
472
   occupies only 1 unit.  */
473
/* Similar to memset().  */
474
extern uint8_t *
475
       u8_set (uint8_t *s, ucs4_t uc, size_t n);
476
extern uint16_t *
477
       u16_set (uint16_t *s, ucs4_t uc, size_t n);
478
extern uint32_t *
479
       u32_set (uint32_t *s, ucs4_t uc, size_t n);
480
481
/* Compare S1 and S2, each of length N.  */
482
/* Similar to memcmp().  */
483
extern int
484
       u8_cmp (const uint8_t *s1, const uint8_t *s2, size_t n)
485
       _UC_ATTRIBUTE_PURE;
486
extern int
487
       u16_cmp (const uint16_t *s1, const uint16_t *s2, size_t n)
488
       _UC_ATTRIBUTE_PURE;
489
extern int
490
       u32_cmp (const uint32_t *s1, const uint32_t *s2, size_t n)
491
       _UC_ATTRIBUTE_PURE;
492
493
/* Compare S1 and S2.  */
494
/* Similar to the gnulib function memcmp2().  */
495
extern int
496
       u8_cmp2 (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2)
497
       _UC_ATTRIBUTE_PURE;
498
extern int
499
       u16_cmp2 (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2)
500
       _UC_ATTRIBUTE_PURE;
501
extern int
502
       u32_cmp2 (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2)
503
       _UC_ATTRIBUTE_PURE;
504
505
/* Search the string at S for UC.  */
506
/* Similar to memchr().  */
507
extern uint8_t *
508
       u8_chr (const uint8_t *s, size_t n, ucs4_t uc)
509
       _UC_ATTRIBUTE_PURE;
510
extern uint16_t *
511
       u16_chr (const uint16_t *s, size_t n, ucs4_t uc)
512
       _UC_ATTRIBUTE_PURE;
513
extern uint32_t *
514
       u32_chr (const uint32_t *s, size_t n, ucs4_t uc)
515
       _UC_ATTRIBUTE_PURE;
516
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
517
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
518
   want compiler warnings for 'const' related mistakes.  */
519
# ifdef __cplusplus
520
template <typename T>
521
  T * u8_chr_template (T* str, size_t n, ucs4_t uc);
522
template <>
523
  inline uint8_t * u8_chr_template (uint8_t *str, size_t n, ucs4_t uc)
524
  { return u8_chr (str, n, uc); }
525
template <>
526
  inline const uint8_t * u8_chr_template (const uint8_t *str, size_t n, ucs4_t uc)
527
  { return u8_chr (str, n, uc); }
528
#  undef u8_chr
529
#  define u8_chr u8_chr_template
530
# elif !defined u8_chr
531
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
532
       || defined __ICC  || defined __TINYC__ \
533
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
534
#   define u8_chr(s,n,u) \
535
      _Generic ((s), \
536
                uint8_t const *: (uint8_t const *) u8_chr ((s), (n), (u)), \
537
                default        :                   u8_chr ((s), (n), (u)))
538
#  endif
539
# endif
540
# ifdef __cplusplus
541
template <typename T>
542
  T * u16_chr_template (T* str, size_t n, ucs4_t uc);
543
template <>
544
  inline uint16_t * u16_chr_template (uint16_t *str, size_t n, ucs4_t uc)
545
  { return u16_chr (str, n, uc); }
546
template <>
547
  inline const uint16_t * u16_chr_template (const uint16_t *str, size_t n, ucs4_t uc)
548
  { return u16_chr (str, n, uc); }
549
#  undef u16_chr
550
#  define u16_chr u16_chr_template
551
# elif !defined u16_chr
552
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
553
       || defined __ICC  || defined __TINYC__ \
554
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
555
#   define u16_chr(s,n,u) \
556
      _Generic ((s), \
557
                uint16_t const *: (uint16_t const *) u16_chr ((s), (n), (u)), \
558
                default         :                    u16_chr ((s), (n), (u)))
559
#  endif
560
# endif
561
# ifdef __cplusplus
562
template <typename T>
563
  T * u32_chr_template (T* str, size_t n, ucs4_t uc);
564
template <>
565
  inline uint32_t * u32_chr_template (uint32_t *str, size_t n, ucs4_t uc)
566
  { return u32_chr (str, n, uc); }
567
template <>
568
  inline const uint32_t * u32_chr_template (const uint32_t *str, size_t n, ucs4_t uc)
569
  { return u32_chr (str, n, uc); }
570
#  undef u32_chr
571
#  define u32_chr u32_chr_template
572
# elif !defined u32_chr
573
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
574
       || defined __ICC  || defined __TINYC__ \
575
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
576
#   define u32_chr(s,n,u) \
577
      _Generic ((s), \
578
                uint32_t const *: (uint32_t const *) u32_chr ((s), (n), (u)), \
579
                default         :                    u32_chr ((s), (n), (u)))
580
#  endif
581
# endif
582
#endif
583
584
/* Count the number of Unicode characters in the N units from S.  */
585
/* Similar to mbsnlen().  */
586
extern size_t
587
       u8_mbsnlen (const uint8_t *s, size_t n)
588
       _UC_ATTRIBUTE_PURE;
589
extern size_t
590
       u16_mbsnlen (const uint16_t *s, size_t n)
591
       _UC_ATTRIBUTE_PURE;
592
extern size_t
593
       u32_mbsnlen (const uint32_t *s, size_t n)
594
       _UC_ATTRIBUTE_PURE;
595
596
/* Elementary string functions with memory allocation.  */
597
598
/* Make a freshly allocated copy of S, of length N.  */
599
extern uint8_t *
600
       u8_cpy_alloc (const uint8_t *s, size_t n);
601
extern uint16_t *
602
       u16_cpy_alloc (const uint16_t *s, size_t n);
603
extern uint32_t *
604
       u32_cpy_alloc (const uint32_t *s, size_t n);
605
606
/* Elementary string functions on NUL terminated strings.  */
607
608
/* Return the length (number of units) of the first character in S.
609
   Return 0 if it is the NUL character.  Return -1 upon failure.  */
610
extern int
611
       u8_strmblen (const uint8_t *s)
612
       _UC_ATTRIBUTE_PURE;
613
extern int
614
       u16_strmblen (const uint16_t *s)
615
       _UC_ATTRIBUTE_PURE;
616
extern int
617
       u32_strmblen (const uint32_t *s)
618
       _UC_ATTRIBUTE_PURE;
619
620
/* Return the length (number of units) of the first character in S, putting
621
   its 'ucs4_t' representation in *PUC.  Return 0 if it is the NUL
622
   character.  Return -1 upon failure.  */
623
extern int
624
       u8_strmbtouc (ucs4_t *puc, const uint8_t *s);
625
extern int
626
       u16_strmbtouc (ucs4_t *puc, const uint16_t *s);
627
extern int
628
       u32_strmbtouc (ucs4_t *puc, const uint32_t *s);
629
630
/* Forward iteration step.  Advances the pointer past the next character,
631
   or returns NULL if the end of the string has been reached.  Puts the
632
   character's 'ucs4_t' representation in *PUC.  */
633
extern const uint8_t *
634
       u8_next (ucs4_t *puc, const uint8_t *s);
635
extern const uint16_t *
636
       u16_next (ucs4_t *puc, const uint16_t *s);
637
extern const uint32_t *
638
       u32_next (ucs4_t *puc, const uint32_t *s);
639
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
640
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
641
   want compiler warnings for 'const' related mistakes.  */
642
# ifdef __cplusplus
643
template <typename T>
644
  T * u8_next_template (ucs4_t *puc, T* s);
645
template <>
646
  inline uint8_t * u8_next_template (ucs4_t *puc, uint8_t *s)
647
  { return const_cast<uint8_t *>(u8_next (puc, s)); }
648
template <>
649
  inline const uint8_t * u8_next_template (ucs4_t *puc, const uint8_t *s)
650
  { return u8_next (puc, s); }
651
#  undef u8_next
652
#  define u8_next u8_next_template
653
# elif !defined u8_next
654
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
655
       || defined __ICC  || defined __TINYC__ \
656
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
657
#   define u8_next(p,s) \
658
      _Generic ((s), \
659
                uint8_t *: (uint8_t *) u8_next ((p), (s)), \
660
                default  :             u8_next ((p), (s)))
661
#  endif
662
# endif
663
# ifdef __cplusplus
664
template <typename T>
665
  T * u16_next_template (ucs4_t *puc, T* s);
666
template <>
667
  inline uint16_t * u16_next_template (ucs4_t *puc, uint16_t *s)
668
  { return const_cast<uint16_t *>(u16_next (puc, s)); }
669
template <>
670
  inline const uint16_t * u16_next_template (ucs4_t *puc, const uint16_t *s)
671
  { return u16_next (puc, s); }
672
#  undef u16_next
673
#  define u16_next u16_next_template
674
# elif !defined u16_next
675
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
676
       || defined __ICC  || defined __TINYC__ \
677
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
678
#   define u16_next(p,s) \
679
      _Generic ((s), \
680
                uint16_t *: (uint16_t *) u16_next ((p), (s)), \
681
                default   :              u16_next ((p), (s)))
682
#  endif
683
# endif
684
# ifdef __cplusplus
685
template <typename T>
686
  T * u32_next_template (ucs4_t *puc, T* s);
687
template <>
688
  inline uint32_t * u32_next_template (ucs4_t *puc, uint32_t *s)
689
  { return const_cast<uint32_t *>(u32_next (puc, s)); }
690
template <>
691
  inline const uint32_t * u32_next_template (ucs4_t *puc, const uint32_t *s)
692
  { return u32_next (puc, s); }
693
#  undef u32_next
694
#  define u32_next u32_next_template
695
# elif !defined u32_next
696
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
697
       || defined __ICC  || defined __TINYC__ \
698
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
699
#   define u32_next(p,s) \
700
      _Generic ((s), \
701
                uint32_t *: (uint32_t *) u32_next ((p), (s)), \
702
                default   :              u32_next ((p), (s)))
703
#  endif
704
# endif
705
#endif
706
707
/* Backward iteration step.  Advances the pointer to point to the previous
708
   character, or returns NULL if the beginning of the string had been reached.
709
   Puts the character's 'ucs4_t' representation in *PUC.  */
710
extern const uint8_t *
711
       u8_prev (ucs4_t *puc, const uint8_t *s, const uint8_t *start);
712
extern const uint16_t *
713
       u16_prev (ucs4_t *puc, const uint16_t *s, const uint16_t *start);
714
extern const uint32_t *
715
       u32_prev (ucs4_t *puc, const uint32_t *s, const uint32_t *start);
716
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
717
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
718
   want compiler warnings for 'const' related mistakes.  */
719
# ifdef __cplusplus
720
template <typename T>
721
  T * u8_prev_template (ucs4_t *puc, T* s, const uint8_t *start);
722
template <>
723
  inline uint8_t * u8_prev_template (ucs4_t *puc, uint8_t *s, const uint8_t *start)
724
  { return const_cast<uint8_t *>(u8_prev (puc, s, start)); }
725
template <>
726
  inline const uint8_t * u8_prev_template (ucs4_t *puc, const uint8_t *s, const uint8_t *start)
727
  { return u8_prev (puc, s, start); }
728
#  undef u8_prev
729
#  define u8_prev u8_prev_template
730
# elif !defined u8_prev
731
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
732
       || defined __ICC  || defined __TINYC__ \
733
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
734
#   define u8_prev(p,s,start) \
735
      _Generic ((s), \
736
                uint8_t *: (uint8_t *) u8_prev ((p), (s), (start)), \
737
                default  :             u8_prev ((p), (s), (start)))
738
#  endif
739
# endif
740
# ifdef __cplusplus
741
template <typename T>
742
  T * u16_prev_template (ucs4_t *puc, T* s, const uint16_t *start);
743
template <>
744
  inline uint16_t * u16_prev_template (ucs4_t *puc, uint16_t *s, const uint16_t *start)
745
  { return const_cast<uint16_t *>(u16_prev (puc, s, start)); }
746
template <>
747
  inline const uint16_t * u16_prev_template (ucs4_t *puc, const uint16_t *s, const uint16_t *start)
748
  { return u16_prev (puc, s, start); }
749
#  undef u16_prev
750
#  define u16_prev u16_prev_template
751
# elif !defined u16_prev
752
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
753
       || defined __ICC  || defined __TINYC__ \
754
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
755
#   define u16_prev(p,s,start) \
756
      _Generic ((s), \
757
                uint16_t *: (uint16_t *) u16_prev ((p), (s), (start)), \
758
                default   :              u16_prev ((p), (s), (start)))
759
#  endif
760
# endif
761
# ifdef __cplusplus
762
template <typename T>
763
  T * u32_prev_template (ucs4_t *puc, T* s, const uint32_t *start);
764
template <>
765
  inline uint32_t * u32_prev_template (ucs4_t *puc, uint32_t *s, const uint32_t *start)
766
  { return const_cast<uint32_t *>(u32_prev (puc, s, start)); }
767
template <>
768
  inline const uint32_t * u32_prev_template (ucs4_t *puc, const uint32_t *s, const uint32_t *start)
769
  { return u32_prev (puc, s, start); }
770
#  undef u32_prev
771
#  define u32_prev u32_prev_template
772
# elif !defined u32_prev
773
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
774
       || defined __ICC  || defined __TINYC__ \
775
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
776
#   define u32_prev(p,s,start) \
777
      _Generic ((s), \
778
                uint32_t *: (uint32_t *) u32_prev ((p), (s), (start)), \
779
                default   :              u32_prev ((p), (s), (start)))
780
#  endif
781
# endif
782
#endif
783
784
/* Return the number of units in S.  */
785
/* Similar to strlen(), wcslen().  */
786
extern size_t
787
       u8_strlen (const uint8_t *s)
788
       _UC_ATTRIBUTE_PURE;
789
extern size_t
790
       u16_strlen (const uint16_t *s)
791
       _UC_ATTRIBUTE_PURE;
792
extern size_t
793
       u32_strlen (const uint32_t *s)
794
       _UC_ATTRIBUTE_PURE;
795
796
/* Return the number of units in S, but at most MAXLEN.  */
797
/* Similar to strnlen(), wcsnlen().  */
798
extern size_t
799
       u8_strnlen (const uint8_t *s, size_t maxlen)
800
       _UC_ATTRIBUTE_PURE;
801
extern size_t
802
       u16_strnlen (const uint16_t *s, size_t maxlen)
803
       _UC_ATTRIBUTE_PURE;
804
extern size_t
805
       u32_strnlen (const uint32_t *s, size_t maxlen)
806
       _UC_ATTRIBUTE_PURE;
807
808
/* Copy SRC to DEST.  */
809
/* Similar to strcpy(), wcscpy().  */
810
extern uint8_t *
811
       u8_strcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
812
extern uint16_t *
813
       u16_strcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
814
extern uint32_t *
815
       u32_strcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
816
817
/* Copy SRC to DEST, returning the address of the terminating NUL in DEST.  */
818
/* Similar to stpcpy().  */
819
extern uint8_t *
820
       u8_stpcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
821
extern uint16_t *
822
       u16_stpcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
823
extern uint32_t *
824
       u32_stpcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
825
826
/* Copy no more than N units of SRC to DEST.  */
827
/* Similar to strncpy(), wcsncpy().  */
828
extern uint8_t *
829
       u8_strncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
830
extern uint16_t *
831
       u16_strncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
832
extern uint32_t *
833
       u32_strncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
834
835
/* Copy no more than N units of SRC to DEST.  Return a pointer past the last
836
   non-NUL unit written into DEST.  */
837
/* Similar to stpncpy().  */
838
extern uint8_t *
839
       u8_stpncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
840
extern uint16_t *
841
       u16_stpncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
842
extern uint32_t *
843
       u32_stpncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
844
845
/* Append SRC onto DEST.  */
846
/* Similar to strcat(), wcscat().  */
847
extern uint8_t *
848
       u8_strcat (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
849
extern uint16_t *
850
       u16_strcat (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
851
extern uint32_t *
852
       u32_strcat (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
853
854
/* Append no more than N units of SRC onto DEST.  */
855
/* Similar to strncat(), wcsncat().  */
856
extern uint8_t *
857
       u8_strncat (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
858
extern uint16_t *
859
       u16_strncat (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
860
extern uint32_t *
861
       u32_strncat (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
862
863
/* Compare S1 and S2.  */
864
/* Similar to strcmp(), wcscmp().  */
865
#ifdef __sun
866
/* Avoid a collision with the u8_strcmp() function in Solaris 11 libc.  */
867
extern int
868
       u8_strcmp_gnu (const uint8_t *s1, const uint8_t *s2)
869
       _UC_ATTRIBUTE_PURE;
870
# define u8_strcmp u8_strcmp_gnu
871
#else
872
extern int
873
       u8_strcmp (const uint8_t *s1, const uint8_t *s2)
874
       _UC_ATTRIBUTE_PURE;
875
#endif
876
extern int
877
       u16_strcmp (const uint16_t *s1, const uint16_t *s2)
878
       _UC_ATTRIBUTE_PURE;
879
extern int
880
       u32_strcmp (const uint32_t *s1, const uint32_t *s2)
881
       _UC_ATTRIBUTE_PURE;
882
883
/* Compare S1 and S2 using the collation rules of the current locale.
884
   Return -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2.
885
   Upon failure, set errno and return any value.  */
886
/* Similar to strcoll(), wcscoll().  */
887
extern int
888
       u8_strcoll (const uint8_t *s1, const uint8_t *s2);
889
extern int
890
       u16_strcoll (const uint16_t *s1, const uint16_t *s2);
891
extern int
892
       u32_strcoll (const uint32_t *s1, const uint32_t *s2);
893
894
/* Compare no more than N units of S1 and S2.  */
895
/* Similar to strncmp(), wcsncmp().  */
896
extern int
897
       u8_strncmp (const uint8_t *s1, const uint8_t *s2, size_t n)
898
       _UC_ATTRIBUTE_PURE;
899
extern int
900
       u16_strncmp (const uint16_t *s1, const uint16_t *s2, size_t n)
901
       _UC_ATTRIBUTE_PURE;
902
extern int
903
       u32_strncmp (const uint32_t *s1, const uint32_t *s2, size_t n)
904
       _UC_ATTRIBUTE_PURE;
905
906
/* Duplicate S, returning an identical malloc'd string.  */
907
/* Similar to strdup(), wcsdup().  */
908
extern uint8_t *
909
       u8_strdup (const uint8_t *s)
910
       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
911
extern uint16_t *
912
       u16_strdup (const uint16_t *s)
913
       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
914
extern uint32_t *
915
       u32_strdup (const uint32_t *s)
916
       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
917
918
/* Find the first occurrence of UC in STR.  */
919
/* Similar to strchr(), wcschr().  */
920
extern uint8_t *
921
       u8_strchr (const uint8_t *str, ucs4_t uc)
922
       _UC_ATTRIBUTE_PURE;
923
extern uint16_t *
924
       u16_strchr (const uint16_t *str, ucs4_t uc)
925
       _UC_ATTRIBUTE_PURE;
926
extern uint32_t *
927
       u32_strchr (const uint32_t *str, ucs4_t uc)
928
       _UC_ATTRIBUTE_PURE;
929
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
930
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
931
   want compiler warnings for 'const' related mistakes.  */
932
# ifdef __cplusplus
933
template <typename T>
934
  T * u8_strchr_template (T* str, ucs4_t uc);
935
template <>
936
  inline uint8_t * u8_strchr_template (uint8_t *str, ucs4_t uc)
937
  { return u8_strchr (str, uc); }
938
template <>
939
  inline const uint8_t * u8_strchr_template (const uint8_t *str, ucs4_t uc)
940
  { return u8_strchr (str, uc); }
941
#  undef u8_strchr
942
#  define u8_strchr u8_strchr_template
943
# elif !defined u8_strchr
944
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
945
       || defined __ICC  || defined __TINYC__ \
946
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
947
#   define u8_strchr(s,u) \
948
      _Generic ((s), \
949
                uint8_t const *: (uint8_t const *) u8_strchr ((s), (u)), \
950
                default        :                   u8_strchr ((s), (u)))
951
#  endif
952
# endif
953
# ifdef __cplusplus
954
template <typename T>
955
  T * u16_strchr_template (T* str, ucs4_t uc);
956
template <>
957
  inline uint16_t * u16_strchr_template (uint16_t *str, ucs4_t uc)
958
  { return u16_strchr (str, uc); }
959
template <>
960
  inline const uint16_t * u16_strchr_template (const uint16_t *str, ucs4_t uc)
961
  { return u16_strchr (str, uc); }
962
#  undef u16_strchr
963
#  define u16_strchr u16_strchr_template
964
# elif !defined u16_strchr
965
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
966
       || defined __ICC  || defined __TINYC__ \
967
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
968
#   define u16_strchr(s,u) \
969
      _Generic ((s), \
970
                uint16_t const *: (uint16_t const *) u16_strchr ((s), (u)), \
971
                default         :                    u16_strchr ((s), (u)))
972
#  endif
973
# endif
974
# ifdef __cplusplus
975
template <typename T>
976
  T * u32_strchr_template (T* str, ucs4_t uc);
977
template <>
978
  inline uint32_t * u32_strchr_template (uint32_t *str, ucs4_t uc)
979
  { return u32_strchr (str, uc); }
980
template <>
981
  inline const uint32_t * u32_strchr_template (const uint32_t *str, ucs4_t uc)
982
  { return u32_strchr (str, uc); }
983
#  undef u32_strchr
984
#  define u32_strchr u32_strchr_template
985
# elif !defined u32_strchr
986
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
987
       || defined __ICC  || defined __TINYC__ \
988
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
989
#   define u32_strchr(s,u) \
990
      _Generic ((s), \
991
                uint32_t const *: (uint32_t const *) u32_strchr ((s), (u)), \
992
                default         :                    u32_strchr ((s), (u)))
993
#  endif
994
# endif
995
#endif
996
997
/* Find the last occurrence of UC in STR.  */
998
/* Similar to strrchr(), wcsrchr().  */
999
extern uint8_t *
1000
       u8_strrchr (const uint8_t *str, ucs4_t uc)
1001
       _UC_ATTRIBUTE_PURE;
1002
extern uint16_t *
1003
       u16_strrchr (const uint16_t *str, ucs4_t uc)
1004
       _UC_ATTRIBUTE_PURE;
1005
extern uint32_t *
1006
       u32_strrchr (const uint32_t *str, ucs4_t uc)
1007
       _UC_ATTRIBUTE_PURE;
1008
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
1009
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
1010
   want compiler warnings for 'const' related mistakes.  */
1011
# ifdef __cplusplus
1012
template <typename T>
1013
  T * u8_strrchr_template (T* str, ucs4_t uc);
1014
template <>
1015
  inline uint8_t * u8_strrchr_template (uint8_t *str, ucs4_t uc)
1016
  { return u8_strrchr (str, uc); }
1017
template <>
1018
  inline const uint8_t * u8_strrchr_template (const uint8_t *str, ucs4_t uc)
1019
  { return u8_strrchr (str, uc); }
1020
#  undef u8_strrchr
1021
#  define u8_strrchr u8_strrchr_template
1022
# elif !defined u8_strrchr
1023
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1024
       || defined __ICC  || defined __TINYC__ \
1025
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1026
#   define u8_strrchr(s,u) \
1027
      _Generic ((s), \
1028
                uint8_t const *: (uint8_t const *) u8_strrchr ((s), (u)), \
1029
                default        :                   u8_strrchr ((s), (u)))
1030
#  endif
1031
# endif
1032
# ifdef __cplusplus
1033
template <typename T>
1034
  T * u16_strrchr_template (T* str, ucs4_t uc);
1035
template <>
1036
  inline uint16_t * u16_strrchr_template (uint16_t *str, ucs4_t uc)
1037
  { return u16_strrchr (str, uc); }
1038
template <>
1039
  inline const uint16_t * u16_strrchr_template (const uint16_t *str, ucs4_t uc)
1040
  { return u16_strrchr (str, uc); }
1041
#  undef u16_strrchr
1042
#  define u16_strrchr u16_strrchr_template
1043
# elif !defined u16_strrchr
1044
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1045
       || defined __ICC  || defined __TINYC__ \
1046
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1047
#   define u16_strrchr(s,u) \
1048
      _Generic ((s), \
1049
                uint16_t const *: (uint16_t const *) u16_strrchr ((s), (u)), \
1050
                default         :                    u16_strrchr ((s), (u)))
1051
#  endif
1052
# endif
1053
# ifdef __cplusplus
1054
template <typename T>
1055
  T * u32_strrchr_template (T* str, ucs4_t uc);
1056
template <>
1057
  inline uint32_t * u32_strrchr_template (uint32_t *str, ucs4_t uc)
1058
  { return u32_strrchr (str, uc); }
1059
template <>
1060
  inline const uint32_t * u32_strrchr_template (const uint32_t *str, ucs4_t uc)
1061
  { return u32_strrchr (str, uc); }
1062
#  undef u32_strrchr
1063
#  define u32_strrchr u32_strrchr_template
1064
# elif !defined u32_strrchr
1065
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1066
       || defined __ICC  || defined __TINYC__ \
1067
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1068
#   define u32_strrchr(s,u) \
1069
      _Generic ((s), \
1070
                uint32_t const *: (uint32_t const *) u32_strrchr ((s), (u)), \
1071
                default         :                    u32_strrchr ((s), (u)))
1072
#  endif
1073
# endif
1074
#endif
1075
1076
/* Return the length of the initial segment of STR which consists entirely
1077
   of Unicode characters not in REJECT.  */
1078
/* Similar to strcspn(), wcscspn().  */
1079
extern size_t
1080
       u8_strcspn (const uint8_t *str, const uint8_t *reject)
1081
       _UC_ATTRIBUTE_PURE;
1082
extern size_t
1083
       u16_strcspn (const uint16_t *str, const uint16_t *reject)
1084
       _UC_ATTRIBUTE_PURE;
1085
extern size_t
1086
       u32_strcspn (const uint32_t *str, const uint32_t *reject)
1087
       _UC_ATTRIBUTE_PURE;
1088
1089
/* Return the length of the initial segment of STR which consists entirely
1090
   of Unicode characters in ACCEPT.  */
1091
/* Similar to strspn(), wcsspn().  */
1092
extern size_t
1093
       u8_strspn (const uint8_t *str, const uint8_t *accept)
1094
       _UC_ATTRIBUTE_PURE;
1095
extern size_t
1096
       u16_strspn (const uint16_t *str, const uint16_t *accept)
1097
       _UC_ATTRIBUTE_PURE;
1098
extern size_t
1099
       u32_strspn (const uint32_t *str, const uint32_t *accept)
1100
       _UC_ATTRIBUTE_PURE;
1101
1102
/* Find the first occurrence in STR of any character in ACCEPT.  */
1103
/* Similar to strpbrk(), wcspbrk().  */
1104
extern uint8_t *
1105
       u8_strpbrk (const uint8_t *str, const uint8_t *accept)
1106
       _UC_ATTRIBUTE_PURE;
1107
extern uint16_t *
1108
       u16_strpbrk (const uint16_t *str, const uint16_t *accept)
1109
       _UC_ATTRIBUTE_PURE;
1110
extern uint32_t *
1111
       u32_strpbrk (const uint32_t *str, const uint32_t *accept)
1112
       _UC_ATTRIBUTE_PURE;
1113
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
1114
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
1115
   want compiler warnings for 'const' related mistakes.  */
1116
# ifdef __cplusplus
1117
template <typename T>
1118
  T * u8_strpbrk_template (T* str, const uint8_t *accept);
1119
template <>
1120
  inline uint8_t * u8_strpbrk_template (uint8_t *str, const uint8_t *accept)
1121
  { return u8_strpbrk (str, accept); }
1122
template <>
1123
  inline const uint8_t * u8_strpbrk_template (const uint8_t *str, const uint8_t *accept)
1124
  { return u8_strpbrk (str, accept); }
1125
#  undef u8_strpbrk
1126
#  define u8_strpbrk u8_strpbrk_template
1127
# elif !defined u8_strpbrk
1128
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1129
       || defined __ICC  || defined __TINYC__ \
1130
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1131
#   define u8_strpbrk(s,a) \
1132
      _Generic ((s), \
1133
                uint8_t const *: (uint8_t const *) u8_strpbrk ((s), (a)), \
1134
                default        :                   u8_strpbrk ((s), (a)))
1135
#  endif
1136
# endif
1137
# ifdef __cplusplus
1138
template <typename T>
1139
  T * u16_strpbrk_template (T* str, const uint16_t *accept);
1140
template <>
1141
  inline uint16_t * u16_strpbrk_template (uint16_t *str, const uint16_t *accept)
1142
  { return u16_strpbrk (str, accept); }
1143
template <>
1144
  inline const uint16_t * u16_strpbrk_template (const uint16_t *str, const uint16_t *accept)
1145
  { return u16_strpbrk (str, accept); }
1146
#  undef u16_strpbrk
1147
#  define u16_strpbrk u16_strpbrk_template
1148
# elif !defined u16_strpbrk
1149
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1150
       || defined __ICC  || defined __TINYC__ \
1151
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1152
#   define u16_strpbrk(s,a) \
1153
      _Generic ((s), \
1154
                uint16_t const *: (uint16_t const *) u16_strpbrk ((s), (a)), \
1155
                default         :                    u16_strpbrk ((s), (a)))
1156
#  endif
1157
# endif
1158
# ifdef __cplusplus
1159
template <typename T>
1160
  T * u32_strpbrk_template (T* str, const uint32_t *accept);
1161
template <>
1162
  inline uint32_t * u32_strpbrk_template (uint32_t *str, const uint32_t *accept)
1163
  { return u32_strpbrk (str, accept); }
1164
template <>
1165
  inline const uint32_t * u32_strpbrk_template (const uint32_t *str, const uint32_t *accept)
1166
  { return u32_strpbrk (str, accept); }
1167
#  undef u32_strpbrk
1168
#  define u32_strpbrk u32_strpbrk_template
1169
# elif !defined u32_strpbrk
1170
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1171
       || defined __ICC  || defined __TINYC__ \
1172
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1173
#   define u32_strpbrk(s,a) \
1174
      _Generic ((s), \
1175
                uint32_t const *: (uint32_t const *) u32_strpbrk ((s), (a)), \
1176
                default         :                    u32_strpbrk ((s), (a)))
1177
#  endif
1178
# endif
1179
#endif
1180
1181
/* Find the first occurrence of NEEDLE in HAYSTACK.  */
1182
/* Similar to strstr(), wcsstr().  */
1183
extern uint8_t *
1184
       u8_strstr (const uint8_t *haystack, const uint8_t *needle)
1185
       _UC_ATTRIBUTE_PURE;
1186
extern uint16_t *
1187
       u16_strstr (const uint16_t *haystack, const uint16_t *needle)
1188
       _UC_ATTRIBUTE_PURE;
1189
extern uint32_t *
1190
       u32_strstr (const uint32_t *haystack, const uint32_t *needle)
1191
       _UC_ATTRIBUTE_PURE;
1192
#ifndef _LIBUNISTRING_NO_CONST_GENERICS
1193
/* Don't silently convert a 'const uintN_t *' to a 'uintN_t *'.  Programmers
1194
   want compiler warnings for 'const' related mistakes.  */
1195
# ifdef __cplusplus
1196
template <typename T>
1197
  T * u8_strstr_template (T* haystack, const uint8_t *needle);
1198
template <>
1199
  inline uint8_t * u8_strstr_template (uint8_t *haystack, const uint8_t *needle)
1200
  { return u8_strstr (haystack, needle); }
1201
template <>
1202
  inline const uint8_t * u8_strstr_template (const uint8_t *haystack, const uint8_t *needle)
1203
  { return u8_strstr (haystack, needle); }
1204
#  undef u8_strstr
1205
#  define u8_strstr u8_strstr_template
1206
# elif !defined u8_strstr
1207
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1208
       || defined __ICC  || defined __TINYC__ \
1209
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1210
#   define u8_strstr(h,n) \
1211
      _Generic ((h), \
1212
                uint8_t const *: (uint8_t const *) u8_strstr ((h), (n)), \
1213
                default        :                   u8_strstr ((h), (n)))
1214
#  endif
1215
# endif
1216
# ifdef __cplusplus
1217
template <typename T>
1218
  T * u16_strstr_template (T* haystack, const uint16_t *needle);
1219
template <>
1220
  inline uint16_t * u16_strstr_template (uint16_t *haystack, const uint16_t *needle)
1221
  { return u16_strstr (haystack, needle); }
1222
template <>
1223
  inline const uint16_t * u16_strstr_template (const uint16_t *haystack, const uint16_t *needle)
1224
  { return u16_strstr (haystack, needle); }
1225
#  undef u16_strstr
1226
#  define u16_strstr u16_strstr_template
1227
# elif !defined u16_strstr
1228
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1229
       || defined __ICC  || defined __TINYC__ \
1230
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1231
#   define u16_strstr(h,n) \
1232
      _Generic ((h), \
1233
                uint16_t const *: (uint16_t const *) u16_strstr ((h), (n)), \
1234
                default         :                    u16_strstr ((h), (n)))
1235
#  endif
1236
# endif
1237
# ifdef __cplusplus
1238
template <typename T>
1239
  T * u32_strstr_template (T* haystack, const uint32_t *needle);
1240
template <>
1241
  inline uint32_t * u32_strstr_template (uint32_t *haystack, const uint32_t *needle)
1242
  { return u32_strstr (haystack, needle); }
1243
template <>
1244
  inline const uint32_t * u32_strstr_template (const uint32_t *haystack, const uint32_t *needle)
1245
  { return u32_strstr (haystack, needle); }
1246
#  undef u32_strstr
1247
#  define u32_strstr u32_strstr_template
1248
# elif !defined u32_strstr
1249
#  if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \
1250
       || defined __ICC  || defined __TINYC__ \
1251
       || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__)))
1252
#   define u32_strstr(h,n) \
1253
      _Generic ((h), \
1254
                uint32_t const *: (uint32_t const *) u32_strstr ((h), (n)), \
1255
                default         :                    u32_strstr ((h), (n)))
1256
#  endif
1257
# endif
1258
#endif
1259
1260
/* Test whether STR starts with PREFIX.  */
1261
extern bool
1262
       u8_startswith (const uint8_t *str, const uint8_t *prefix)
1263
       _UC_ATTRIBUTE_PURE;
1264
extern bool
1265
       u16_startswith (const uint16_t *str, const uint16_t *prefix)
1266
       _UC_ATTRIBUTE_PURE;
1267
extern bool
1268
       u32_startswith (const uint32_t *str, const uint32_t *prefix)
1269
       _UC_ATTRIBUTE_PURE;
1270
1271
/* Test whether STR ends with SUFFIX.  */
1272
extern bool
1273
       u8_endswith (const uint8_t *str, const uint8_t *suffix)
1274
       _UC_ATTRIBUTE_PURE;
1275
extern bool
1276
       u16_endswith (const uint16_t *str, const uint16_t *suffix)
1277
       _UC_ATTRIBUTE_PURE;
1278
extern bool
1279
       u32_endswith (const uint32_t *str, const uint32_t *suffix)
1280
       _UC_ATTRIBUTE_PURE;
1281
1282
/* Divide STR into tokens separated by characters in DELIM.
1283
   This interface is actually more similar to wcstok than to strtok.  */
1284
/* Similar to strtok_r(), wcstok().  */
1285
extern uint8_t *
1286
       u8_strtok (uint8_t *_UC_RESTRICT str, const uint8_t *delim,
1287
                  uint8_t **ptr);
1288
extern uint16_t *
1289
       u16_strtok (uint16_t *_UC_RESTRICT str, const uint16_t *delim,
1290
                   uint16_t **ptr);
1291
extern uint32_t *
1292
       u32_strtok (uint32_t *_UC_RESTRICT str, const uint32_t *delim,
1293
                   uint32_t **ptr);
1294
1295
1296
#ifdef __cplusplus
1297
}
1298
#endif
1299
1300
#endif /* _UNISTR_H */