Coverage Report

Created: 2026-02-05 06:23

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