diff options
| author | Mattias Andrée <m@maandree.se> | 2026-10-18 13:21:09 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-10-18 13:21:09 +0200 |
| commit | 53b3e04d87f1f81845716e585efcba3c9f7cf9e5 (patch) | |
| tree | 6daf34677c9dc5b2dbda75881a084aff0d400f88 | |
| parent | Add to codepoint data whether the codepoint is a character or not (diff) | |
| download | libcmap-master.tar.gz libcmap-master.tar.bz2 libcmap-master.tar.xz | |
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | UnicodeData.parse.c | 20 | ||||
| -rw-r--r-- | common.h | 2 | ||||
| -rw-r--r-- | libcmap.h | 62 | ||||
| -rw-r--r-- | libcmap_bidirectional_category_string.c | 46 | ||||
| -rw-r--r-- | libcmap_codepoint_list.c | 7 | ||||
| -rw-r--r-- | libcmap_decomposition_type_string.c | 28 | ||||
| -rw-r--r-- | libcmap_find_codepoint_data.c | 2 | ||||
| -rw-r--r-- | libcmap_general_category_string.c | 59 | ||||
| -rw-r--r-- | libcmap_get_codepoint_data.c | 123 | ||||
| -rw-r--r-- | libcmap_numeric_type_string.c | 15 |
11 files changed, 361 insertions, 8 deletions
@@ -29,6 +29,11 @@ OBJ =\ libcmap_find_block.o\ libcmap_find_script.o\ libcmap_find_codepoint_data.o\ + libcmap_get_codepoint_data.o\ + libcmap_general_category_string.o\ + libcmap_bidirectional_category_string.o\ + libcmap_numeric_type_string.o\ + libcmap_decomposition_type_string.o\ libcmap_sprint_range.o\ libcmap_snprint_range.o\ libcmap_fprint_range.o\ diff --git a/UnicodeData.parse.c b/UnicodeData.parse.c index f9b676c..14aff33 100644 --- a/UnicodeData.parse.c +++ b/UnicodeData.parse.c @@ -128,6 +128,8 @@ split(char **text) static int output_character_data(char *text) { + static int first_first = 1; + char *field, *numeric_value = NULL, *simple_uppercase_mapping; unsigned long int codepoint; const char *formatted; @@ -138,6 +140,17 @@ output_character_data(char *text) if (!(field = split(&text))) return 0; add_linef(".name = \"%s\"", field); + if (strstr(field, ", First>")) { + if (first_first) { + ret |= printf("static const struct libcmap_range gaplist[] = {\n"); + first_first = 0; + } else { + ret |= printf(",\n"); + } + ret |= printf("\t{UINT32_C(0x%04lX)", codepoint); + } else if (strstr(field, ", Last>")) { + ret |= printf(", UINT32_C(0x%04lX)}", codepoint); + } if (!(field = split(&text))) return 0; add_linef(", .general_category = GENERAL_CATEGORY_%s", field); @@ -215,7 +228,10 @@ output_character_data(char *text) add_linef(", .bidirectional_mirrored = BIDIRECTIONAL_MIRRORED_%s", field); if (!(field = split(&text))) return 0; - add_linef(", .unicode_1_name = \"%s\"", field); + if (*field) + add_linef(", .unicode_1_name = \"%s\"", field); + else + add_linef(", .unicode_1_name = NULL"); if (!(field = split(&text))) return 0; /* ISO 10646 comment field -- always empty as of Unicode 5.2.0 */ @@ -371,6 +387,8 @@ output(void) uint32_t *seq = NULL; size_t i, seqlen = 0u, off, end, ext; + ret |= printf("\n};\n"); + if (!nsegments) { fprintf(stderr, "%s: character list is empty\n", argv0); exit(1); @@ -1,6 +1,8 @@ /* See LICENSE file for copyright and license details. */ #include "libcmap.h" +#include <errno.h> #include <limits.h> +#include <string.h> #define SINGLETON_RANGE_FMT "U+%04lX" @@ -53,8 +53,8 @@ enum libcmap_general_category { LIBCMAP_GENERAL_CATEGORY_LETTER_MODIFIER, LIBCMAP_GENERAL_CATEGORY_LETTER_OTHER, LIBCMAP_GENERAL_CATEGORY_MARK_NONSPACING = LIBCMAP_GENERAL_SUPERCATEGORY_MARK + 1u, - LIBCMAP_GENERAL_CATEGORY_MARK_SPACING_COMBINING, - LIBCMAP_GENERAL_CATEGORY_MARK_ENCODING, + LIBCMAP_GENERAL_CATEGORY_MARK_SPACING, + LIBCMAP_GENERAL_CATEGORY_MARK_ENCLOSING, LIBCMAP_GENERAL_CATEGORY_NUMBER_DECIMAL_DIGIT = LIBCMAP_GENERAL_SUPERCATEGORY_NUMBER + 1u, LIBCMAP_GENERAL_CATEGORY_NUMBER_LETTER, LIBCMAP_GENERAL_CATEGORY_NUMBER_OTHER, @@ -78,8 +78,11 @@ enum libcmap_general_category { LIBCMAP_GENERAL_CATEGORY_OTHER_PRIVATE_USE, /** - * This category has two subcategories: noncharacter and reserved - * If .noncharacter it is not a character, otherwise it is reserved + * This category has two subcategories: noncharacter and reserved. + * If .noncharacter it is not a character, otherwise it is reserved. + * Unfortunately, at the moment there is no way, in the case of + * reserved to distinguish between permanently reserved and not yet + * assigned */ LIBCMAP_GENERAL_CATEGORY_OTHER_NOT_ASSIGNED }; @@ -342,6 +345,7 @@ extern const size_t libcmap_script_list_size; * * @seealso libcmap_codepoint_list_size * @seealso libcmap_find_codepoint_data + * @seealso libcmap_get_codepoint_data */ extern const struct libcmap_codepoint_segment *const libcmap_codepoint_list; @@ -350,6 +354,17 @@ extern const struct libcmap_codepoint_segment *const libcmap_codepoint_list; */ extern const size_t libcmap_codepoint_list_size; +/** + * List of ranges of codepoints not covered by `libcmap_codepoint_list` + * (the boundaries are covered with improper entries) + */ +extern const struct libcmap_range *const libcmap_no_data_range_list; + +/** + * The number of elements in `libcmap_no_data_range_list` + */ +extern const size_t libcmap_no_data_range_list_size; + /** * Find a codepoint within `libcmap_no_block` @@ -426,6 +441,9 @@ const struct libcmap_script *libcmap_find_script(uint32_t codepoint, size_t *off /** * Find data about a specified codepoint * + * You should generally use `libcmap_get_codepoint_data` + * instead of this function + * * @param codepoint The codepoint * @return Information from UnicodeData about the codepoint, * `NULL` if not found @@ -435,10 +453,46 @@ const struct libcmap_script *libcmap_find_script(uint32_t codepoint, size_t *off * which is common for ideographs * * @seealso libcmap_codepoint_list + * @seealso libcmap_get_codepoint_data */ LIBCMAP_PURE_ const struct libcmap_codepoint_data *libcmap_find_codepoint_data(uint32_t codepoint); +/** + * Get data about a specified codepoint + * + * @param codepoint The codepoint + * @param data_out Output parameter for the data + * @param buffer Buffer that the function can store data in, this data + * is then referenced by pointers in `*data_out` + * @param bufsizep Input parameter for the size of `buffer`, and + * output parameter for the required size of `buffer` + * (only set when -1 is returned with `errno` set to ERANGE) + * @return 1 if `codepoint` is within the range of codepoints + * (that is, if `codepoint` is no greater than + * LIBCMAP_ULTIMATE_CODEPOINT), 0 otherwise, -1 on failure + * + * @throws ERANGE `*bufsizep` was too small, but has been update with the required size + * + * `*data_out` is only updated if 1 is returned + * + * Unlike `libcmap_find_codepoint_data`, this function can + * synthesis the data for codepoints that are not in UnicodeData, + * and can correct the names where the codepoint is listing in + * UnicodeData as the start or end of an omitted range + * + * @seealso libcmap_codepoint_list + * @seealso libcmap_find_codepoint_data + */ +int libcmap_get_codepoint_data(uint32_t codepoint, struct libcmap_codepoint_data *data_out, void *buffer, size_t *bufsizep); + + +/* TODO documentation is needed */ +LIBCMAP_CONST_ const char *libcmap_general_category_string(enum libcmap_general_category value); +LIBCMAP_CONST_ const char *libcmap_bidirectional_category_string(enum libcmap_bidirectional_category value); +LIBCMAP_CONST_ const char *libcmap_numeric_type_string(enum libcmap_numeric_type value); +LIBCMAP_CONST_ const char *libcmap_decomposition_type_string(enum libcmap_decomposition_type value); + /** * Print a string representing a Unicode codepoint range diff --git a/libcmap_bidirectional_category_string.c b/libcmap_bidirectional_category_string.c new file mode 100644 index 0000000..4cbd116 --- /dev/null +++ b/libcmap_bidirectional_category_string.c @@ -0,0 +1,46 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char * +libcmap_bidirectional_category_string(enum libcmap_bidirectional_category value) +{ + switch ((enum libcmap_bidirectional_supercategory)value) { + case LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_STRONG: return "strong"; + case LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_WEAK: return "weak"; + case LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_NEUTRAL: return "neutral"; + case LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_EXPLICIT: return "explicit"; + default: break; + } + + switch (value) { + case LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT: return "Left-to-right"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT: return "Right-to-left"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_ARABIC: return "Arabic right-to-left"; + + case LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER: return "European number"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER_SEPARATOR: return "European number separator"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER_TERMINATOR: return "European number terminator"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_ARABIC_NUMBER: return "Arabic number"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_COMMON_SEPARATOR: return "Common separator"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_NONSPACING_MARK: return "Non-spacing mark"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_BOUNDARY_NEUTRAL: return "Boundary neutral"; + + case LIBCMAP_BIDIRECTIONAL_CATEGORY_PARAGRAPH_SEPARATOR: return "Paragraph separator"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_SEGMENT_SEPARATOR: return "Segment separator"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_WHITESPACE: return "Whitespace"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_OTHER_NEUTRALS: return "Other neutrals"; + + case LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_EMBEDDING: return "Left-to-right embedding"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_OVERRIDE: return "Left-to-right override"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_EMBEDDING: return "Right-to-left embedding"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_OVERRIDE: return "Right-to-left override"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_POP_DIRECTIONAL_FORMAT: return "Pop directional format"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_ISOLATE: return "Left-to-right isolate"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_ISOLATE: return "Right-to-left isolate"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_FIRST_STRONG_ISOLATE: return "First strong isolate"; + case LIBCMAP_BIDIRECTIONAL_CATEGORY_POP_DIRECTIONAL_ISOLATE: return "Pop directional isolate"; + + default: return NULL; + } +} diff --git a/libcmap_codepoint_list.c b/libcmap_codepoint_list.c index d706441..c747236 100644 --- a/libcmap_codepoint_list.c +++ b/libcmap_codepoint_list.c @@ -8,8 +8,8 @@ #define GENERAL_CATEGORY_Lm LIBCMAP_GENERAL_CATEGORY_LETTER_MODIFIER #define GENERAL_CATEGORY_Lo LIBCMAP_GENERAL_CATEGORY_LETTER_OTHER #define GENERAL_CATEGORY_Mn LIBCMAP_GENERAL_CATEGORY_MARK_NONSPACING -#define GENERAL_CATEGORY_Mc LIBCMAP_GENERAL_CATEGORY_MARK_SPACING_COMBINING -#define GENERAL_CATEGORY_Me LIBCMAP_GENERAL_CATEGORY_MARK_ENCODING +#define GENERAL_CATEGORY_Mc LIBCMAP_GENERAL_CATEGORY_MARK_SPACING +#define GENERAL_CATEGORY_Me LIBCMAP_GENERAL_CATEGORY_MARK_ENCLOSING #define GENERAL_CATEGORY_Nd LIBCMAP_GENERAL_CATEGORY_NUMBER_DECIMAL_DIGIT #define GENERAL_CATEGORY_Nl LIBCMAP_GENERAL_CATEGORY_NUMBER_LETTER #define GENERAL_CATEGORY_No LIBCMAP_GENERAL_CATEGORY_NUMBER_OTHER @@ -66,3 +66,6 @@ const struct libcmap_codepoint_segment *const libcmap_codepoint_list = list; const size_t libcmap_codepoint_list_size = sizeof(list) / sizeof(*list); + +const struct libcmap_range *const libcmap_no_data_range_list = gaplist; +const size_t libcmap_no_data_range_list_size = sizeof(gaplist) / sizeof(*gaplist); diff --git a/libcmap_decomposition_type_string.c b/libcmap_decomposition_type_string.c new file mode 100644 index 0000000..f8ea38d --- /dev/null +++ b/libcmap_decomposition_type_string.c @@ -0,0 +1,28 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char * +libcmap_decomposition_type_string(enum libcmap_decomposition_type value) +{ + switch (value) { + case LIBCMAP_DECOMPOSITION_TYPE_CANONICAL: return "Canonical"; + case LIBCMAP_DECOMPOSITION_TYPE_FONT: return "Font"; + case LIBCMAP_DECOMPOSITION_TYPE_NO_BREAK: return "No-break"; + case LIBCMAP_DECOMPOSITION_TYPE_INITIAL: return "Initial"; + case LIBCMAP_DECOMPOSITION_TYPE_MEDIAL: return "Medial"; + case LIBCMAP_DECOMPOSITION_TYPE_FINAL: return "Final"; + case LIBCMAP_DECOMPOSITION_TYPE_ISOLATED: return "Isolated"; + case LIBCMAP_DECOMPOSITION_TYPE_CIRCLE: return "Circle"; + case LIBCMAP_DECOMPOSITION_TYPE_SUPER: return "Superscript"; + case LIBCMAP_DECOMPOSITION_TYPE_SUB: return "Subscript"; + case LIBCMAP_DECOMPOSITION_TYPE_VERTICAL: return "Vertical"; + case LIBCMAP_DECOMPOSITION_TYPE_WIDE: return "Wide"; + case LIBCMAP_DECOMPOSITION_TYPE_NARROW: return "Narrow"; + case LIBCMAP_DECOMPOSITION_TYPE_SMALL: return "Small"; + case LIBCMAP_DECOMPOSITION_TYPE_SQUARE: return "Square"; + case LIBCMAP_DECOMPOSITION_TYPE_FRACTION: return "Fraction"; + case LIBCMAP_DECOMPOSITION_TYPE_COMPAT: return "Compat"; + default: return NULL; + } +} diff --git a/libcmap_find_codepoint_data.c b/libcmap_find_codepoint_data.c index cd2e52f..8b048c0 100644 --- a/libcmap_find_codepoint_data.c +++ b/libcmap_find_codepoint_data.c @@ -21,5 +21,5 @@ libcmap_find_codepoint_data(uint32_t codepoint) } } - return NULL; + return NULL; } diff --git a/libcmap_general_category_string.c b/libcmap_general_category_string.c new file mode 100644 index 0000000..2860efe --- /dev/null +++ b/libcmap_general_category_string.c @@ -0,0 +1,59 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char * +libcmap_general_category_string(enum libcmap_general_category value) +{ + switch ((enum libcmap_general_supercategory)value) { + case LIBCMAP_GENERAL_SUPERCATEGORY_LETTER: return "Letter"; + case LIBCMAP_GENERAL_SUPERCATEGORY_MARK: return "Mark"; + case LIBCMAP_GENERAL_SUPERCATEGORY_NUMBER: return "Number"; + case LIBCMAP_GENERAL_SUPERCATEGORY_PUNCTUATION: return "Punctuation"; + case LIBCMAP_GENERAL_SUPERCATEGORY_SYMBOL: return "Symbol"; + case LIBCMAP_GENERAL_SUPERCATEGORY_SEPARATOR: return "Separator"; + case LIBCMAP_GENERAL_SUPERCATEGORY_OTHER: return "Other"; + default: break; + } + + switch (value) { + case LIBCMAP_GENERAL_CATEGORY_LETTER_UPPERCASE: return "Uppercase"; + case LIBCMAP_GENERAL_CATEGORY_LETTER_LOWERCASE: return "Lowercase"; + case LIBCMAP_GENERAL_CATEGORY_LETTER_TITLECASE: return "Titlecase"; + case LIBCMAP_GENERAL_CATEGORY_LETTER_MODIFIER: return "Modifier"; + case LIBCMAP_GENERAL_CATEGORY_LETTER_OTHER: return "Other"; + + case LIBCMAP_GENERAL_CATEGORY_MARK_NONSPACING: return "Non-spacing"; + case LIBCMAP_GENERAL_CATEGORY_MARK_SPACING: return "Spacing"; + case LIBCMAP_GENERAL_CATEGORY_MARK_ENCLOSING: return "Enclosing"; + + case LIBCMAP_GENERAL_CATEGORY_NUMBER_DECIMAL_DIGIT: return "Decimal digit"; + case LIBCMAP_GENERAL_CATEGORY_NUMBER_LETTER: return "Letter"; + case LIBCMAP_GENERAL_CATEGORY_NUMBER_OTHER: return "Other"; + + case LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_CONNECTOR: return "Connector"; + case LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_DASH: return "Dash"; + case LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_OPEN: return "Open"; + case LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_CLOSE: return "Close"; + case LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_INITIAL_QUOTE: return "Initial quote"; + case LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_FINAL_QUOTE: return "Finak quote"; + case LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_OTHER: return "Other"; + + case LIBCMAP_GENERAL_CATEGORY_SYMBOL_MATH: return "Math"; + case LIBCMAP_GENERAL_CATEGORY_SYMBOL_CURRENCY: return "Currency"; + case LIBCMAP_GENERAL_CATEGORY_SYMBOL_MODIFIER: return "Modifier"; + case LIBCMAP_GENERAL_CATEGORY_SYMBOL_OTHER: return "Other"; + + case LIBCMAP_GENERAL_CATEGORY_SEPARATOR_SPACE: return "Space"; + case LIBCMAP_GENERAL_CATEGORY_SEPARATOR_LINE: return "Line"; + case LIBCMAP_GENERAL_CATEGORY_SEPARATOR_PARAGRAPH: return "Paragraph"; + + case LIBCMAP_GENERAL_CATEGORY_OTHER_CONTROL: return "Control"; + case LIBCMAP_GENERAL_CATEGORY_OTHER_FORMAT: return "Format"; + case LIBCMAP_GENERAL_CATEGORY_OTHER_SURROGATE: return "Surrogate"; + case LIBCMAP_GENERAL_CATEGORY_OTHER_PRIVATE_USE: return "Private-use"; + case LIBCMAP_GENERAL_CATEGORY_OTHER_NOT_ASSIGNED: return "Not assigned"; + + default: return NULL; + } +} diff --git a/libcmap_get_codepoint_data.c b/libcmap_get_codepoint_data.c new file mode 100644 index 0000000..553636d --- /dev/null +++ b/libcmap_get_codepoint_data.c @@ -0,0 +1,123 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static int +construct_codepoint_label(const char *metalabel, uint32_t codepoint, void *buffer, size_t *bufsizep) +{ + /* See Unicode Core Spec 4.8.2 Code Point Labels */ + + size_t req = sizeof("-NNNN") + strlen(metalabel) - 2u * (size_t)(*metalabel == '<'); + char *p = buffer; + + if (codepoint >> 16) req += 1u; + if (codepoint >> 20) req += 1u; + + if (*bufsizep < req) { + *bufsizep = req; + errno = ERANGE; + return -1; + } + + p = stpcpy(buffer, &metalabel[*metalabel == '<']); + p -= *metalabel == '<'; + *p++ = '-'; + if (codepoint >> 20) *p++ = "0123456789ABCDEF"[(codepoint >> 20) & 15u]; + if (codepoint >> 16) *p++ = "0123456789ABCDEF"[(codepoint >> 16) & 15u]; + *p++ = "0123456789ABCDEF"[(codepoint >> 12) & 15u]; + *p++ = "0123456789ABCDEF"[(codepoint >> 8) & 15u]; + *p++ = "0123456789ABCDEF"[(codepoint >> 4) & 15u]; + *p++ = "0123456789ABCDEF"[(codepoint >> 0) & 15u]; + *p = '\0'; + + return 0; +} + + +int +libcmap_get_codepoint_data(uint32_t codepoint, struct libcmap_codepoint_data *data_out, void *buffer, size_t *bufsizep) +{ + const struct libcmap_codepoint_data *data; + size_t i, namelen; + const char *metalabel; + + memset(data_out, 0, sizeof(*data_out)); + data_out->name = NULL; + data_out->unicode_1_name = NULL; + data_out->numeric_value = NULL; + data_out->decomposition_mapping = NULL; + + if (codepoint > LIBCMAP_ULTIMATE_CODEPOINT) + return 0; + + if ((0xFDD0u <= codepoint && codepoint <= 0xFDEFu) || (codepoint & 0xFFFEu) == 0xFFFEu) { + if (data_out) { + if (construct_codepoint_label("noncharacter", codepoint, buffer, bufsizep)) + return -1; + data_out->name = buffer; + data_out->general_category = LIBCMAP_GENERAL_CATEGORY_OTHER_NOT_ASSIGNED; + data_out->noncharacter = 1u; + } + return 1; + } + + for (i = 0u; i < libcmap_no_data_range_list_size; i++) { + if (codepoint <= libcmap_no_data_range_list[i].last) { + if (libcmap_no_data_range_list[i].first > codepoint) + break; + if (!data_out) + return 1; + data = libcmap_find_codepoint_data(libcmap_no_data_range_list[i].first); + switch ((int)data->general_category) { + case LIBCMAP_GENERAL_CATEGORY_OTHER_CONTROL: metalabel = "control"; goto have_metalabel; + case LIBCMAP_GENERAL_CATEGORY_OTHER_SURROGATE: metalabel = "surrogate"; goto have_metalabel; + case LIBCMAP_GENERAL_CATEGORY_OTHER_PRIVATE_USE: metalabel = "private-use"; goto have_metalabel; + default: + namelen = strlen(data->name); + namelen -= sizeof(", First") - 1u; + if (namelen + 1u > *bufsizep) { + *bufsizep = namelen + 1u; + errno = ERANGE; + return -1; + } + memcpy(buffer, data->name, namelen - 1u); + ((char *)buffer)[namelen - 1u] = '>'; + ((char *)buffer)[namelen] = '\0'; + break; + + have_metalabel: + if (construct_codepoint_label(metalabel, codepoint, buffer, bufsizep)) + return -1; + break; + } + *data_out = *data; + data_out->name = buffer; + return 1; + } + } + + data = libcmap_find_codepoint_data(codepoint); + if (!data) { + if (data_out) { + if (construct_codepoint_label("reserved", codepoint, buffer, bufsizep)) + return -1; + data_out->name = buffer; + data_out->general_category = LIBCMAP_GENERAL_CATEGORY_OTHER_NOT_ASSIGNED; + data_out->noncharacter = 0u; + } + return 1; + } + + if (data_out) { + if (data->name[0u] == '<') { + if (construct_codepoint_label(data->name, codepoint, buffer, bufsizep)) + return -1; + *data_out = *data; + data_out->name = buffer; + } else { + *data_out = *data; + } + } + + return 1; +} diff --git a/libcmap_numeric_type_string.c b/libcmap_numeric_type_string.c new file mode 100644 index 0000000..e9ea113 --- /dev/null +++ b/libcmap_numeric_type_string.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char * +libcmap_numeric_type_string(enum libcmap_numeric_type value) +{ + switch (value) { + case LIBCMAP_NUMERIC_TYPE_NONE: return "None"; + case LIBCMAP_NUMERIC_TYPE_DECIMAL: return "Decimal"; + case LIBCMAP_NUMERIC_TYPE_DIGIT: return "Digit"; + case LIBCMAP_NUMERIC_TYPE_NUMERIC: return "Numeric"; + default: return NULL; + } +} |
