diff options
| author | Mattias Andrée <m@maandree.se> | 2026-10-16 22:13:02 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-10-16 22:13:02 +0200 |
| commit | 8f2086b5289ee484f9cded05f477096f50d17076 (patch) | |
| tree | cb3780441708288ae702138eeb82b26412bc296d | |
| parent | Fix libcmap_find_block and libcmap_find_script (diff) | |
| download | libcmap-8f2086b5289ee484f9cded05f477096f50d17076.tar.gz libcmap-8f2086b5289ee484f9cded05f477096f50d17076.tar.bz2 libcmap-8f2086b5289ee484f9cded05f477096f50d17076.tar.xz | |
Add codepoint data and Unicode version
Signed-off-by: Mattias Andrée <m@maandree.se>
| -rw-r--r-- | Makefile | 23 | ||||
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | UnicodeData.parse.c | 139 | ||||
| -rw-r--r-- | libcmap.h | 162 | ||||
| -rw-r--r-- | libcmap_codepoint_list.c | 68 | ||||
| -rw-r--r-- | libcmap_find_codepoint_data.c | 25 | ||||
| -rw-r--r-- | libcmap_unicode_version.c | 5 | ||||
| -rw-r--r-- | parse-common.c | 2 |
8 files changed, 422 insertions, 3 deletions
@@ -21,11 +21,14 @@ UNICODE_VERSION = 17.0.0 OBJ =\ + libcmap_unicode_version.o\ libcmap_block_list.o\ libcmap_script_list.o\ + libcmap_codepoint_list.o\ libcmap_find_in_no_block.o\ libcmap_find_block.o\ libcmap_find_script.o\ + libcmap_find_codepoint_data.o\ libcmap_sprint_range.o\ libcmap_snprint_range.o\ libcmap_fprint_range.o\ @@ -40,22 +43,30 @@ LOBJ = $(OBJ:.o=.lo) PARSERS =\ Scripts.parse\ - Blocks.parse + Blocks.parse\ + UnicodeData.parse all: libcmap.a libcmap.$(LIBEXT) $(OBJ): $(HDR) $(LOBJ): $(HDR) $(PARSERS:=.o): parse-common.c +$(PARSERS): libcmap_script_list.o: Scripts.txt.c libcmap_block_list.o: Blocks.txt.c +libcmap_codepoint_list.o: UnicodeData.txt.c + +libcmap_unicode_version.o: Makefile .c.o: - $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) -D'UNICODE_VERSION="$(UNICODE_VERSION)"' .c.lo: - $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS) -D'UNICODE_VERSION="$(UNICODE_VERSION)"' + +.o: + $(CC) -o $@ $< libcmap.a: $(OBJ) @rm -f -- $@ @@ -71,12 +82,18 @@ Scripts.$(UNICODE_VERSION).txt: Blocks.$(UNICODE_VERSION).txt: $(DOWNLOAD) 'https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/Blocks.txt' > $@ +UnicodeData.$(UNICODE_VERSION).txt: + $(DOWNLOAD) 'https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/UnicodeData.txt' > $@ + Scripts.txt.c: Scripts.$(UNICODE_VERSION).txt Scripts.parse ./Scripts.parse < $(@:.txt.c=).$(UNICODE_VERSION).txt > $@ Blocks.txt.c: Blocks.$(UNICODE_VERSION).txt Blocks.parse ./Blocks.parse < $(@:.txt.c=).$(UNICODE_VERSION).txt > $@ +UnicodeData.txt.c: UnicodeData.$(UNICODE_VERSION).txt UnicodeData.parse + ./UnicodeData.parse < $(@:.txt.c=).$(UNICODE_VERSION).txt > $@ + install: libcmap.a libcmap.$(LIBEXT) mkdir -p -- "$(DESTDIR)$(PREFIX)/lib" mkdir -p -- "$(DESTDIR)$(PREFIX)/include" @@ -0,0 +1 @@ +Add man pages diff --git a/UnicodeData.parse.c b/UnicodeData.parse.c new file mode 100644 index 0000000..173fb6a --- /dev/null +++ b/UnicodeData.parse.c @@ -0,0 +1,139 @@ +/* See LICENSE file for copyright and license details. */ +#include "parse-common.c" + + +struct segment { + uint32_t first, last; +}; + + +static struct segment *segments = NULL; +static size_t nsegments = 0u; +static int ret = 0; + + +static char * +split(char **text) +{ + char *field = *text; + if (field) { + *text = strchr(*text, ';'); + if (*text) + *(*text)++ = '\0'; + } + return field; +} + + +static int +output_character_data(char *text) +{ + char *field; + + if (!(field = split(&text))) return 0; /* codepoint */ + + if (!(field = split(&text))) return 0; + ret |= printf(".name = \"%s\"", field); + + if (!(field = split(&text))) return 0; + ret |= printf(", .general_category = GENERAL_CATEGORY_%s", field); + + if (!(field = split(&text))) return 0; + ret |= printf(", .canonical_combining_classes = %su", field); + + if (!(field = split(&text))) return 0; + ret |= printf(", .bidirectional_category = BIDIRECTIONAL_CATEGORY_%s", field); + + if (!(field = split(&text))) return 0; /* TODO Character Decomposition Mapping */ + if (!(field = split(&text))) return 0; /* TODO Decimal digit value */ + if (!(field = split(&text))) return 0; /* TODO Digit value */ + if (!(field = split(&text))) return 0; /* TODO Numeric value */ + + if (!(field = split(&text))) return 0; + ret |= printf(", .bidirectional_mirrored = BIDIRECTIONAL_MIRRORED_%s", field); + + if (!(field = split(&text))) return 0; + ret |= printf(", .unicode_1_name = \"%s\"", field); + + if (!(field = split(&text))) return 0; /* ISO 10646 comment field -- always empty as of Unicode 5.2.0 */ + + if (!(field = split(&text))) return 0; /* TODO Uppercase Mapping */ + if (!(field = split(&text))) return 0; /* TODO Lowercase Mapping */ + if (!(field = split(&text))) return 0; /* TODO Titlecase Mapping */ + + return 1; +} + + +static void +parse_line(char *text, size_t lineno) +{ + unsigned long int codepoint; + char *end; + + if (!isxdigit(*text)) { + malformat: + fprintf(stderr, "%s: line %zu in is malformatted\n", argv0, lineno); + exit(1); + } + + errno = 0; + + codepoint = strtoul(text, &end, 16); + if (errno || codepoint > ULTIMATE_CODEPOINT || *end != ';') + goto malformat; + + if (!nsegments) { + new_segment: + ret |= printf("static const struct libcmap_codepoint_data data_from_%04lx[] = {\n", codepoint); + segments = realloc(segments, ++nsegments * sizeof(*segments)); + if (!segments) { + fprintf(stderr, "%s: realloc %zu: %s\n", argv0, nsegments * sizeof(*segments), strerror(errno)); + exit(1); + } + segments[nsegments - 1u].first = (uint32_t)codepoint; + goto new_codepoint; + } else if (segments[nsegments - 1u].last + 1u == (uint32_t)codepoint) { + ret |= printf(",\n"); + new_codepoint: + segments[nsegments - 1u].last = (uint32_t)codepoint; + ret |= printf("\t{"); + if (!output_character_data(text)) + goto malformat; + ret |= printf("}"); + } else { + if ((uint32_t)codepoint < segments[nsegments - 1u].last) { + fprintf(stderr, "%s: UnicodeData is not sorted\n", argv0); + exit(1); + } + ret |= printf("\n};\n"); + goto new_segment; + } +} + + +static int +output(void) +{ + size_t i; + + if (!nsegments) { + fprintf(stderr, "%s: character list is empty\n", argv0); + exit(1); + } + + ret |= printf("\n};\n"); + + ret |= printf("static const struct libcmap_codepoint_segment list[] = {\n"); + for (i = 0u; i < nsegments; i++) { + if (i) + ret |= printf(",\n"); + ret |= printf("\t{.range = {0x%04"PRIX32", 0x%04"PRIX32"}, .data = data_from_%04"PRIx32"}", + segments[i].first, segments[i].last, segments[i].first); + } + ret |= printf("\n};\n"); + + free(segments); + + return ret; +} @@ -36,6 +36,88 @@ #define LIBCMAP_RANGE_SIZE(RANGE) ((size_t)((RANGE)->last - (RANGE)->first + 1u)) +enum libcmap_general_supercategory { + LIBCMAP_GENERAL_SUPERCATEGORY_LETTER = 0x0100u, + LIBCMAP_GENERAL_SUPERCATEGORY_MARK = 0x0200u, + LIBCMAP_GENERAL_SUPERCATEGORY_NUMBER = 0x0300u, + LIBCMAP_GENERAL_SUPERCATEGORY_PUNCTUATION = 0x0400u, + LIBCMAP_GENERAL_SUPERCATEGORY_SYMBOL = 0x0500u, + LIBCMAP_GENERAL_SUPERCATEGORY_SEPARATOR = 0x0600u, + LIBCMAP_GENERAL_SUPERCATEGORY_OTHER = 0x0700u +}; + +enum libcmap_general_category { + LIBCMAP_GENERAL_CATEGORY_LETTER_UPPERCASE = LIBCMAP_GENERAL_SUPERCATEGORY_LETTER + 1u, + LIBCMAP_GENERAL_CATEGORY_LETTER_LOWERCASE, + LIBCMAP_GENERAL_CATEGORY_LETTER_TITLECASE, + 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_NUMBER_DECIMAL_DIGIT = LIBCMAP_GENERAL_SUPERCATEGORY_NUMBER + 1u, + LIBCMAP_GENERAL_CATEGORY_NUMBER_LETTER, + LIBCMAP_GENERAL_CATEGORY_NUMBER_OTHER, + LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_CONNECTOR = LIBCMAP_GENERAL_SUPERCATEGORY_PUNCTUATION + 1u, + LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_DASH, + LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_OPEN, + LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_CLOSE, + LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_INITIAL_QUOTE, + LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_FINAL_QUOTE, + LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_OTHER, + LIBCMAP_GENERAL_CATEGORY_SYMBOL_MATH = LIBCMAP_GENERAL_SUPERCATEGORY_SYMBOL + 1u, + LIBCMAP_GENERAL_CATEGORY_SYMBOL_CURRENCY, + LIBCMAP_GENERAL_CATEGORY_SYMBOL_MODIFIER, + LIBCMAP_GENERAL_CATEGORY_SYMBOL_OTHER, + LIBCMAP_GENERAL_CATEGORY_SEPARATOR_SPACE = LIBCMAP_GENERAL_SUPERCATEGORY_SEPARATOR + 1u, + LIBCMAP_GENERAL_CATEGORY_SEPARATOR_LINE, + LIBCMAP_GENERAL_CATEGORY_SEPARATOR_PARAGRAPH, + LIBCMAP_GENERAL_CATEGORY_OTHER_CONTROL = LIBCMAP_GENERAL_SUPERCATEGORY_OTHER + 1u, + LIBCMAP_GENERAL_CATEGORY_OTHER_FORMAT, + LIBCMAP_GENERAL_CATEGORY_OTHER_SURROGATE, + LIBCMAP_GENERAL_CATEGORY_OTHER_PRIVATE_USE, + LIBCMAP_GENERAL_CATEGORY_OTHER_NOT_ASSIGNED +}; + +#define LIBCMAP_GENERAL_SUPERCATEGORY_MASK 0x7F00u + + +enum libcmap_bidirectional_supercategory { + LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_STRONG = 0x0100u, + LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_WEAK = 0x0200u, + LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_NEUTRAL = 0x0300u, + LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_EXPLICIT = 0x0400u +}; + +enum libcmap_bidirectional_category { + LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT = LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_STRONG + 1u, + LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT, + LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_ARABIC, + LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER = LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_WEAK + 1u, + LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER_SEPARATOR, + LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER_TERMINATOR, + LIBCMAP_BIDIRECTIONAL_CATEGORY_ARABIC_NUMBER, + LIBCMAP_BIDIRECTIONAL_CATEGORY_COMMON_SEPARATOR, + LIBCMAP_BIDIRECTIONAL_CATEGORY_NONSPACING_MARK, + LIBCMAP_BIDIRECTIONAL_CATEGORY_BOUNDARY_NEUTRAL, + LIBCMAP_BIDIRECTIONAL_CATEGORY_PARAGRAPH_SEPARATOR = LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_NEUTRAL + 1u, + LIBCMAP_BIDIRECTIONAL_CATEGORY_SEGMENT_SEPARATOR, + LIBCMAP_BIDIRECTIONAL_CATEGORY_WHITESPACE, + LIBCMAP_BIDIRECTIONAL_CATEGORY_OTHER_NEUTRALS, + LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_EMBEDDING = LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_EXPLICIT + 1u, + LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_OVERRIDE, + LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_EMBEDDING, + LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_OVERRIDE, + LIBCMAP_BIDIRECTIONAL_CATEGORY_POP_DIRECTIONAL_FORMAT, + LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_ISOLATE, + LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_ISOLATE, + LIBCMAP_BIDIRECTIONAL_CATEGORY_FIRST_STRONG_ISOLATE, + LIBCMAP_BIDIRECTIONAL_CATEGORY_POP_DIRECTIONAL_ISOLATE +}; + +#define LIBCMAP_BIDIRECTIONAL_SUPERCATEGORY_MASK 0x7F00u + + /** * Contiguous range of Unicode codepoints * @@ -107,6 +189,52 @@ struct libcmap_script { /** + * Information about a specific codepoint + */ +struct libcmap_codepoint_data { + /** + * The name as published in the Unicode Standard code charts + * + * It uniquely identifies the character unless it starts with '<' + */ + const char *name; + + /* TODO documentation is needed */ + enum libcmap_general_category general_category; + enum libcmap_bidirectional_category bidirectional_category; + uint16_t canonical_combining_classes; + uint16_t bidirectional_mirrored; + const char *unicode_1_name; +}; + + +/** + * Contiguous block of codepoints with + * data for each codepoint + */ +struct libcmap_codepoint_segment { + /** + * The range of codepoints the segment covers + */ + struct libcmap_range range; + + /** + * data for each codepoint in the segment, + * + * `.data[codepoint - .range.first]` gives the entry for + * a specific codepoint without [`.range.first, `.range.last`] + */ + const struct libcmap_codepoint_data *data; +}; + + +/** + * The version of the Unicode Standard that the library is + * compiled with data for + */ +extern const char *const libcmap_unicode_version; + +/** * Listing of all Unicode codepoints not assigned any block * * This listing can potentially be empty @@ -163,6 +291,23 @@ extern const struct libcmap_script *const libcmap_script_list; */ extern const size_t libcmap_script_list_size; +/** + * Data about codepoints + * + * There are gaps, hence the list is segmented + * + * The list is sorted in ascending order + * + * @seealso libcmap_codepoint_list_size + * @seealso libcmap_find_codepoint_data + */ +extern const struct libcmap_codepoint_segment *const libcmap_codepoint_list; + +/** + * The number of elements in `libcmap_codepoint_list` + */ +extern const size_t libcmap_codepoint_list_size; + /** * Find a codepoint within `libcmap_no_block` @@ -237,6 +382,23 @@ const struct libcmap_script *libcmap_find_script(uint32_t codepoint, size_t *off /** + * Find data about a specified codepoint + * + * @param codepoint The codepoint + * @return Information from UnicodeData about the codepoint, + * `NULL` if not found + * + * `NULL`-return doesn't necessary mean it is unassigned, + * but rather just that it doesn't appear in UnicodeData, + * which is common for ideographs + * + * @seealso libcmap_codepoint_list + */ +LIBCMAP_PURE_ +const struct libcmap_codepoint_data *libcmap_find_codepoint_data(uint32_t codepoint); + + +/** * Print a string representing a Unicode codepoint range * * @param buf Output buffer to print to, must be sufficiently large; diff --git a/libcmap_codepoint_list.c b/libcmap_codepoint_list.c new file mode 100644 index 0000000..d706441 --- /dev/null +++ b/libcmap_codepoint_list.c @@ -0,0 +1,68 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define GENERAL_CATEGORY_Lu LIBCMAP_GENERAL_CATEGORY_LETTER_UPPERCASE +#define GENERAL_CATEGORY_Ll LIBCMAP_GENERAL_CATEGORY_LETTER_LOWERCASE +#define GENERAL_CATEGORY_Lt LIBCMAP_GENERAL_CATEGORY_LETTER_TITLECASE +#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_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 +#define GENERAL_CATEGORY_Pc LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_CONNECTOR +#define GENERAL_CATEGORY_Pd LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_DASH +#define GENERAL_CATEGORY_Ps LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_OPEN +#define GENERAL_CATEGORY_Pe LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_CLOSE +#define GENERAL_CATEGORY_Pi LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_INITIAL_QUOTE +#define GENERAL_CATEGORY_Pf LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_FINAL_QUOTE +#define GENERAL_CATEGORY_Po LIBCMAP_GENERAL_CATEGORY_PUNCTUATION_OTHER +#define GENERAL_CATEGORY_Sm LIBCMAP_GENERAL_CATEGORY_SYMBOL_MATH +#define GENERAL_CATEGORY_Sc LIBCMAP_GENERAL_CATEGORY_SYMBOL_CURRENCY +#define GENERAL_CATEGORY_Sk LIBCMAP_GENERAL_CATEGORY_SYMBOL_MODIFIER +#define GENERAL_CATEGORY_So LIBCMAP_GENERAL_CATEGORY_SYMBOL_OTHER +#define GENERAL_CATEGORY_Zs LIBCMAP_GENERAL_CATEGORY_SEPARATOR_SPACE +#define GENERAL_CATEGORY_Zl LIBCMAP_GENERAL_CATEGORY_SEPARATOR_LINE +#define GENERAL_CATEGORY_Zp LIBCMAP_GENERAL_CATEGORY_SEPARATOR_PARAGRAPH +#define GENERAL_CATEGORY_Cc LIBCMAP_GENERAL_CATEGORY_OTHER_CONTROL +#define GENERAL_CATEGORY_Cf LIBCMAP_GENERAL_CATEGORY_OTHER_FORMAT +#define GENERAL_CATEGORY_Cs LIBCMAP_GENERAL_CATEGORY_OTHER_SURROGATE +#define GENERAL_CATEGORY_Co LIBCMAP_GENERAL_CATEGORY_OTHER_PRIVATE_USE +/* #define GENERAL_CATEGORY_Cn LIBCMAP_GENERAL_CATEGORY_OTHER_NOT_ASSIGNED */ + +#define BIDIRECTIONAL_CATEGORY_L LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT +#define BIDIRECTIONAL_CATEGORY_R LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT +#define BIDIRECTIONAL_CATEGORY_AL LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_ARABIC +#define BIDIRECTIONAL_CATEGORY_EN LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER +#define BIDIRECTIONAL_CATEGORY_ES LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER_SEPARATOR +#define BIDIRECTIONAL_CATEGORY_ET LIBCMAP_BIDIRECTIONAL_CATEGORY_EUROPEAN_NUMBER_TERMINATOR +#define BIDIRECTIONAL_CATEGORY_AN LIBCMAP_BIDIRECTIONAL_CATEGORY_ARABIC_NUMBER +#define BIDIRECTIONAL_CATEGORY_CS LIBCMAP_BIDIRECTIONAL_CATEGORY_COMMON_SEPARATOR +#define BIDIRECTIONAL_CATEGORY_NSM LIBCMAP_BIDIRECTIONAL_CATEGORY_NONSPACING_MARK +#define BIDIRECTIONAL_CATEGORY_BN LIBCMAP_BIDIRECTIONAL_CATEGORY_BOUNDARY_NEUTRAL +#define BIDIRECTIONAL_CATEGORY_B LIBCMAP_BIDIRECTIONAL_CATEGORY_PARAGRAPH_SEPARATOR +#define BIDIRECTIONAL_CATEGORY_S LIBCMAP_BIDIRECTIONAL_CATEGORY_SEGMENT_SEPARATOR +#define BIDIRECTIONAL_CATEGORY_WS LIBCMAP_BIDIRECTIONAL_CATEGORY_WHITESPACE +#define BIDIRECTIONAL_CATEGORY_ON LIBCMAP_BIDIRECTIONAL_CATEGORY_OTHER_NEUTRALS +#define BIDIRECTIONAL_CATEGORY_LRE LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_EMBEDDING +#define BIDIRECTIONAL_CATEGORY_LRO LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_OVERRIDE +#define BIDIRECTIONAL_CATEGORY_RLE LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_EMBEDDING +#define BIDIRECTIONAL_CATEGORY_RLO LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_OVERRIDE +#define BIDIRECTIONAL_CATEGORY_PDF LIBCMAP_BIDIRECTIONAL_CATEGORY_POP_DIRECTIONAL_FORMAT +#define BIDIRECTIONAL_CATEGORY_LRI LIBCMAP_BIDIRECTIONAL_CATEGORY_LEFT_TO_RIGHT_ISOLATE +#define BIDIRECTIONAL_CATEGORY_RLI LIBCMAP_BIDIRECTIONAL_CATEGORY_RIGHT_TO_LEFT_ISOLATE +#define BIDIRECTIONAL_CATEGORY_FSI LIBCMAP_BIDIRECTIONAL_CATEGORY_FIRST_STRONG_ISOLATE +#define BIDIRECTIONAL_CATEGORY_PDI LIBCMAP_BIDIRECTIONAL_CATEGORY_POP_DIRECTIONAL_ISOLATE + +#define BIDIRECTIONAL_MIRRORED_Y 1u +#define BIDIRECTIONAL_MIRRORED_N 0u + + + +#include "UnicodeData.txt.c" + +const struct libcmap_codepoint_segment *const libcmap_codepoint_list = list; +const size_t libcmap_codepoint_list_size = sizeof(list) / sizeof(*list); diff --git a/libcmap_find_codepoint_data.c b/libcmap_find_codepoint_data.c new file mode 100644 index 0000000..cd2e52f --- /dev/null +++ b/libcmap_find_codepoint_data.c @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const struct libcmap_codepoint_data * +libcmap_find_codepoint_data(uint32_t codepoint) +{ + size_t low = 0u, high = libcmap_codepoint_list_size - 1u; + size_t i; + + while (low <= high) { + i = low + (high - low) / 2u; + if (libcmap_codepoint_list[i].range.last < codepoint) { + low = i + 1u; + } else if (libcmap_codepoint_list[i].range.first > codepoint) { + if (!high) + break; + high = i - 1u; + } else { + return &libcmap_codepoint_list[i].data[codepoint - libcmap_codepoint_list[i].range.first]; + } + } + + return NULL; +} diff --git a/libcmap_unicode_version.c b/libcmap_unicode_version.c new file mode 100644 index 0000000..5184701 --- /dev/null +++ b/libcmap_unicode_version.c @@ -0,0 +1,5 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char *const libcmap_unicode_version = UNICODE_VERSION; diff --git a/parse-common.c b/parse-common.c index 899debb..aeac342 100644 --- a/parse-common.c +++ b/parse-common.c @@ -1,6 +1,8 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <errno.h> +#include <inttypes.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> |
