utf8proc.h 32.3 KB
Newer Older
1
/*
liucong's avatar
liucong committed
2
3
4
 * Copyright (c) 2014-2021 Steven G. Johnson, Jiahao Chen, Peter Colberg, Tony
 * Kelman, Scott P. Jones, and other contributors. Copyright (c) 2009 Public
 * Software Group e. V., Berlin, Germany
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * @mainpage
 *
 * utf8proc is a free/open-source (MIT/expat licensed) C library
 * providing Unicode normalization, case-folding, and other operations
 * for strings in the UTF-8 encoding, supporting up-to-date Unicode versions.
 * See the utf8proc home page (http://julialang.org/utf8proc/)
 * for downloads and other information, or the source code on github
 * (https://github.com/JuliaLang/utf8proc).
 *
 * For the utf8proc API documentation, see: @ref utf8proc.h
 *
 * The features of utf8proc include:
 *
 * - Transformation of strings (@ref utf8proc_map) to:
liucong's avatar
liucong committed
40
41
42
 *    - decompose (@ref UTF8PROC_DECOMPOSE) or compose (@ref UTF8PROC_COMPOSE)
 * Unicode combining characters
 * (http://en.wikipedia.org/wiki/Combining_character)
43
 *    - canonicalize Unicode compatibility characters (@ref UTF8PROC_COMPAT)
liucong's avatar
liucong committed
44
45
46
 *    - strip "ignorable" (@ref UTF8PROC_IGNORE) characters, control characters
 * (@ref UTF8PROC_STRIPCC), or combining characters such as accents (@ref
 * UTF8PROC_STRIPMARK)
47
 *    - case-folding (@ref UTF8PROC_CASEFOLD)
liucong's avatar
liucong committed
48
49
50
51
 * - Unicode normalization: @ref utf8proc_NFD, @ref utf8proc_NFC, @ref
 * utf8proc_NFKD, @ref utf8proc_NFKC
 * - Detecting grapheme boundaries (@ref utf8proc_grapheme_break and @ref
 * UTF8PROC_CHARBOUND)
52
 * - Character-width computation: @ref utf8proc_charwidth
liucong's avatar
liucong committed
53
54
55
56
 * - Classification of characters by Unicode category: @ref utf8proc_category
 * and @ref utf8proc_category_string
 * - Encode (@ref utf8proc_encode_char) and decode (@ref utf8proc_iterate)
 * Unicode codepoints to/from UTF-8.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 */

/** @file */

#ifndef UTF8PROC_H
#define UTF8PROC_H

/** @name API version
 *
 * The utf8proc API version MAJOR.MINOR.PATCH, following
 * semantic-versioning rules (http://semver.org) based on API
 * compatibility.
 *
 * This is also returned at runtime by @ref utf8proc_version; however, the
 * runtime version may append a string like "-dev" to the version number
 * for prerelease versions.
 *
 * @note The shared-library version number in the Makefile
 *       (and CMakeLists.txt, and MANIFEST) may be different,
 *       being based on ABI compatibility rather than API compatibility.
 */
/** @{ */
liucong's avatar
liucong committed
79
80
/** The MAJOR version number (increased when backwards API compatibility is
 * broken). */
81
#define UTF8PROC_VERSION_MAJOR 2
liucong's avatar
liucong committed
82
83
/** The MINOR version number (increased when new functionality is added in a
 * backwards-compatible manner). */
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#define UTF8PROC_VERSION_MINOR 8
/** The PATCH version (increased for fixes that do not change the API). */
#define UTF8PROC_VERSION_PATCH 0
/** @} */

#include <stdlib.h>

#if defined(_MSC_VER) && _MSC_VER < 1800
// MSVC prior to 2013 lacked stdbool.h and inttypes.h
typedef signed char utf8proc_int8_t;
typedef unsigned char utf8proc_uint8_t;
typedef short utf8proc_int16_t;
typedef unsigned short utf8proc_uint16_t;
typedef int utf8proc_int32_t;
typedef unsigned int utf8proc_uint32_t;
liucong's avatar
liucong committed
99
#ifdef _WIN64
100
101
typedef __int64 utf8proc_ssize_t;
typedef unsigned __int64 utf8proc_size_t;
liucong's avatar
liucong committed
102
#else
103
104
typedef int utf8proc_ssize_t;
typedef unsigned int utf8proc_size_t;
liucong's avatar
liucong committed
105
106
#endif
#ifndef __cplusplus
107
108
// emulate C99 bool
typedef unsigned char utf8proc_bool;
liucong's avatar
liucong committed
109
110
111
112
113
114
#ifndef __bool_true_false_are_defined
#define false 0
#define true 1
#define __bool_true_false_are_defined 1
#endif
#else
115
typedef bool utf8proc_bool;
liucong's avatar
liucong committed
116
#endif
117
#else
liucong's avatar
liucong committed
118
119
120
121
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>

122
123
124
125
126
127
128
129
130
131
132
133
134
typedef int8_t utf8proc_int8_t;
typedef uint8_t utf8proc_uint8_t;
typedef int16_t utf8proc_int16_t;
typedef uint16_t utf8proc_uint16_t;
typedef int32_t utf8proc_int32_t;
typedef uint32_t utf8proc_uint32_t;
typedef size_t utf8proc_size_t;
typedef ptrdiff_t utf8proc_ssize_t;
typedef bool utf8proc_bool;
#endif
#include <limits.h>

#ifdef UTF8PROC_STATIC
liucong's avatar
liucong committed
135
#define UTF8PROC_DLLEXPORT
136
#else
liucong's avatar
liucong committed
137
138
139
140
141
142
143
144
145
146
147
#ifdef _WIN32
#ifdef UTF8PROC_EXPORTS
#define UTF8PROC_DLLEXPORT __declspec(dllexport)
#else
#define UTF8PROC_DLLEXPORT __declspec(dllimport)
#endif
#elif __GNUC__ >= 4
#define UTF8PROC_DLLEXPORT __attribute__((visibility("default")))
#else
#define UTF8PROC_DLLEXPORT
#endif
148
149
150
151
152
153
154
155
156
#endif

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Option flags used by several functions in the library.
 */
liucong's avatar
liucong committed
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
typedef enum
{
    /** The given UTF-8 input is NULL terminated. */
    UTF8PROC_NULLTERM = (1 << 0),
    /** Unicode Versioning Stability has to be respected. */
    UTF8PROC_STABLE = (1 << 1),
    /** Compatibility decomposition (i.e. formatting information is lost). */
    UTF8PROC_COMPAT = (1 << 2),
    /** Return a result with decomposed characters. */
    UTF8PROC_COMPOSE = (1 << 3),
    /** Return a result with decomposed characters. */
    UTF8PROC_DECOMPOSE = (1 << 4),
    /** Strip "default ignorable characters" such as SOFT-HYPHEN or
       ZERO-WIDTH-SPACE. */
    UTF8PROC_IGNORE = (1 << 5),
    /** Return an error, if the input contains unassigned codepoints. */
    UTF8PROC_REJECTNA = (1 << 6),
    /**
     * Indicating that NLF-sequences (LF, CRLF, CR, NEL) are representing a
     * line break, and should be converted to the codepoint for line
     * separation (LS).
     */
    UTF8PROC_NLF2LS = (1 << 7),
    /**
     * Indicating that NLF-sequences are representing a paragraph break, and
     * should be converted to the codepoint for paragraph separation
     * (PS).
     */
    UTF8PROC_NLF2PS = (1 << 8),
    /** Indicating that the meaning of NLF-sequences is unknown. */
    UTF8PROC_NLF2LF = (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS),
    /** Strips and/or convers control characters.
     *
     * NLF-sequences are transformed into space, except if one of the
     * NLF2LS/PS/LF options is given. HorizontalTab (HT) and FormFeed (FF)
     * are treated as a NLF-sequence in this case.  All other control
     * characters are simply removed.
     */
    UTF8PROC_STRIPCC = (1 << 9),
    /**
     * Performs unicode case folding, to be able to do a case-insensitive
     * string comparison.
     */
    UTF8PROC_CASEFOLD = (1 << 10),
    /**
     * Inserts 0xFF bytes at the beginning of each sequence which is
     * representing a single grapheme cluster (see UAX#29).
     */
    UTF8PROC_CHARBOUND = (1 << 11),
    /** Lumps certain characters together.
     *
     * E.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-". See lump.md for details.
     *
     * If NLF2LF is set, this includes a transformation of paragraph and
     * line separators to ASCII line-feed (LF).
     */
    UTF8PROC_LUMP = (1 << 12),
    /** Strips all character markings.
     *
     * This includes non-spacing, spacing and enclosing (i.e. accents).
     * @note This option works only with @ref UTF8PROC_COMPOSE or
     *       @ref UTF8PROC_DECOMPOSE
     */
    UTF8PROC_STRIPMARK = (1 << 13),
    /**
     * Strip unassigned codepoints.
     */
    UTF8PROC_STRIPNA = (1 << 14),
225
226
227
228
229
230
231
232
233
234
235
236
} utf8proc_option_t;

/** @name Error codes
 * Error codes being returned by almost all functions.
 */
/** @{ */
/** Memory could not be allocated. */
#define UTF8PROC_ERROR_NOMEM -1
/** The given string is too long to be processed. */
#define UTF8PROC_ERROR_OVERFLOW -2
/** The given string is not a legal UTF-8 string. */
#define UTF8PROC_ERROR_INVALIDUTF8 -3
liucong's avatar
liucong committed
237
238
/** The @ref UTF8PROC_REJECTNA flag was set and an unassigned codepoint was
 * found. */
239
240
241
242
243
244
245
246
247
248
249
#define UTF8PROC_ERROR_NOTASSIGNED -4
/** Invalid options have been used. */
#define UTF8PROC_ERROR_INVALIDOPTS -5
/** @} */

/* @name Types */

/** Holds the value of a property. */
typedef utf8proc_int16_t utf8proc_propval_t;

/** Struct containing information about a codepoint. */
liucong's avatar
liucong committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
typedef struct utf8proc_property_struct
{
    /**
     * Unicode category.
     * @see utf8proc_category_t.
     */
    utf8proc_propval_t category;
    utf8proc_propval_t combining_class;
    /**
     * Bidirectional class.
     * @see utf8proc_bidi_class_t.
     */
    utf8proc_propval_t bidi_class;
    /**
     * @anchor Decomposition type.
     * @see utf8proc_decomp_type_t.
     */
    utf8proc_propval_t decomp_type;
    utf8proc_uint16_t decomp_seqindex;
    utf8proc_uint16_t casefold_seqindex;
    utf8proc_uint16_t uppercase_seqindex;
    utf8proc_uint16_t lowercase_seqindex;
    utf8proc_uint16_t titlecase_seqindex;
    utf8proc_uint16_t comb_index;
    unsigned bidi_mirrored : 1;
    unsigned comp_exclusion : 1;
    /**
     * Can this codepoint be ignored?
     *
     * Used by @ref utf8proc_decompose_char when @ref UTF8PROC_IGNORE is
     * passed as an option.
     */
    unsigned ignorable : 1;
    unsigned control_boundary : 1;
    /** The width of the codepoint. */
    unsigned charwidth : 2;
    unsigned pad : 2;
    /**
     * Boundclass.
     * @see utf8proc_boundclass_t.
     */
    unsigned boundclass : 8;
292
293
294
} utf8proc_property_t;

/** Unicode categories. */
liucong's avatar
liucong committed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
typedef enum
{
    UTF8PROC_CATEGORY_CN = 0,  /**< Other, not assigned */
    UTF8PROC_CATEGORY_LU = 1,  /**< Letter, uppercase */
    UTF8PROC_CATEGORY_LL = 2,  /**< Letter, lowercase */
    UTF8PROC_CATEGORY_LT = 3,  /**< Letter, titlecase */
    UTF8PROC_CATEGORY_LM = 4,  /**< Letter, modifier */
    UTF8PROC_CATEGORY_LO = 5,  /**< Letter, other */
    UTF8PROC_CATEGORY_MN = 6,  /**< Mark, nonspacing */
    UTF8PROC_CATEGORY_MC = 7,  /**< Mark, spacing combining */
    UTF8PROC_CATEGORY_ME = 8,  /**< Mark, enclosing */
    UTF8PROC_CATEGORY_ND = 9,  /**< Number, decimal digit */
    UTF8PROC_CATEGORY_NL = 10, /**< Number, letter */
    UTF8PROC_CATEGORY_NO = 11, /**< Number, other */
    UTF8PROC_CATEGORY_PC = 12, /**< Punctuation, connector */
    UTF8PROC_CATEGORY_PD = 13, /**< Punctuation, dash */
    UTF8PROC_CATEGORY_PS = 14, /**< Punctuation, open */
    UTF8PROC_CATEGORY_PE = 15, /**< Punctuation, close */
    UTF8PROC_CATEGORY_PI = 16, /**< Punctuation, initial quote */
    UTF8PROC_CATEGORY_PF = 17, /**< Punctuation, final quote */
    UTF8PROC_CATEGORY_PO = 18, /**< Punctuation, other */
    UTF8PROC_CATEGORY_SM = 19, /**< Symbol, math */
    UTF8PROC_CATEGORY_SC = 20, /**< Symbol, currency */
    UTF8PROC_CATEGORY_SK = 21, /**< Symbol, modifier */
    UTF8PROC_CATEGORY_SO = 22, /**< Symbol, other */
    UTF8PROC_CATEGORY_ZS = 23, /**< Separator, space */
    UTF8PROC_CATEGORY_ZL = 24, /**< Separator, line */
    UTF8PROC_CATEGORY_ZP = 25, /**< Separator, paragraph */
    UTF8PROC_CATEGORY_CC = 26, /**< Other, control */
    UTF8PROC_CATEGORY_CF = 27, /**< Other, format */
    UTF8PROC_CATEGORY_CS = 28, /**< Other, surrogate */
    UTF8PROC_CATEGORY_CO = 29, /**< Other, private use */
327
328
329
} utf8proc_category_t;

/** Bidirectional character classes. */
liucong's avatar
liucong committed
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
typedef enum
{
    UTF8PROC_BIDI_CLASS_L   = 1,  /**< Left-to-Right */
    UTF8PROC_BIDI_CLASS_LRE = 2,  /**< Left-to-Right Embedding */
    UTF8PROC_BIDI_CLASS_LRO = 3,  /**< Left-to-Right Override */
    UTF8PROC_BIDI_CLASS_R   = 4,  /**< Right-to-Left */
    UTF8PROC_BIDI_CLASS_AL  = 5,  /**< Right-to-Left Arabic */
    UTF8PROC_BIDI_CLASS_RLE = 6,  /**< Right-to-Left Embedding */
    UTF8PROC_BIDI_CLASS_RLO = 7,  /**< Right-to-Left Override */
    UTF8PROC_BIDI_CLASS_PDF = 8,  /**< Pop Directional Format */
    UTF8PROC_BIDI_CLASS_EN  = 9,  /**< European Number */
    UTF8PROC_BIDI_CLASS_ES  = 10, /**< European Separator */
    UTF8PROC_BIDI_CLASS_ET  = 11, /**< European Number Terminator */
    UTF8PROC_BIDI_CLASS_AN  = 12, /**< Arabic Number */
    UTF8PROC_BIDI_CLASS_CS  = 13, /**< Common Number Separator */
    UTF8PROC_BIDI_CLASS_NSM = 14, /**< Nonspacing Mark */
    UTF8PROC_BIDI_CLASS_BN  = 15, /**< Boundary Neutral */
    UTF8PROC_BIDI_CLASS_B   = 16, /**< Paragraph Separator */
    UTF8PROC_BIDI_CLASS_S   = 17, /**< Segment Separator */
    UTF8PROC_BIDI_CLASS_WS  = 18, /**< Whitespace */
    UTF8PROC_BIDI_CLASS_ON  = 19, /**< Other Neutrals */
    UTF8PROC_BIDI_CLASS_LRI = 20, /**< Left-to-Right Isolate */
    UTF8PROC_BIDI_CLASS_RLI = 21, /**< Right-to-Left Isolate */
    UTF8PROC_BIDI_CLASS_FSI = 22, /**< First Strong Isolate */
    UTF8PROC_BIDI_CLASS_PDI = 23, /**< Pop Directional Isolate */
355
356
357
} utf8proc_bidi_class_t;

/** Decomposition type. */
liucong's avatar
liucong committed
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
typedef enum
{
    UTF8PROC_DECOMP_TYPE_FONT     = 1,  /**< Font */
    UTF8PROC_DECOMP_TYPE_NOBREAK  = 2,  /**< Nobreak */
    UTF8PROC_DECOMP_TYPE_INITIAL  = 3,  /**< Initial */
    UTF8PROC_DECOMP_TYPE_MEDIAL   = 4,  /**< Medial */
    UTF8PROC_DECOMP_TYPE_FINAL    = 5,  /**< Final */
    UTF8PROC_DECOMP_TYPE_ISOLATED = 6,  /**< Isolated */
    UTF8PROC_DECOMP_TYPE_CIRCLE   = 7,  /**< Circle */
    UTF8PROC_DECOMP_TYPE_SUPER    = 8,  /**< Super */
    UTF8PROC_DECOMP_TYPE_SUB      = 9,  /**< Sub */
    UTF8PROC_DECOMP_TYPE_VERTICAL = 10, /**< Vertical */
    UTF8PROC_DECOMP_TYPE_WIDE     = 11, /**< Wide */
    UTF8PROC_DECOMP_TYPE_NARROW   = 12, /**< Narrow */
    UTF8PROC_DECOMP_TYPE_SMALL    = 13, /**< Small */
    UTF8PROC_DECOMP_TYPE_SQUARE   = 14, /**< Square */
    UTF8PROC_DECOMP_TYPE_FRACTION = 15, /**< Fraction */
    UTF8PROC_DECOMP_TYPE_COMPAT   = 16, /**< Compat */
376
377
378
} utf8proc_decomp_type_t;

/** Boundclass property. (TR29) */
liucong's avatar
liucong committed
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
typedef enum
{
    UTF8PROC_BOUNDCLASS_START              = 0,  /**< Start */
    UTF8PROC_BOUNDCLASS_OTHER              = 1,  /**< Other */
    UTF8PROC_BOUNDCLASS_CR                 = 2,  /**< Cr */
    UTF8PROC_BOUNDCLASS_LF                 = 3,  /**< Lf */
    UTF8PROC_BOUNDCLASS_CONTROL            = 4,  /**< Control */
    UTF8PROC_BOUNDCLASS_EXTEND             = 5,  /**< Extend */
    UTF8PROC_BOUNDCLASS_L                  = 6,  /**< L */
    UTF8PROC_BOUNDCLASS_V                  = 7,  /**< V */
    UTF8PROC_BOUNDCLASS_T                  = 8,  /**< T */
    UTF8PROC_BOUNDCLASS_LV                 = 9,  /**< Lv */
    UTF8PROC_BOUNDCLASS_LVT                = 10, /**< Lvt */
    UTF8PROC_BOUNDCLASS_REGIONAL_INDICATOR = 11, /**< Regional indicator */
    UTF8PROC_BOUNDCLASS_SPACINGMARK        = 12, /**< Spacingmark */
    UTF8PROC_BOUNDCLASS_PREPEND            = 13, /**< Prepend */
    UTF8PROC_BOUNDCLASS_ZWJ                = 14, /**< Zero Width Joiner */

    /* the following are no longer used in Unicode 11, but we keep
       the constants here for backward compatibility */
    UTF8PROC_BOUNDCLASS_E_BASE         = 15, /**< Emoji Base */
    UTF8PROC_BOUNDCLASS_E_MODIFIER     = 16, /**< Emoji Modifier */
    UTF8PROC_BOUNDCLASS_GLUE_AFTER_ZWJ = 17, /**< Glue_After_ZWJ */
    UTF8PROC_BOUNDCLASS_E_BASE_GAZ     = 18, /**< E_BASE + GLUE_AFTER_ZJW */

    /* the Extended_Pictographic property is used in the Unicode 11
       grapheme-boundary rules, so we store it in the boundclass field */
    UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC = 19,
    UTF8PROC_BOUNDCLASS_E_ZWG = 20, /* UTF8PROC_BOUNDCLASS_EXTENDED_PICTOGRAPHIC + ZWJ */
408
409
410
411
412
413
414
} utf8proc_boundclass_t;

/**
 * Function pointer type passed to @ref utf8proc_map_custom and
 * @ref utf8proc_decompose_custom, which is used to specify a user-defined
 * mapping of codepoints to be applied in conjunction with other mappings.
 */
liucong's avatar
liucong committed
415
typedef utf8proc_int32_t (*utf8proc_custom_func)(utf8proc_int32_t codepoint, void* data);
416
417
418
419
420
421
422
423
424
425
426
427

/**
 * Array containing the byte lengths of a UTF-8 encoded codepoint based
 * on the first byte.
 */
UTF8PROC_DLLEXPORT extern const utf8proc_int8_t utf8proc_utf8class[256];

/**
 * Returns the utf8proc API version as a string MAJOR.MINOR.PATCH
 * (http://semver.org format), possibly with a "-dev" suffix for
 * development versions.
 */
liucong's avatar
liucong committed
428
UTF8PROC_DLLEXPORT const char* utf8proc_version(void);
429
430
431
432

/**
 * Returns the utf8proc supported Unicode version as a string MAJOR.MINOR.PATCH.
 */
liucong's avatar
liucong committed
433
UTF8PROC_DLLEXPORT const char* utf8proc_unicode_version(void);
434
435
436
437
438

/**
 * Returns an informative error string for the given utf8proc error code
 * (e.g. the error codes returned by @ref utf8proc_map).
 */
liucong's avatar
liucong committed
439
UTF8PROC_DLLEXPORT const char* utf8proc_errmsg(utf8proc_ssize_t errcode);
440
441
442
443
444
445
446
447
448
449
450

/**
 * Reads a single codepoint from the UTF-8 sequence being pointed to by `str`.
 * The maximum number of bytes read is `strlen`, unless `strlen` is
 * negative (in which case up to 4 bytes are read).
 *
 * If a valid codepoint could be read, it is stored in the variable
 * pointed to by `codepoint_ref`, otherwise that variable will be set to -1.
 * In case of success, the number of bytes read is returned; otherwise, a
 * negative error code is returned.
 */
liucong's avatar
liucong committed
451
452
453
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_iterate(const utf8proc_uint8_t* str,
                                                     utf8proc_ssize_t strlen,
                                                     utf8proc_int32_t* codepoint_ref);
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471

/**
 * Check if a codepoint is valid (regardless of whether it has been
 * assigned a value by the current Unicode standard).
 *
 * @return 1 if the given `codepoint` is valid and otherwise return 0.
 */
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_codepoint_valid(utf8proc_int32_t codepoint);

/**
 * Encodes the codepoint as an UTF-8 string in the byte array pointed
 * to by `dst`. This array must be at least 4 bytes long.
 *
 * In case of success the number of bytes written is returned, and
 * otherwise 0 is returned.
 *
 * This function does not check whether `codepoint` is valid Unicode.
 */
liucong's avatar
liucong committed
472
473
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_encode_char(utf8proc_int32_t codepoint,
                                                         utf8proc_uint8_t* dst);
474
475
476
477
478
479
480
481
482
483
484
485
486

/**
 * Look up the properties for a given codepoint.
 *
 * @param codepoint The Unicode codepoint.
 *
 * @returns
 * A pointer to a (constant) struct containing information about
 * the codepoint.
 * @par
 * If the codepoint is unassigned or invalid, a pointer to a special struct is
 * returned in which `category` is 0 (@ref UTF8PROC_CATEGORY_CN).
 */
liucong's avatar
liucong committed
487
UTF8PROC_DLLEXPORT const utf8proc_property_t* utf8proc_get_property(utf8proc_int32_t codepoint);
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

/** Decompose a codepoint into an array of codepoints.
 *
 * @param codepoint the codepoint.
 * @param dst the destination buffer.
 * @param bufsize the size of the destination buffer.
 * @param options one or more of the following flags:
 * - @ref UTF8PROC_REJECTNA  - return an error `codepoint` is unassigned
 * - @ref UTF8PROC_IGNORE    - strip "default ignorable" codepoints
 * - @ref UTF8PROC_CASEFOLD  - apply Unicode casefolding
 * - @ref UTF8PROC_COMPAT    - replace certain codepoints with their
 *                             compatibility decomposition
 * - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster
 * - @ref UTF8PROC_LUMP      - lump certain different codepoints together
 * - @ref UTF8PROC_STRIPMARK - remove all character marks
 * - @ref UTF8PROC_STRIPNA   - remove unassigned codepoints
 * @param last_boundclass
 * Pointer to an integer variable containing
 * the previous codepoint's boundary class if the @ref UTF8PROC_CHARBOUND
 * option is used.  Otherwise, this parameter is ignored.
 *
 * @return
 * In case of success, the number of codepoints written is returned; in case
 * of an error, a negative error code is returned (@ref utf8proc_errmsg).
 * @par
 * If the number of written codepoints would be bigger than `bufsize`, the
 * required buffer size is returned, while the buffer will be overwritten with
 * undefined data.
 */
liucong's avatar
liucong committed
517
518
519
520
521
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_char(utf8proc_int32_t codepoint,
                                                            utf8proc_int32_t* dst,
                                                            utf8proc_ssize_t bufsize,
                                                            utf8proc_option_t options,
                                                            int* last_boundclass);
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

/**
 * The same as @ref utf8proc_decompose_char, but acts on a whole UTF-8
 * string and orders the decomposed sequences correctly.
 *
 * If the @ref UTF8PROC_NULLTERM flag in `options` is set, processing
 * will be stopped, when a NULL byte is encountered, otherwise `strlen`
 * bytes are processed.  The result (in the form of 32-bit unicode
 * codepoints) is written into the buffer being pointed to by
 * `buffer` (which must contain at least `bufsize` entries).  In case of
 * success, the number of codepoints written is returned; in case of an
 * error, a negative error code is returned (@ref utf8proc_errmsg).
 * See @ref utf8proc_decompose_custom to supply additional transformations.
 *
 * If the number of written codepoints would be bigger than `bufsize`, the
 * required buffer size is returned, while the buffer will be overwritten with
 * undefined data.
 */
liucong's avatar
liucong committed
540
541
542
543
544
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose(const utf8proc_uint8_t* str,
                                                       utf8proc_ssize_t strlen,
                                                       utf8proc_int32_t* buffer,
                                                       utf8proc_ssize_t bufsize,
                                                       utf8proc_option_t options);
545
546

/**
liucong's avatar
liucong committed
547
548
549
550
551
 * The same as @ref utf8proc_decompose, but also takes a `custom_func` mapping
 * function that is called on each codepoint in `str` before any other
 * transformations (along with a `custom_data` pointer that is passed through to
 * `custom_func`). The `custom_func` argument is ignored if it is `NULL`.  See
 * also @ref utf8proc_map_custom.
552
 */
liucong's avatar
liucong committed
553
554
555
556
557
558
559
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom(const utf8proc_uint8_t* str,
                                                              utf8proc_ssize_t strlen,
                                                              utf8proc_int32_t* buffer,
                                                              utf8proc_ssize_t bufsize,
                                                              utf8proc_option_t options,
                                                              utf8proc_custom_func custom_func,
                                                              void* custom_data);
560
561
562
563
564
565
566
567
568
569
570

/**
 * Normalizes the sequence of `length` codepoints pointed to by `buffer`
 * in-place (i.e., the result is also stored in `buffer`).
 *
 * @param buffer the (native-endian UTF-32) unicode codepoints to re-encode.
 * @param length the length (in codepoints) of the buffer.
 * @param options a bitwise or (`|`) of one or more of the following flags:
 * - @ref UTF8PROC_NLF2LS  - convert LF, CRLF, CR and NEL into LS
 * - @ref UTF8PROC_NLF2PS  - convert LF, CRLF, CR and NEL into PS
 * - @ref UTF8PROC_NLF2LF  - convert LF, CRLF, CR and NEL into LF
liucong's avatar
liucong committed
571
572
 * - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control
 * characters
573
574
575
576
577
578
 * - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite
 *                           codepoints
 * - @ref UTF8PROC_STABLE  - prohibit combining characters that would violate
 *                           the unicode versioning stability
 *
 * @return
liucong's avatar
liucong committed
579
580
581
 * In case of success, the length (in codepoints) of the normalized UTF-32
 * string is returned; otherwise, a negative error code is returned (@ref
 * utf8proc_errmsg).
582
583
584
585
 *
 * @warning The entries of the array pointed to by `str` have to be in the
 *          range `0x0000` to `0x10FFFF`. Otherwise, the program might crash!
 */
liucong's avatar
liucong committed
586
587
588
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_normalize_utf32(utf8proc_int32_t* buffer,
                                                             utf8proc_ssize_t length,
                                                             utf8proc_option_t options);
589
590
591
592
593
594
595
596
597
598
599
600

/**
 * Reencodes the sequence of `length` codepoints pointed to by `buffer`
 * UTF-8 data in-place (i.e., the result is also stored in `buffer`).
 * Can optionally normalize the UTF-32 sequence prior to UTF-8 conversion.
 *
 * @param buffer the (native-endian UTF-32) unicode codepoints to re-encode.
 * @param length the length (in codepoints) of the buffer.
 * @param options a bitwise or (`|`) of one or more of the following flags:
 * - @ref UTF8PROC_NLF2LS  - convert LF, CRLF, CR and NEL into LS
 * - @ref UTF8PROC_NLF2PS  - convert LF, CRLF, CR and NEL into PS
 * - @ref UTF8PROC_NLF2LF  - convert LF, CRLF, CR and NEL into LF
liucong's avatar
liucong committed
601
602
 * - @ref UTF8PROC_STRIPCC - strip or convert all non-affected control
 * characters
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
 * - @ref UTF8PROC_COMPOSE - try to combine decomposed codepoints into composite
 *                           codepoints
 * - @ref UTF8PROC_STABLE  - prohibit combining characters that would violate
 *                           the unicode versioning stability
 * - @ref UTF8PROC_CHARBOUND - insert 0xFF bytes before each grapheme cluster
 *
 * @return
 * In case of success, the length (in bytes) of the resulting nul-terminated
 * UTF-8 string is returned; otherwise, a negative error code is returned
 * (@ref utf8proc_errmsg).
 *
 * @warning The amount of free space pointed to by `buffer` must
 *          exceed the amount of the input data by one byte, and the
 *          entries of the array pointed to by `str` have to be in the
 *          range `0x0000` to `0x10FFFF`. Otherwise, the program might crash!
 */
liucong's avatar
liucong committed
619
620
621
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_reencode(utf8proc_int32_t* buffer,
                                                      utf8proc_ssize_t length,
                                                      utf8proc_option_t options);
622
623
624

/**
 * Given a pair of consecutive codepoints, return whether a grapheme break is
liucong's avatar
liucong committed
625
626
 * permitted between them (as defined by the extended grapheme clusters in
 * UAX#29).
627
628
 *
 * @param codepoint1 The first codepoint.
liucong's avatar
liucong committed
629
630
631
632
 * @param codepoint2 The second codepoint, occurring consecutively after
 * `codepoint1`.
 * @param state Beginning with Version 29 (Unicode 9.0.0), this algorithm
 * requires state to break graphemes. This state can be passed in as a pointer
633
 *              in the `state` argument and should initially be set to 0. If the
liucong's avatar
liucong committed
634
635
 *              state is not passed in (i.e. a null pointer is passed), UAX#29
 * rules GB10/12/13 which require this state will not be applied, essentially
636
637
 *              matching the rules in Unicode 8.0.0.
 *
liucong's avatar
liucong committed
638
639
640
 * @warning If the state parameter is used, `utf8proc_grapheme_break_stateful`
 * must be called IN ORDER on ALL potential breaks in a string.  However, it is
 * safe to reset the state to zero after a grapheme break.
641
 */
liucong's avatar
liucong committed
642
643
644
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break_stateful(utf8proc_int32_t codepoint1,
                                                                  utf8proc_int32_t codepoint2,
                                                                  utf8proc_int32_t* state);
645
646
647
648
649

/**
 * Same as @ref utf8proc_grapheme_break_stateful, except without support for the
 * Unicode 9 additions to the algorithm. Supported for legacy reasons.
 */
liucong's avatar
liucong committed
650
651
UTF8PROC_DLLEXPORT utf8proc_bool utf8proc_grapheme_break(utf8proc_int32_t codepoint1,
                                                         utf8proc_int32_t codepoint2);
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674

/**
 * Given a codepoint `c`, return the codepoint of the corresponding
 * lower-case character, if any; otherwise (if there is no lower-case
 * variant, or if `c` is not a valid codepoint) return `c`.
 */
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_tolower(utf8proc_int32_t c);

/**
 * Given a codepoint `c`, return the codepoint of the corresponding
 * upper-case character, if any; otherwise (if there is no upper-case
 * variant, or if `c` is not a valid codepoint) return `c`.
 */
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_toupper(utf8proc_int32_t c);

/**
 * Given a codepoint `c`, return the codepoint of the corresponding
 * title-case character, if any; otherwise (if there is no title-case
 * variant, or if `c` is not a valid codepoint) return `c`.
 */
UTF8PROC_DLLEXPORT utf8proc_int32_t utf8proc_totitle(utf8proc_int32_t c);

/**
liucong's avatar
liucong committed
675
676
 * Given a codepoint `c`, return `1` if the codepoint corresponds to a
 * lower-case character and `0` otherwise.
677
678
679
680
 */
UTF8PROC_DLLEXPORT int utf8proc_islower(utf8proc_int32_t c);

/**
liucong's avatar
liucong committed
681
682
 * Given a codepoint `c`, return `1` if the codepoint corresponds to an
 * upper-case character and `0` otherwise.
683
684
685
686
 */
UTF8PROC_DLLEXPORT int utf8proc_isupper(utf8proc_int32_t c);

/**
liucong's avatar
liucong committed
687
688
689
 * Given a codepoint, return a character width analogous to
 * `wcwidth(codepoint)`, except that a width of 0 is returned for non-printable
 * codepoints instead of -1 as in `wcwidth`.
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
 *
 * @note
 * If you want to check for particular types of non-printable characters,
 * (analogous to `isprint` or `iscntrl`), use @ref utf8proc_category. */
UTF8PROC_DLLEXPORT int utf8proc_charwidth(utf8proc_int32_t codepoint);

/**
 * Return the Unicode category for the codepoint (one of the
 * @ref utf8proc_category_t constants.)
 */
UTF8PROC_DLLEXPORT utf8proc_category_t utf8proc_category(utf8proc_int32_t codepoint);

/**
 * Return the two-letter (nul-terminated) Unicode category string for
 * the codepoint (e.g. `"Lu"` or `"Co"`).
 */
liucong's avatar
liucong committed
706
UTF8PROC_DLLEXPORT const char* utf8proc_category_string(utf8proc_int32_t codepoint);
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726

/**
 * Maps the given UTF-8 string pointed to by `str` to a new UTF-8
 * string, allocated dynamically by `malloc` and returned via `dstptr`.
 *
 * If the @ref UTF8PROC_NULLTERM flag in the `options` field is set,
 * the length is determined by a NULL terminator, otherwise the
 * parameter `strlen` is evaluated to determine the string length, but
 * in any case the result will be NULL terminated (though it might
 * contain NULL characters with the string if `str` contained NULL
 * characters). Other flags in the `options` field are passed to the
 * functions defined above, and regarded as described.  See also
 * @ref utf8proc_map_custom to supply a custom codepoint transformation.
 *
 * In case of success the length of the new string is returned,
 * otherwise a negative error code is returned.
 *
 * @note The memory of the new UTF-8 string will have been allocated
 * with `malloc`, and should therefore be deallocated with `free`.
 */
liucong's avatar
liucong committed
727
728
729
730
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map(const utf8proc_uint8_t* str,
                                                 utf8proc_ssize_t strlen,
                                                 utf8proc_uint8_t** dstptr,
                                                 utf8proc_option_t options);
731
732
733
734
735
736
737

/**
 * Like @ref utf8proc_map, but also takes a `custom_func` mapping function
 * that is called on each codepoint in `str` before any other transformations
 * (along with a `custom_data` pointer that is passed through to `custom_func`).
 * The `custom_func` argument is ignored if it is `NULL`.
 */
liucong's avatar
liucong committed
738
739
740
741
742
743
UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_map_custom(const utf8proc_uint8_t* str,
                                                        utf8proc_ssize_t strlen,
                                                        utf8proc_uint8_t** dstptr,
                                                        utf8proc_option_t options,
                                                        utf8proc_custom_func custom_func,
                                                        void* custom_data);
744
745
746
747
748
749
750
751
752
753

/** @name Unicode normalization
 *
 * Returns a pointer to newly allocated memory of a NFD, NFC, NFKD, NFKC or
 * NFKC_Casefold normalized version of the null-terminated string `str`.  These
 * are shortcuts to calling @ref utf8proc_map with @ref UTF8PROC_NULLTERM
 * combined with @ref UTF8PROC_STABLE and flags indicating the normalization.
 */
/** @{ */
/** NFD normalization (@ref UTF8PROC_DECOMPOSE). */
liucong's avatar
liucong committed
754
UTF8PROC_DLLEXPORT utf8proc_uint8_t* utf8proc_NFD(const utf8proc_uint8_t* str);
755
/** NFC normalization (@ref UTF8PROC_COMPOSE). */
liucong's avatar
liucong committed
756
UTF8PROC_DLLEXPORT utf8proc_uint8_t* utf8proc_NFC(const utf8proc_uint8_t* str);
757
/** NFKD normalization (@ref UTF8PROC_DECOMPOSE and @ref UTF8PROC_COMPAT). */
liucong's avatar
liucong committed
758
UTF8PROC_DLLEXPORT utf8proc_uint8_t* utf8proc_NFKD(const utf8proc_uint8_t* str);
759
/** NFKC normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT). */
liucong's avatar
liucong committed
760
UTF8PROC_DLLEXPORT utf8proc_uint8_t* utf8proc_NFKC(const utf8proc_uint8_t* str);
761
762
763
764
/**
 * NFKC_Casefold normalization (@ref UTF8PROC_COMPOSE and @ref UTF8PROC_COMPAT
 * and @ref UTF8PROC_CASEFOLD and @ref UTF8PROC_IGNORE).
 **/
liucong's avatar
liucong committed
765
UTF8PROC_DLLEXPORT utf8proc_uint8_t* utf8proc_NFKC_Casefold(const utf8proc_uint8_t* str);
766
767
768
769
770
771
772
/** @} */

#ifdef __cplusplus
}
#endif

#endif