Coverage Report

Created: 2025-10-12 06:56

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