diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 12:38:58 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 12:38:58 +0300 |
| commit | 22345caf457e8d9a4bdb56b696cc5f3694812276 (patch) | |
| tree | 801bd4f17569fa875e81bc2297a46ecf5176cbc7 | |
| parent | 6ee9eb37d8e616a972fb29b3fbdbc33991aa844f (diff) | |
| parent | 212f1cc9109aa0deb9e5d990bb2dba2b167618fb (diff) | |
Merge branch 'wt/namespace' into api-hardening
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | include/term/unicode/grapheme.h | 12 | ||||
| -rw-r--r-- | include/term/unicode/unicode_data.inc | 14 | ||||
| -rw-r--r-- | include/term/unicode/utf8.h | 72 | ||||
| -rw-r--r-- | include/term/unicode/width.h | 30 | ||||
| -rw-r--r-- | meson.build | 2 | ||||
| -rw-r--r-- | src/core.c | 24 | ||||
| -rw-r--r-- | src/gstore.c | 28 | ||||
| -rw-r--r-- | src/hist.c | 14 | ||||
| -rw-r--r-- | src/input.c | 4 | ||||
| -rw-r--r-- | src/selection.c | 10 | ||||
| -rw-r--r-- | src/snapshot.c | 6 | ||||
| -rw-r--r-- | src/term.c | 2 | ||||
| -rw-r--r-- | src/text.c | 38 | ||||
| -rw-r--r-- | src/text_run.c | 24 | ||||
| -rw-r--r-- | src/text_run.h | 18 | ||||
| -rw-r--r-- | tests/gstore_test.c | 38 | ||||
| -rw-r--r-- | tests/header_test.sh | 75 | ||||
| -rw-r--r-- | tests/hist_test.c | 12 | ||||
| -rw-r--r-- | tests/model.c | 26 | ||||
| -rw-r--r-- | tests/model.h | 2 | ||||
| -rw-r--r-- | tests/model_test.c | 12 | ||||
| -rw-r--r-- | tests/term_test.c | 18 | ||||
| -rw-r--r-- | tests/unicode/unicode_test.c | 68 | ||||
| -rw-r--r-- | tools/generate_unicode.py | 16 |
25 files changed, 310 insertions, 262 deletions
@@ -52,8 +52,11 @@ no flags to get them: `simd.h` states the rules for a new kernel. -- `term.h` is the only header a host includes. It includes - `term_input.h` and `term_types.h`. It compiles as C11 and as C++. +- `term.h` is the only header a host includes. A host writes + `#include <term/term.h>`. The package adds only the include directory, + so `term.h` from another library, such as ncurses, is not shadowed. The + header includes `term_input.h` and `term_types.h`. It compiles as C11 + and as C++. - Every global symbol starts with `term_`. The library builds with hidden symbols, so a shared build exports only the `TERM_API` functions of `term.h`. `term-symbols-test` checks both. diff --git a/include/term/unicode/grapheme.h b/include/term/unicode/grapheme.h index 5573949..0946bb6 100644 --- a/include/term/unicode/grapheme.h +++ b/include/term/unicode/grapheme.h @@ -5,20 +5,20 @@ #include <stddef.h> #include <stdint.h> -#define GRAPHEME_MAX_LEN 20 -#define GRAPHEME_HANDLE_BASE 0x7F000000u +#define TERM_GRAPHEME_MAX_LEN 20 +#define TERM_GRAPHEME_HANDLE_BASE 0x7F000000u -static inline bool grapheme_is_handle(uint32_t c) +static inline bool term_grapheme_is_handle(uint32_t c) { - return c >= GRAPHEME_HANDLE_BASE; + return c >= TERM_GRAPHEME_HANDLE_BASE; } -static inline bool grapheme_regional_indicator(uint32_t cp) +static inline bool term_grapheme_regional_indicator(uint32_t cp) { return cp >= 0x1F1E6 && cp <= 0x1F1FF; } -static inline bool grapheme_emoji_modifier(uint32_t cp) +static inline bool term_grapheme_emoji_modifier(uint32_t cp) { return cp >= 0x1F3FB && cp <= 0x1F3FF; } diff --git a/include/term/unicode/unicode_data.inc b/include/term/unicode/unicode_data.inc index 8053b01..4ab1461 100644 --- a/include/term/unicode/unicode_data.inc +++ b/include/term/unicode/unicode_data.inc @@ -1,8 +1,8 @@ /* Generated from Unicode 18.0.0 data by tools/generate_unicode.py. */ -#define UNICODE_DATA_VERSION "18.0.0" +#define TERM_UNICODE_DATA_VERSION "18.0.0" -static const struct unicode_range zero_width[] = { +static const struct term_unicode_range term_zero_width[] = { {0xAD,0xAD},{0x300,0x36F},{0x483,0x489},{0x591,0x5BD}, {0x5BF,0x5BF},{0x5C1,0x5C2},{0x5C4,0x5C5},{0x5C7,0x5C9}, {0x600,0x605},{0x610,0x61A},{0x61C,0x61C},{0x64B,0x65F}, @@ -101,11 +101,11 @@ static const struct unicode_range zero_width[] = { {0xE0020,0xE007F},{0xE0100,0xE01EF}, }; -static const struct unicode_range nonprintable[] = { +static const struct term_unicode_range term_nonprintable[] = { {0x0,0x1F},{0x7F,0x9F},{0xD800,0xDFFF}, }; -static const struct unicode_range unicode_wide[] = { +static const struct term_unicode_range term_unicode_wide[] = { {0x1100,0x115F},{0x231A,0x231B},{0x2329,0x232A},{0x23E9,0x23EC}, {0x23F0,0x23F0},{0x23F3,0x23F3},{0x25FD,0x25FE},{0x2614,0x2615}, {0x2630,0x2637},{0x2648,0x2653},{0x267F,0x267F},{0x268A,0x268F}, @@ -140,7 +140,7 @@ static const struct unicode_range unicode_wide[] = { {0x20000,0x2FFFD},{0x30000,0x3FFFD}, }; -static const struct unicode_range spacing_mark[] = { +static const struct term_unicode_range term_spacing_mark[] = { {0x903,0x903},{0x93B,0x93B},{0x93E,0x940},{0x949,0x94C}, {0x94E,0x94F},{0x982,0x983},{0x9BE,0x9C0},{0x9C7,0x9C8}, {0x9CB,0x9CC},{0x9D7,0x9D7},{0xA03,0xA03},{0xA3E,0xA40}, @@ -192,7 +192,7 @@ static const struct unicode_range spacing_mark[] = { {0x1D16D,0x1D172},{0x1D250,0x1D252},{0x1D25F,0x1D25F},{0x1D280,0x1D281}, }; -static const struct unicode_range extended_pictographic[] = { +static const struct term_unicode_range term_extended_pictographic[] = { {0xA9,0xA9},{0xAE,0xAE},{0x203C,0x203C},{0x2049,0x2049}, {0x2122,0x2122},{0x2139,0x2139},{0x2194,0x2199},{0x21A9,0x21AA}, {0x231A,0x231B},{0x2328,0x2328},{0x23CF,0x23CF},{0x23E9,0x23F3}, @@ -234,7 +234,7 @@ static const struct unicode_range extended_pictographic[] = { {0x1F947,0x1F9FF},{0x1FA58,0x1FA5F},{0x1FA6E,0x1FAFF},{0x1FC00,0x1FFFD}, }; -static const struct unicode_range emoji_presentation[] = { +static const struct term_unicode_range term_emoji_presentation[] = { {0x231A,0x231B},{0x23E9,0x23EC},{0x23F0,0x23F0},{0x23F3,0x23F3}, {0x25FD,0x25FE},{0x2614,0x2615},{0x2648,0x2653},{0x267F,0x267F}, {0x2693,0x2693},{0x26A1,0x26A1},{0x26AA,0x26AB},{0x26BD,0x26BE}, diff --git a/include/term/unicode/utf8.h b/include/term/unicode/utf8.h index 1c3cc3f..ad44465 100644 --- a/include/term/unicode/utf8.h +++ b/include/term/unicode/utf8.h @@ -1,19 +1,19 @@ -#ifndef UTF_8_H -#define UTF_8_H +#ifndef TERM_UNICODE_UTF8_H +#define TERM_UNICODE_UTF8_H #include <stdint.h> #include <stddef.h> #include <stdlib.h> #include <string.h> -#define UTF8_ACCEPT 0 -#define UTF8_REJECT 1 +#define TERM_UTF8_ACCEPT 0 +#define TERM_UTF8_REJECT 1 -#define UTF8_3BYTE_MIN 0x800u -#define UTF8_SURROGATE_LO 0xd800u -#define UTF8_SURROGATE_HI 0xdfffu +#define TERM_UTF8_3BYTE_MIN 0x800u +#define TERM_UTF8_SURROGATE_LO 0xd800u +#define TERM_UTF8_SURROGATE_HI 0xdfffu -static const uint8_t utf8d[] = { +static const uint8_t term_utf8d[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -30,19 +30,19 @@ static const uint8_t utf8d[] = { 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, }; -static inline uint32_t utf8_decode(uint32_t *state, uint32_t *codep, uint32_t byte) { +static inline uint32_t term_utf8_decode(uint32_t *state, uint32_t *codep, uint32_t byte) { byte &= 0xff; - uint32_t type = utf8d[byte]; + uint32_t type = term_utf8d[byte]; - *codep = (*state != UTF8_ACCEPT) ? + *codep = (*state != TERM_UTF8_ACCEPT) ? (byte & 0x3fu) | (*codep << 6) : (0xff >> type) & (byte); - *state = utf8d[256 + *state*16 + type]; + *state = term_utf8d[256 + *state*16 + type]; return *state; } -static const uint8_t utf8_acc_state[256] = { +static const uint8_t term_utf8_acc_state[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -60,7 +60,7 @@ static const uint8_t utf8_acc_state[256] = { 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; -static const uint8_t utf8_acc_codep[256] = { +static const uint8_t term_utf8_acc_codep[256] = { 0, 1, 2, 3, 4, 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, 40, 41, 42, 43, 44, 45, 46, 47, @@ -86,7 +86,7 @@ static const uint8_t utf8_acc_codep[256] = { * ends an unfinished sequence the same way. An unfinished sequence at the * end of buf gives *cp = 0 and keeps the state. */ -static inline int utf8_decode_ground(uint32_t *state, uint32_t *codep, +static inline int term_utf8_decode_ground(uint32_t *state, uint32_t *codep, const char *buf, size_t len, uint32_t *cp) { uint32_t st = *state; uint32_t cpv = *codep; @@ -97,25 +97,25 @@ static inline int utf8_decode_ground(uint32_t *state, uint32_t *codep, do { unsigned char c = (unsigned char)buf[n]; if (c < 0x20) { - if (st != UTF8_ACCEPT) *cp = 0xFFFD; - st = UTF8_ACCEPT; + if (st != TERM_UTF8_ACCEPT) *cp = 0xFFFD; + st = TERM_UTF8_ACCEPT; break; } uint32_t before = st; n++; - if (st == UTF8_ACCEPT) { - cpv = utf8_acc_codep[c]; - st = utf8_acc_state[c]; + if (st == TERM_UTF8_ACCEPT) { + cpv = term_utf8_acc_codep[c]; + st = term_utf8_acc_state[c]; } else { - uint32_t type = utf8d[c]; + uint32_t type = term_utf8d[c]; cpv = (c & 0x3fu) | (cpv << 6); - st = utf8d[256 + st*16 + type]; + st = term_utf8d[256 + st*16 + type]; } - if (st == UTF8_ACCEPT) { *cp = cpv; break; } - if (st == UTF8_REJECT) { - st = UTF8_ACCEPT; + if (st == TERM_UTF8_ACCEPT) { *cp = cpv; break; } + if (st == TERM_UTF8_REJECT) { + st = TERM_UTF8_ACCEPT; *cp = 0xFFFD; - if (before != UTF8_ACCEPT) n--; + if (before != TERM_UTF8_ACCEPT) n--; break; } } while ((size_t)n < len); @@ -125,7 +125,7 @@ static inline int utf8_decode_ground(uint32_t *state, uint32_t *codep, } static inline int -utf8_decode_one(const char *buf, size_t len, uint32_t *codep) +term_utf8_decode_one(const char *buf, size_t len, uint32_t *codep) { const unsigned char *s = (const unsigned char *)buf; unsigned c0, c1, c2, c3; @@ -159,8 +159,8 @@ utf8_decode_one(const char *buf, size_t len, uint32_t *codep) if ((c1 & 0xc0) != 0x80 || (c2 & 0xc0) != 0x80) return 0; cp = ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f); - if (cp < UTF8_3BYTE_MIN || - (cp >= UTF8_SURROGATE_LO && cp <= UTF8_SURROGATE_HI)) + if (cp < TERM_UTF8_3BYTE_MIN || + (cp >= TERM_UTF8_SURROGATE_LO && cp <= TERM_UTF8_SURROGATE_HI)) return 0; *codep = cp; return 3; @@ -183,14 +183,14 @@ utf8_decode_one(const char *buf, size_t len, uint32_t *codep) } static inline void -utf8_sanitize(char *dst, size_t cap, const char *src) +term_utf8_sanitize(char *dst, size_t cap, const char *src) { if (!cap) return; size_t i = 0, len = strlen(src), off = 0; while (off < len && i + 1 < cap) { uint32_t cp; - int n = utf8_decode_one(src + off, len - off, &cp); + int n = term_utf8_decode_one(src + off, len - off, &cp); if (n <= 0 || i + (size_t)n >= cap) { off++; continue; @@ -204,17 +204,17 @@ utf8_sanitize(char *dst, size_t cap, const char *src) /* A sanitized copy of src. Sanitizing only drops bytes, so the copy is * never longer than src. */ -static inline char *utf8_sanitize_dup(const char *src) +static inline char *term_utf8_sanitize_dup(const char *src) { size_t cap = strlen(src) + 1; - char *dst = malloc(cap); + char *dst = (char *)malloc(cap); if (dst) - utf8_sanitize(dst, cap, src); + term_utf8_sanitize(dst, cap, src); return dst; } -#define UTF8_MAX_BYTES 4 -static inline int utf8_encode(uint32_t cp, char *out) +#define TERM_UTF8_MAX_BYTES 4 +static inline int term_utf8_encode(uint32_t cp, char *out) { if (cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff)) cp = 0xfffd; diff --git a/include/term/unicode/width.h b/include/term/unicode/width.h index a7dfe66..a85ec77 100644 --- a/include/term/unicode/width.h +++ b/include/term/unicode/width.h @@ -5,15 +5,15 @@ #include <stddef.h> #include <stdint.h> -struct unicode_range { uint32_t lo, hi; }; +struct term_unicode_range { uint32_t lo, hi; }; #include "unicode_data.inc" -static inline bool in_ranges(const struct unicode_range *ranges, size_t count, uint32_t cp) +static inline bool term_in_ranges(const struct term_unicode_range *ranges, size_t count, uint32_t cp) { if (count == 0 || cp < ranges[0].lo || cp > ranges[count - 1].hi) return false; - const struct unicode_range *base = ranges; + const struct term_unicode_range *base = ranges; size_t n = count; while (n > 1) { size_t half = n / 2; @@ -23,34 +23,34 @@ static inline bool in_ranges(const struct unicode_range *ranges, size_t count, u return cp <= base->hi; } -#define IN_TABLE(table, cp) in_ranges(table, sizeof(table) / sizeof(table[0]), cp) +#define TERM_IN_TABLE(table, cp) term_in_ranges(table, sizeof(table) / sizeof(table[0]), cp) -static inline int unicode_width(uint32_t cp) +static inline int term_unicode_width(uint32_t cp) { - if (cp > 0x10FFFF || IN_TABLE(nonprintable, cp)) + if (cp > 0x10FFFF || TERM_IN_TABLE(term_nonprintable, cp)) return -1; - if (IN_TABLE(zero_width, cp)) + if (TERM_IN_TABLE(term_zero_width, cp)) return 0; - return IN_TABLE(unicode_wide, cp) ? 2 : 1; + return TERM_IN_TABLE(term_unicode_wide, cp) ? 2 : 1; } -static inline bool unicode_extended_pictographic(uint32_t cp) +static inline bool term_unicode_extended_pictographic(uint32_t cp) { - return IN_TABLE(extended_pictographic, cp); + return TERM_IN_TABLE(term_extended_pictographic, cp); } -static inline bool unicode_emoji_presentation(uint32_t cp) +static inline bool term_unicode_emoji_presentation(uint32_t cp) { - return IN_TABLE(emoji_presentation, cp); + return TERM_IN_TABLE(term_emoji_presentation, cp); } -static inline bool unicode_spacing_mark(uint32_t cp) +static inline bool term_unicode_spacing_mark(uint32_t cp) { if (cp < 0x903 || ((cp - 0xABEDu) < (0x11000u - 0xABEDu)) || cp > 0x1D281) return false; - return IN_TABLE(spacing_mark, cp); + return TERM_IN_TABLE(term_spacing_mark, cp); } -#undef IN_TABLE +#undef TERM_IN_TABLE #endif diff --git a/meson.build b/meson.build index fa450f9..e25bf13 100644 --- a/meson.build +++ b/meson.build @@ -72,7 +72,7 @@ pkg.generate( name: 'term', description: 'Headless terminal emulator core library', version: meson.project_version(), - subdirs: ['.', 'term'], + subdirs: ['.'], ) if get_option('tests') @@ -16,13 +16,13 @@ static uint16_t cluster_presentation(const uint32_t *cps, int len) { if (len <= 1) return 0; - bool pictographic = unicode_extended_pictographic(cps[0]); + bool pictographic = term_unicode_extended_pictographic(cps[0]); if (len == 2) { uint32_t c1 = cps[1]; if (c1 == 0xFE0F) return CELL_EMOJI; if (c1 == 0xFE0E) return CELL_TEXT; - if (c1 == 0x20E3 || grapheme_regional_indicator(c1) || - (pictographic && (c1 == 0x200D || grapheme_emoji_modifier(c1) || + if (c1 == 0x20E3 || term_grapheme_regional_indicator(c1) || + (pictographic && (c1 == 0x200D || term_grapheme_emoji_modifier(c1) || (c1 >= 0xE0020 && c1 <= 0xE007F)))) return CELL_EMOJI; return 0; @@ -33,8 +33,8 @@ static uint16_t cluster_presentation(const uint32_t *cps, int len) return CELL_EMOJI; if (cps[i] == 0xFE0E) return CELL_TEXT; - if (cps[i] == 0x20E3 || grapheme_regional_indicator(cps[i]) || - (pictographic && (cps[i] == 0x200D || grapheme_emoji_modifier(cps[i]) || + if (cps[i] == 0x20E3 || term_grapheme_regional_indicator(cps[i]) || + (pictographic && (cps[i] == 0x200D || term_grapheme_emoji_modifier(cps[i]) || (cps[i] >= 0xE0020 && cps[i] <= 0xE007F)))) emoji = true; } @@ -44,9 +44,9 @@ static uint16_t cluster_presentation(const uint32_t *cps, int len) void term_sc_print_glyph(struct term *t, uint32_t cp, int width, uint16_t flags) { uint32_t base = cp; - if (TERM_EXPECT(grapheme_is_handle(cp), 0)) { - uint32_t cps[GRAPHEME_MAX_LEN]; - int len = term_gstore_expand(t->gstore, cp, cps, GRAPHEME_MAX_LEN); + if (TERM_EXPECT(term_grapheme_is_handle(cp), 0)) { + uint32_t cps[TERM_GRAPHEME_MAX_LEN]; + int len = term_gstore_expand(t->gstore, cp, cps, TERM_GRAPHEME_MAX_LEN); base = cps[0]; flags = (flags & ~(CELL_EMOJI | CELL_TEXT)) | cluster_presentation(cps, len); } @@ -179,13 +179,13 @@ bool term_sc_extend_cluster(struct term *t, uint32_t cp, int klass) return false; struct cell *prev = last_written_cell(t); - uint32_t cps[GRAPHEME_MAX_LEN]; - int len = prev && prev->c > ' ' ? term_gstore_expand(t->gstore, prev->c, cps, GRAPHEME_MAX_LEN) : 0; + uint32_t cps[TERM_GRAPHEME_MAX_LEN]; + int len = prev && prev->c > ' ' ? term_gstore_expand(t->gstore, prev->c, cps, TERM_GRAPHEME_MAX_LEN) : 0; if (!len) return joins_cluster(cp, klass); if (!cluster_joins(cps, len, cp, klass)) return false; - if (len >= GRAPHEME_MAX_LEN) + if (len >= TERM_GRAPHEME_MAX_LEN) return true; cps[len++] = cp; @@ -517,7 +517,7 @@ static inline bool next_byte_wraps(const char *buf, size_t len, size_t pos, uint { if (pos >= len) return false; uint32_t cp; - if (!utf8_decode_one(buf + pos, len - pos, &cp)) return false; + if (!term_utf8_decode_one(buf + pos, len - pos, &cp)) return false; int w = term_text_class(cp); return w > 0 && !can_extend_cluster(last, cp, w); } diff --git a/src/gstore.c b/src/gstore.c index d2bc57f..813ea7d 100644 --- a/src/gstore.c +++ b/src/gstore.c @@ -72,11 +72,11 @@ int term_gstore_expand(const struct gstore *g, uint32_t handle, uint32_t *cps, i { if (cap <= 0) return 0; - if (!g || !grapheme_is_handle(handle)) { + if (!g || !term_grapheme_is_handle(handle)) { cps[0] = handle; return 1; } - uint32_t idx = handle - GRAPHEME_HANDLE_BASE; + uint32_t idx = handle - TERM_GRAPHEME_HANDLE_BASE; if (idx >= g->entries_count || !g->entries[idx].allocated) { cps[0] = 0xFFFD; return 1; @@ -124,8 +124,8 @@ static bool grow_slots(struct gstore *g) struct gentry *e = &g->entries[i]; if (!e->allocated) continue; - uint32_t cps_buf[GRAPHEME_MAX_LEN]; - int n = term_gstore_expand(g, GRAPHEME_HANDLE_BASE + i, cps_buf, GRAPHEME_MAX_LEN); + uint32_t cps_buf[TERM_GRAPHEME_MAX_LEN]; + int n = term_gstore_expand(g, TERM_GRAPHEME_HANDLE_BASE + i, cps_buf, TERM_GRAPHEME_MAX_LEN); uint64_t h = hash_cps(cps_buf, n); uint32_t h32 = (uint32_t)h ? (uint32_t)h : 1; gstore_insert_slot(g, h32, i); @@ -147,7 +147,7 @@ static uint32_t gstore_find(const struct gstore *g, const uint32_t *cps, int n, uint32_t e_idx = slot->entry_idx - 1; const struct gentry *e = &g->entries[e_idx]; if (e->allocated && gentry_matches(g, e, cps, n)) - return GRAPHEME_HANDLE_BASE + e_idx; + return TERM_GRAPHEME_HANDLE_BASE + e_idx; } idx = (idx + 1) & mask; } @@ -193,9 +193,9 @@ void term_gstore_unpin(struct gstore *g) void term_gstore_mark(struct gstore *g, uint32_t handle) { - if (!g || !grapheme_is_handle(handle)) + if (!g || !term_grapheme_is_handle(handle)) return; - uint32_t idx = handle - GRAPHEME_HANDLE_BASE; + uint32_t idx = handle - TERM_GRAPHEME_HANDLE_BASE; if (idx < g->entries_count && g->entries[idx].allocated) g->entries[idx].mark = true; } @@ -204,7 +204,7 @@ static void sweep_mark_row(struct gstore *g, const struct cell *cells, int len) { for (int x = 0; x < len; x++) { uint32_t c = cells[x].c; - if (grapheme_is_handle(c)) + if (term_grapheme_is_handle(c)) term_gstore_mark(g, c); } } @@ -215,7 +215,7 @@ void term_gstore_sweep(struct gstore *g, struct term *t) return; if (t) { - if (grapheme_is_handle(t->last_char)) + if (term_grapheme_is_handle(t->last_char)) term_gstore_mark(g, t->last_char); struct screen *s = &t->scr; @@ -266,8 +266,8 @@ void term_gstore_sweep(struct gstore *g, struct term *t) live++; e->mark = false; if (g->slots) { - uint32_t cps_buf[GRAPHEME_MAX_LEN]; - int n = term_gstore_expand(g, GRAPHEME_HANDLE_BASE + i, cps_buf, GRAPHEME_MAX_LEN); + uint32_t cps_buf[TERM_GRAPHEME_MAX_LEN]; + int n = term_gstore_expand(g, TERM_GRAPHEME_HANDLE_BASE + i, cps_buf, TERM_GRAPHEME_MAX_LEN); uint64_t h = hash_cps(cps_buf, n); uint32_t h32 = (uint32_t)h ? (uint32_t)h : 1; gstore_insert_slot(g, h32, i); @@ -300,8 +300,8 @@ uint32_t term_gstore_intern(struct gstore *g, const uint32_t *cps, int n) return 0; if (n == 1) return cps[0]; - if (n > GRAPHEME_MAX_LEN) - n = GRAPHEME_MAX_LEN; + if (n > TERM_GRAPHEME_MAX_LEN) + n = TERM_GRAPHEME_MAX_LEN; uint64_t h = hash_cps(cps, n); uint32_t h32 = (uint32_t)h ? (uint32_t)h : 1; @@ -375,5 +375,5 @@ uint32_t term_gstore_intern(struct gstore *g, const uint32_t *cps, int n) gstore_insert_slot(g, h32, entry_idx); g->live_count++; - return GRAPHEME_HANDLE_BASE + entry_idx; + return TERM_GRAPHEME_HANDLE_BASE + entry_idx; } @@ -42,7 +42,7 @@ #define ROWS_UNKNOWN 255 /* Bytes one cell can need, except a cluster. */ #define CELL_BYTES 5 -#define CLUSTER_BYTES (2 + GRAPHEME_MAX_LEN * 4) +#define CLUSTER_BYTES (2 + TERM_GRAPHEME_MAX_LEN * 4) /* ---- Parts and pages ---- */ @@ -1039,8 +1039,8 @@ static int uniform_utf8_prefix(const struct cell *cells, int len, uint8_t *dst, static TERM_NOINLINE size_t encode_cluster(uint8_t *dst, const struct gstore *g, uint32_t handle, uint16_t f) { - uint32_t cps[GRAPHEME_MAX_LEN]; - int n = term_gstore_expand(g, handle, cps, GRAPHEME_MAX_LEN); + uint32_t cps[TERM_GRAPHEME_MAX_LEN]; + int n = term_gstore_expand(g, handle, cps, TERM_GRAPHEME_MAX_LEN); size_t b = 0; dst[b++] = PREFIX_CLUSTER; dst[b++] = (uint8_t)((n & 0x1f) | ((f & CELL_WIDE) ? 0x80 : 0) | @@ -1053,7 +1053,7 @@ static TERM_NOINLINE size_t encode_cluster(uint8_t *dst, const struct gstore *g, static size_t encode_shaped(uint8_t *dst, uint32_t cp, uint16_t f, const struct gstore *g, uint8_t *flags) { - if (grapheme_is_handle(cp)) { + if (term_grapheme_is_handle(cp)) { *flags |= HLINE_HAS_CLUSTER | ((f & CELL_WIDE) ? HLINE_HAS_WIDE : 0); return encode_cluster(dst, g, cp, f); } @@ -1155,7 +1155,7 @@ static int encode_cells(struct hist_runs *r, const struct cell *cells, int n, ui continue; uint32_t cp = c->c; bool simple = !(f & (CELL_WIDE | CELL_EMOJI | CELL_TEXT)) && cp - 0x20u < 0x60u; - if (!simple && grapheme_is_handle(cp) && + if (!simple && term_grapheme_is_handle(cp) && bytes + CLUSTER_BYTES + (size_t)(n - i) * CELL_BYTES > cap) break; uint32_t sl = (uint32_t)(f & STYLE_FLAGS) | ((uint32_t)c->pad << 16); @@ -2516,12 +2516,12 @@ static const uint8_t *text_cell(const uint8_t *s, const uint8_t *end, struct gst } uint8_t k = s[1]; s += 2; - uint32_t cps[GRAPHEME_MAX_LEN]; + uint32_t cps[TERM_GRAPHEME_MAX_LEN]; int n = 0; for (int i = 0; i < (k & 0x1f) && s < end; i++) { uint32_t c; s += get_utf8(s, end, &c); - if (n < GRAPHEME_MAX_LEN) + if (n < TERM_GRAPHEME_MAX_LEN) cps[n++] = c; } *cp = n == 0 ? ' ' : (g && n > 1) ? term_gstore_intern(g, cps, n) : cps[0]; diff --git a/src/input.c b/src/input.c index 9fee179..2f0cd5c 100644 --- a/src/input.c +++ b/src/input.c @@ -53,7 +53,7 @@ static inline void sb_u32(struct seqbuf *sb, uint32_t val) static inline void sb_utf8(struct seqbuf *sb, uint32_t cp) { char tmp[8]; - size_t n = (size_t)utf8_encode(cp, tmp); + size_t n = (size_t)term_utf8_encode(cp, tmp); sb_bytes(sb, tmp, n); } @@ -695,7 +695,7 @@ struct term_input_result term_input_encode_paste(const struct term_modes *m, continue; } uint32_t cp; - int n = utf8_decode_one(text + i, len - i, &cp); + int n = term_utf8_decode_one(text + i, len - i, &cp); if (!n) { i++; continue; } if (cp >= 0xa0 && !is_direction_format(cp)) { sb_bytes(&sb, text + i, (size_t)n); diff --git a/src/selection.c b/src/selection.c index 3ac2ee3..40fb1f1 100644 --- a/src/selection.c +++ b/src/selection.c @@ -742,17 +742,17 @@ static char *range_text_inner(const struct term *t, uint32_t cp = cells[c].c; if (cells[c].flags & (CELL_TRAIL | CELL_WRAP_PAD)) continue; - /* One cell expands to GRAPHEME_MAX_LEN code points of up + /* One cell expands to TERM_GRAPHEME_MAX_LEN code points of up * to 4 bytes each. Leave room for all of them. */ - if (!text_reserve(&text, &cap, n + (size_t)GRAPHEME_MAX_LEN * 4 + 1)) + if (!text_reserve(&text, &cap, n + (size_t)TERM_GRAPHEME_MAX_LEN * 4 + 1)) break; if (cp > 0 && cp < 128) { text[n++] = (char)cp; } else { - uint32_t cps[GRAPHEME_MAX_LEN]; - int len = term_gstore_expand(t->gstore, cp ? cp : ' ', cps, GRAPHEME_MAX_LEN); + uint32_t cps[TERM_GRAPHEME_MAX_LEN]; + int len = term_gstore_expand(t->gstore, cp ? cp : ' ', cps, TERM_GRAPHEME_MAX_LEN); for (int k = 0; k < len; k++) - n += (size_t)utf8_encode(cps[k], text + n); + n += (size_t)term_utf8_encode(cps[k], text + n); } } if (text && !is_last && !wrapped && text_reserve(&text, &cap, n + 2)) diff --git a/src/snapshot.c b/src/snapshot.c index c578f18..0bbf545 100644 --- a/src/snapshot.c +++ b/src/snapshot.c @@ -90,8 +90,8 @@ static void invalidate(struct term_snapshot *s) static uint32_t arena_add(struct term_snapshot *s, const struct gstore *g, uint32_t handle, bool *ok) { - uint32_t cps[GRAPHEME_MAX_LEN]; - int n = term_gstore_expand(g, handle, cps, GRAPHEME_MAX_LEN); + uint32_t cps[TERM_GRAPHEME_MAX_LEN]; + int n = term_gstore_expand(g, handle, cps, TERM_GRAPHEME_MAX_LEN); if (n <= 0) return ' '; if (s->arena_len + (uint32_t)n + 1 > s->arena_cap) { @@ -124,7 +124,7 @@ static uint32_t convert_row(struct term_snapshot *s, const struct gstore *g, uint32_t text = c->c; if (TERM_EXPECT(text < 0x20, 0)) text = text ? ' ' : 0; - else if (TERM_EXPECT(grapheme_is_handle(text), 0)) { + else if (TERM_EXPECT(term_grapheme_is_handle(text), 0)) { text = arena_add(s, g, text, ok); if (!*ok) return 0; @@ -5,7 +5,7 @@ _Thread_local char term_thread_anchor; const char *term_unicode_version(void) { - return UNICODE_DATA_VERSION; + return TERM_UNICODE_DATA_VERSION; } unsigned term_version(void) @@ -50,15 +50,15 @@ static inline void emit_decoded(struct term *t, uint32_t cp, uint16_t flags) * sequence prints U+FFFD (Unicode 3.9, maximal subparts). */ void term_text_utf8_interrupt(struct term *t) { - if (TERM_EXPECT(t->utf8_state == UTF8_ACCEPT, 1)) + if (TERM_EXPECT(t->utf8_state == TERM_UTF8_ACCEPT, 1)) return; - t->utf8_state = UTF8_ACCEPT; + t->utf8_state = TERM_UTF8_ACCEPT; emit_decoded(t, 0xFFFD, term_current_flags(t)); } void term_text_ground(struct term *t, unsigned char ch) { - if (ch >= 0x20 && ch < 0x7f && t->utf8_state == UTF8_ACCEPT) { + if (ch >= 0x20 && ch < 0x7f && t->utf8_state == TERM_UTF8_ACCEPT) { emit_codepoint(t, ch, 1, term_current_flags(t)); return; } @@ -92,14 +92,14 @@ void term_text_ground(struct term *t, unsigned char ch) t->graphics = t->charsets[0] == '0'; } else if (ch >= 0x20 && ch != 0x7f) { uint32_t before = t->utf8_state; - uint32_t st = utf8_decode(&t->utf8_state, &t->utf8_codep, ch); - if (st == UTF8_ACCEPT) { + uint32_t st = term_utf8_decode(&t->utf8_state, &t->utf8_codep, ch); + if (st == TERM_UTF8_ACCEPT) { emit_decoded(t, t->utf8_codep, term_current_flags(t)); - } else if (st == UTF8_REJECT) { - t->utf8_state = UTF8_ACCEPT; + } else if (st == TERM_UTF8_REJECT) { + t->utf8_state = TERM_UTF8_ACCEPT; emit_decoded(t, 0xFFFD, term_current_flags(t)); /* The byte that ended an unfinished sequence starts anew. */ - if (before != UTF8_ACCEPT) + if (before != TERM_UTF8_ACCEPT) term_text_ground(t, ch); } } @@ -109,7 +109,7 @@ static inline bool can_stream_bottom(const struct term *t) { return t->state == ST_GROUND && !t->graphics && !t->insert_mode && t->autowrap && !t->lr_margin_mode && - t->utf8_state == UTF8_ACCEPT && !t->inverse && + t->utf8_state == TERM_UTF8_ACCEPT && !t->inverse && t->scroll_top == 0 && t->scroll_bottom == t->rows - 1 && t->cursor_y == t->rows - 1 && !t->alternate && t->sb_capacity > 0 && @@ -123,14 +123,14 @@ static inline bool try_text_run(struct term *t, const char *buf, size_t len, if (t->pending_wrap || i + 4 > len || ((unsigned char)buf[i] >= 0x80 && ((unsigned char)buf[i] < 0xc2 || (unsigned char)buf[i] > 0xf4)) || - t->last_char == 0x200D || grapheme_is_handle(t->last_char)) + t->last_char == 0x200D || term_grapheme_is_handle(t->last_char)) return false; if (t->cursor_x != 0 && t->cursor_x != term_row(t, t->cursor_y)->len) return false; if ((unsigned char)buf[i] >= 0x80) { uint32_t cp; - int bytes = utf8_decode_one(buf + i, len - i, &cp); + int bytes = term_utf8_decode_one(buf + i, len - i, &cp); if (!bytes || term_text_class(cp) <= 0) return false; } @@ -181,7 +181,7 @@ static inline bool try_text_run(struct term *t, const char *buf, size_t len, newline = true; } if (!newline || i + 4 > len || t->pending_wrap || - t->last_char == 0x200D || grapheme_is_handle(t->last_char) || + t->last_char == 0x200D || term_grapheme_is_handle(t->last_char) || (t->cursor_x != 0 && t->cursor_x != term_row(t, t->cursor_y)->len)) break; @@ -213,7 +213,7 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne unsigned char ch = (unsigned char)buf[i]; if (TERM_EXPECT(ch >= 0x20 && ch < 0x7f && !t->insert_mode && !t->lr_margin_mode && t->state == ST_GROUND && !t->graphics && - t->utf8_state == UTF8_ACCEPT, 1)) { + t->utf8_state == TERM_UTF8_ACCEPT, 1)) { int avail = t->pending_wrap ? t->cols : t->cols - t->cursor_x; int rem = (int)(len - i); if (rem > avail) rem = avail; @@ -240,7 +240,7 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne (unsigned char)buf[i + 1] <= 0xf4 && (i + 2 == len || ((unsigned char)buf[i + 2] & 0xc0) == 0x80)) { uint32_t next_cp; - if (utf8_decode_one(buf + i + 1, len - i - 1, &next_cp) && + if (term_utf8_decode_one(buf + i + 1, len - i - 1, &next_cp) && term_text_class(next_cp) > 0 && try_text_run(t, buf, len, &i)) continue; @@ -250,7 +250,7 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne } if (i + (size_t)run < len && (unsigned char)buf[i + run] >= 0x80) { uint32_t next_cp; - if (utf8_decode_one(buf + i + run, len - i - (size_t)run, &next_cp) && + if (term_utf8_decode_one(buf + i + run, len - i - (size_t)run, &next_cp) && term_text_class(next_cp) > 0 && try_text_run(t, buf, len, &i)) continue; @@ -275,21 +275,21 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne if (TERM_EXPECT(ch >= 0x80, 1)) { if (TERM_EXPECT(t->state == ST_GROUND && - t->utf8_state == UTF8_ACCEPT && !t->graphics, 1)) { + t->utf8_state == TERM_UTF8_ACCEPT && !t->graphics, 1)) { if (ch >= 0xc2 && ch <= 0xf4 && (i + 1 == len || ((unsigned char)buf[i + 1] & 0xc0) == 0x80)) { if (!t->insert_mode && !t->lr_margin_mode && try_text_run(t, buf, len, &i)) continue; } else { - if (TERM_EXPECT(t->last_char != 0x200D && !grapheme_is_handle(t->last_char), 1)) + if (TERM_EXPECT(t->last_char != 0x200D && !term_grapheme_is_handle(t->last_char), 1)) sc_print_cell(t, 0xFFFD, 1, cur_flags); else emit_decoded(t, 0xFFFD, cur_flags); continue; } uint32_t cp; - int cp_len = utf8_decode_ground(&t->utf8_state, &t->utf8_codep, buf + i, len - i, &cp); + int cp_len = term_utf8_decode_ground(&t->utf8_state, &t->utf8_codep, buf + i, len - i, &cp); if (cp) emit_decoded(t, cp, cur_flags); i += (size_t)(cp_len - 1); @@ -329,7 +329,7 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne } continue; case 0x1b: - if (t->utf8_state == UTF8_ACCEPT && i + 1 < len && + if (t->utf8_state == TERM_UTF8_ACCEPT && i + 1 < len && buf[i + 1] == '[' && !t->insert_mode && !t->lr_margin_mode && !t->graphics) { int fast = term_try_fast_csi(t, buf + i + 2, len - i - 2); diff --git a/src/text_run.c b/src/text_run.c index 028b160..c48b73e 100644 --- a/src/text_run.c +++ b/src/text_run.c @@ -19,7 +19,7 @@ static int width_run_count; void term_text_tables_init(void) { for (uint32_t cp = 0; cp < 65536; cp++) { - int w = unicode_width(cp); + int w = term_unicode_width(cp); unicode_fast_class[cp] = (w == 1 || w == 2) && !cluster_contextual(cp) ? (uint8_t)w : 0; unicode_width_bmp[cp] = (int8_t)w; @@ -92,7 +92,7 @@ static TERM_MAYBE_UNUSED bool width_cache_extend(struct width_cache *wc, const u int term_text_class(uint32_t cp) { assert(term_tables_ready()); - return TERM_EXPECT(cp < 65536, 1) ? (int)unicode_width_bmp[cp] : unicode_width(cp); + return TERM_EXPECT(cp < 65536, 1) ? (int)unicode_width_bmp[cp] : term_unicode_width(cp); } #if defined(TERM_KERNEL_AVX512) @@ -189,10 +189,10 @@ static inline bool classify_3byte_block(__m512i in, struct width_ranges *ranges, _mm512_loadu_si512(utf8_3byte_bits)) & UTF8_3BYTE_SPAN, 0)) return false; *cps = utf8_3byte_decode(_mm512_permutexvar_epi8(_mm512_loadu_si512(utf8_3byte_shuffle), in)); - if (_mm512_cmplt_epu32_mask(*cps, _mm512_set1_epi32((int)UTF8_3BYTE_MIN)) || + if (_mm512_cmplt_epu32_mask(*cps, _mm512_set1_epi32((int)TERM_UTF8_3BYTE_MIN)) || _mm512_cmple_epu32_mask( - _mm512_sub_epi32(*cps, _mm512_set1_epi32((int)UTF8_SURROGATE_LO)), - _mm512_set1_epi32((int)(UTF8_SURROGATE_HI - UTF8_SURROGATE_LO)))) + _mm512_sub_epi32(*cps, _mm512_set1_epi32((int)TERM_UTF8_SURROGATE_LO)), + _mm512_set1_epi32((int)(TERM_UTF8_SURROGATE_HI - TERM_UTF8_SURROGATE_LO)))) return false; __mmask16 covered = width_ranges_cover(ranges, *cps); if (TERM_EXPECT(covered != 0xFFFF || wc->klass == 0, 0)) { @@ -289,7 +289,7 @@ text_3byte_blocks(uint8_t * restrict dst, const char * restrict buf, int len, in struct text_run_bytes term_text_run_bytes(uint8_t *restrict dst, const char *restrict buf, int len, int max_cols, uint32_t last, struct width_cache *restrict wc) { - if (TERM_EXPECT(last == 0x200D || grapheme_is_handle(last), 0)) + if (TERM_EXPECT(last == 0x200D || term_grapheme_is_handle(last), 0)) return (struct text_run_bytes){ .last = last, .narrow = true }; /* Unlike term_text_run(), this fills up to the edge and up to the end of * buf: the cells path writes those characters one by one with the same @@ -335,7 +335,7 @@ struct text_run_bytes term_text_run_bytes(uint8_t *restrict dst, const char *res } #endif uint32_t cp; - int bytes = utf8_decode_one(buf + i, (size_t)(len - i), &cp); + int bytes = term_utf8_decode_one(buf + i, (size_t)(len - i), &cp); if (!bytes) break; int w = bytes < 4 ? unicode_fast_class[cp] : term_text_class(cp); @@ -493,9 +493,9 @@ static inline int decode_3byte_quads(uint64_t **dst_io, const char *buf, int len _mm_and_si128(_mm_srli_epi32(packed, 2), _mm_set1_epi32(0x0FC0))), _mm_and_si128(_mm_srli_epi32(packed, 4), _mm_set1_epi32(0xF000))); __m128i bad = _mm_or_si128( - _mm_cmplt_epi32(cps, _mm_set1_epi32((int)UTF8_3BYTE_MIN)), + _mm_cmplt_epi32(cps, _mm_set1_epi32((int)TERM_UTF8_3BYTE_MIN)), _mm_cmpeq_epi32(_mm_and_si128(cps, _mm_set1_epi32(0xF800)), - _mm_set1_epi32((int)UTF8_SURROGATE_LO))); + _mm_set1_epi32((int)TERM_UTF8_SURROGATE_LO))); if (_mm_movemask_epi8(bad)) break; alignas(16) uint32_t cp[4]; @@ -530,7 +530,7 @@ text_run_body(struct cell *restrict row, const char *restrict buf, int len, int { int i = 0; int cx = 0; - if (TERM_EXPECT(last == 0x200D || grapheme_is_handle(last), 0)) + if (TERM_EXPECT(last == 0x200D || term_grapheme_is_handle(last), 0)) return (struct text_run_result){0, 0, last}; const struct cell_bases bases = cell_bases_make(fg, bg, flags); @@ -593,14 +593,14 @@ text_run_body(struct cell *restrict row, const char *restrict buf, int len, int } #endif uint32_t cp; - int bytes = utf8_decode_one(buf + i, (size_t)(len - i), &cp); + int bytes = term_utf8_decode_one(buf + i, (size_t)(len - i), &cp); if (!bytes) break; int w = bytes < 4 ? unicode_fast_class[cp] : term_text_class(cp); if (w <= 0 || (bytes == 4 && can_extend_cluster(last, cp, w))) break; #if defined(TERM_KERNEL_AVX512) if (isa == TERM_ISA_AVX512 && bytes == 3 && w == 2 && i + 6 <= len && cx + 4 <= max_cols) { uint32_t next_cp; - if (utf8_decode_one(buf + i + 3, (size_t)(len - i - 3), &next_cp) == 3 && + if (term_utf8_decode_one(buf + i + 3, (size_t)(len - i - 3), &next_cp) == 3 && unicode_fast_class[next_cp] == 2) { store_wide_pair(dst, fg, bg, flags, cp, next_cp); dst += 8; diff --git a/src/text_run.h b/src/text_run.h index fac638f..3ff432b 100644 --- a/src/text_run.h +++ b/src/text_run.h @@ -53,25 +53,25 @@ static inline bool joins_cluster(uint32_t cp, int klass) { if (cp < 0x0300) return false; - if (klass == 0 || grapheme_emoji_modifier(cp)) + if (klass == 0 || term_grapheme_emoji_modifier(cp)) return true; - return klass == 1 && unicode_spacing_mark(cp); + return klass == 1 && term_unicode_spacing_mark(cp); } static inline bool can_extend_cluster(uint32_t last_char, uint32_t cp, int klass) { if (klass == 0) return true; - if (last_char == 0x200D || grapheme_is_handle(last_char)) return true; - if (cp - 0x1F1E6u <= 0x19u && grapheme_regional_indicator(cp)) + if (last_char == 0x200D || term_grapheme_is_handle(last_char)) return true; + if (cp - 0x1F1E6u <= 0x19u && term_grapheme_regional_indicator(cp)) return true; return joins_cluster(cp, klass); } static inline bool cluster_contextual(uint32_t cp) { - return unicode_spacing_mark(cp) || grapheme_emoji_modifier(cp) || - (cp - 0x1F1E6u <= 0x19u && grapheme_regional_indicator(cp)); + return term_unicode_spacing_mark(cp) || term_grapheme_emoji_modifier(cp) || + (cp - 0x1F1E6u <= 0x19u && term_grapheme_regional_indicator(cp)); } static inline bool cluster_joins(const uint32_t *cps, int len, @@ -80,10 +80,10 @@ static inline bool cluster_joins(const uint32_t *cps, int len, if (joins_cluster(cp, klass)) return true; if (cps[len - 1] == 0x200D) - return unicode_extended_pictographic(cp); + return term_unicode_extended_pictographic(cp); return len == 1 && cp - 0x1F1E6u <= 0x19u && - grapheme_regional_indicator(cp) && - grapheme_regional_indicator(cps[0]); + term_grapheme_regional_indicator(cp) && + term_grapheme_regional_indicator(cps[0]); } #endif diff --git a/tests/gstore_test.c b/tests/gstore_test.c index 637b136..ea582f3 100644 --- a/tests/gstore_test.c +++ b/tests/gstore_test.c @@ -32,7 +32,7 @@ static void test_direct_unit(void) /* Cluster returns a handle. */ uint32_t c1[2] = { 'e', 0x0301 }; uint32_t h1 = term_gstore_intern(g, c1, 2); - assert(grapheme_is_handle(h1)); + assert(term_grapheme_is_handle(h1)); assert(term_gstore_count(g) == 1); /* Identical cluster deduplicates to the same handle. */ @@ -43,17 +43,17 @@ static void test_direct_unit(void) /* Different cluster gets a distinct handle. */ uint32_t c2[2] = { 'a', 0x0300 }; uint32_t h2 = term_gstore_intern(g, c2, 2); - assert(grapheme_is_handle(h2)); + assert(term_grapheme_is_handle(h2)); assert(h2 != h1); assert(term_gstore_count(g) == 2); /* Expand both handles. */ - uint32_t out[GRAPHEME_MAX_LEN] = {0}; - int n = term_gstore_expand(g, h1, out, GRAPHEME_MAX_LEN); + uint32_t out[TERM_GRAPHEME_MAX_LEN] = {0}; + int n = term_gstore_expand(g, h1, out, TERM_GRAPHEME_MAX_LEN); assert(n == 2); assert(out[0] == 'e' && out[1] == 0x0301); - n = term_gstore_expand(g, h2, out, GRAPHEME_MAX_LEN); + n = term_gstore_expand(g, h2, out, TERM_GRAPHEME_MAX_LEN); assert(n == 2); assert(out[0] == 'a' && out[1] == 0x0300); @@ -63,20 +63,20 @@ static void test_direct_unit(void) assert(term_gstore_count(g) == 1); /* h1 is still valid. */ - n = term_gstore_expand(g, h1, out, GRAPHEME_MAX_LEN); + n = term_gstore_expand(g, h1, out, TERM_GRAPHEME_MAX_LEN); assert(n == 2); assert(out[0] == 'e' && out[1] == 0x0301); /* h2 was reclaimed. */ - n = term_gstore_expand(g, h2, out, GRAPHEME_MAX_LEN); + n = term_gstore_expand(g, h2, out, TERM_GRAPHEME_MAX_LEN); assert(n == 1 && out[0] == 0xFFFD); /* New cluster can reuse the reclaimed slot. */ uint32_t c3[3] = { 'o', 0x0308, 0x0301 }; uint32_t h3 = term_gstore_intern(g, c3, 3); - assert(grapheme_is_handle(h3)); + assert(term_grapheme_is_handle(h3)); assert(term_gstore_count(g) == 2); - n = term_gstore_expand(g, h3, out, GRAPHEME_MAX_LEN); + n = term_gstore_expand(g, h3, out, TERM_GRAPHEME_MAX_LEN); assert(n == 3); assert(out[0] == 'o' && out[1] == 0x0308 && out[2] == 0x0301); @@ -105,8 +105,8 @@ static void test_two_terminals_isolation(void) const struct term_cell *row = term_snapshot_row(snap, 0); assert(row[0].text & TERM_TEXT_CLUSTER); - uint32_t cps[GRAPHEME_MAX_LEN] = {0}; - int n = term_snapshot_cluster(snap, row[0].text, cps, GRAPHEME_MAX_LEN); + uint32_t cps[TERM_GRAPHEME_MAX_LEN] = {0}; + int n = term_snapshot_cluster(snap, row[0].text, cps, TERM_GRAPHEME_MAX_LEN); assert(n == 2); assert(cps[0] == 'e' && cps[1] == 0x0301); @@ -143,16 +143,16 @@ static void test_screen_clusters_survive_sweep(void) const struct term_cell *row = term_snapshot_row(snap, 0); assert(row[0].text & TERM_TEXT_CLUSTER); - uint32_t cps[GRAPHEME_MAX_LEN] = {0}; - int n = term_snapshot_cluster(snap, row[0].text, cps, GRAPHEME_MAX_LEN); + uint32_t cps[TERM_GRAPHEME_MAX_LEN] = {0}; + int n = term_snapshot_cluster(snap, row[0].text, cps, TERM_GRAPHEME_MAX_LEN); assert(n == 2); assert(cps[0] == 'a' && cps[1] == 0x0300); - n = term_snapshot_cluster(snap, row[1].text, cps, GRAPHEME_MAX_LEN); + n = term_snapshot_cluster(snap, row[1].text, cps, TERM_GRAPHEME_MAX_LEN); assert(n == 2); assert(cps[0] == 'b' && cps[1] == 0x0301); - n = term_snapshot_cluster(snap, row[2].text, cps, GRAPHEME_MAX_LEN); + n = term_snapshot_cluster(snap, row[2].text, cps, TERM_GRAPHEME_MAX_LEN); assert(n == 2); assert(cps[0] == 'c' && cps[1] == 0x0302); @@ -183,8 +183,8 @@ static void test_more_than_65536_clusters(void) size_t len = 0; buf[len++] = base; - len += (size_t)utf8_encode(cp1, buf + len); - len += (size_t)utf8_encode(cp2, buf + len); + len += (size_t)term_utf8_encode(cp1, buf + len); + len += (size_t)term_utf8_encode(cp2, buf + len); buf[len++] = '\r'; buf[len++] = '\n'; @@ -204,8 +204,8 @@ static void test_more_than_65536_clusters(void) const struct term_cell *row = term_snapshot_row(snap, y); assert(row[0].text & TERM_TEXT_CLUSTER); - uint32_t cps[GRAPHEME_MAX_LEN] = {0}; - int n = term_snapshot_cluster(snap, row[0].text, cps, GRAPHEME_MAX_LEN); + uint32_t cps[TERM_GRAPHEME_MAX_LEN] = {0}; + int n = term_snapshot_cluster(snap, row[0].text, cps, TERM_GRAPHEME_MAX_LEN); assert(n == 3); /* Live cluster count must be small (only bounded screen and history). */ diff --git a/tests/header_test.sh b/tests/header_test.sh index 4ba091b..9fd1041 100644 --- a/tests/header_test.sh +++ b/tests/header_test.sh @@ -1,25 +1,70 @@ #!/usr/bin/env bash -# A host includes term.h and nothing else. The header compiles alone as -# strict C11 and as C++, with only include/term on the include path. +# A host includes <term/term.h> and nothing else. The package puts only the +# parent of term/ on the include path. The headers compile alone as strict +# C11 and as C++. set -euo pipefail cd "${1:-$(dirname "$0")/..}" cc=${CC:-cc} cxx=${CXX:-c++} status=0 -echo '#include "term.h"' | "$cc" -std=c11 -Wall -Wextra -Wpedantic -Werror \ - -Iinclude/term -x c -fsyntax-only - || { echo "term.h: not valid C11" >&2; status=1; } -if command -v "$cxx" >/dev/null; then - echo '#include "term.h"' | "$cxx" -std=c++17 -Wall -Wextra -Wpedantic -Werror \ - -Iinclude/term -x c++ -fsyntax-only - || { echo "term.h: not valid C++" >&2; status=1; } -fi + +# check LABEL: compile the code on stdin as C11 and as C++, with include/ +# on the path. +check() { + local label=$1 src + src=$(cat) + printf '%s\n' "$src" | "$cc" -std=c11 -Wall -Wextra -Wpedantic -Werror \ + -Iinclude -x c -fsyntax-only - || { echo "$label: not valid C11" >&2; status=1; } + if command -v "$cxx" >/dev/null; then + printf '%s\n' "$src" | "$cxx" -std=c++17 -Wall -Wextra -Wpedantic -Werror \ + -Iinclude -x c++ -fsyntax-only - || { echo "$label: not valid C++" >&2; status=1; } + fi +} + +check term.h <<'EOF' +#include <term/term.h> +EOF # Apple headers define wide before a host includes the Unicode API. -unicode_header=$'typedef struct wide { int value; } wide;\n#include "unicode/width.h"' -echo "$unicode_header" | "$cc" -std=c11 -Wall -Wextra -Wpedantic -Werror \ - -Iinclude/term -x c -fsyntax-only - || { echo "unicode/width.h: conflicts with host types" >&2; status=1; } -if command -v "$cxx" >/dev/null; then - echo "$unicode_header" | "$cxx" -std=c++17 -Wall -Wextra -Wpedantic -Werror \ - -Iinclude/term -x c++ -fsyntax-only - || { echo "unicode/width.h: conflicts with C++ host types" >&2; status=1; } -fi +check "unicode/width.h: conflicts with host types" <<'EOF' +typedef struct wide { int value; } wide; +#include <term/unicode/width.h> +EOF + +# A host that uses the names the Unicode API had before the term_ and +# TERM_ prefixes. The API must not clash with them in either order. +check "unicode API: host names declared first" <<'EOF' +int unicode_width(int); +static int in_ranges; +static int zero_width; +static int utf8d; +struct unicode_range { int lo; }; +#define UTF8_ACCEPT 7 +#define GRAPHEME_MAX_LEN 3 +#define IN_TABLE 1 +#define UNICODE_DATA_VERSION "host" +#define UTF_8_H +#include <term/unicode/utf8.h> +#include <term/unicode/width.h> +#include <term/unicode/grapheme.h> +int host_use(void) +{ + return in_ranges + zero_width + utf8d + unicode_width(1) + UTF8_ACCEPT + GRAPHEME_MAX_LEN; +} +EOF + +check "unicode API: host names declared after" <<'EOF' +#include <term/unicode/utf8.h> +#include <term/unicode/width.h> +#include <term/unicode/grapheme.h> +int unicode_width(int); +static int in_ranges; +#define UTF8_ACCEPT 7 +#define GRAPHEME_MAX_LEN 3 +int host_use(void) +{ + return in_ranges + unicode_width(1) + UTF8_ACCEPT + GRAPHEME_MAX_LEN; +} +EOF exit $status diff --git a/tests/hist_test.c b/tests/hist_test.c index d772c5a..691ae3c 100644 --- a/tests/hist_test.c +++ b/tests/hist_test.c @@ -129,9 +129,9 @@ static void test_clusters_roundtrip(void) struct cell out[2]; assert(term_hist_decode_segment(&h, 0, 0, 2, out, g) == 2); - assert(grapheme_is_handle(out[0].c)); - uint32_t got[GRAPHEME_MAX_LEN]; - assert(term_gstore_expand(g, out[0].c, got, GRAPHEME_MAX_LEN) == 3); + assert(term_grapheme_is_handle(out[0].c)); + uint32_t got[TERM_GRAPHEME_MAX_LEN]; + assert(term_gstore_expand(g, out[0].c, got, TERM_GRAPHEME_MAX_LEN) == 3); assert(got[0] == cps[0] && got[1] == cps[1] && got[2] == cps[2]); assert(out[1].c == 'X'); @@ -623,9 +623,9 @@ static void test_fuzz_rows(void) continue; } assert(a->fg == b->fg && a->flags == b->flags); - if (grapheme_is_handle(a->c)) { - uint32_t got[GRAPHEME_MAX_LEN]; - assert(term_gstore_expand(g, b->c, got, GRAPHEME_MAX_LEN) == 2 && got[1] == 0x0301); + if (term_grapheme_is_handle(a->c)) { + uint32_t got[TERM_GRAPHEME_MAX_LEN]; + assert(term_gstore_expand(g, b->c, got, TERM_GRAPHEME_MAX_LEN) == 2 && got[1] == 0x0301); } else { assert(a->c == b->c); } diff --git a/tests/model.c b/tests/model.c index d212acb..6c9f288 100644 --- a/tests/model.c +++ b/tests/model.c @@ -31,7 +31,7 @@ #define STR_KEEP 1024 struct cell { - uint32_t cp[GRAPHEME_MAX_LEN]; + uint32_t cp[TERM_GRAPHEME_MAX_LEN]; uint8_t n, width; uint16_t attrs; term_color fg, bg; @@ -99,7 +99,7 @@ struct model { bool tabs[MAX_TABS]; struct keyboard keyboard[2]; /* The last printed glyph, for REP and cluster joins. */ - uint32_t last[GRAPHEME_MAX_LEN]; + uint32_t last[TERM_GRAPHEME_MAX_LEN]; int last_n; int prompt; /* screen row of the last OSC 133;A, or -1 */ unsigned flags; @@ -159,7 +159,7 @@ static bool pristine(const struct model *m) static bool is_ri(uint32_t cp) { - return cp - 0x1F1E6u <= 0x19u && grapheme_regional_indicator(cp); + return cp - 0x1F1E6u <= 0x19u && term_grapheme_regional_indicator(cp); } /* ---- replies ---- */ @@ -418,13 +418,13 @@ static void fill_gap(struct row *r, int x) static uint16_t presentation(const uint32_t *cps, int n) { - bool pictographic = unicode_extended_pictographic(cps[0]); + bool pictographic = term_unicode_extended_pictographic(cps[0]); bool emoji = false; for (int i = 1; i < n; i++) { if (cps[i] == 0xFE0F) return TERM_ATTR_EMOJI; if (cps[i] == 0xFE0E) return TERM_ATTR_TEXT; - if (cps[i] == 0x20E3 || grapheme_regional_indicator(cps[i]) || - (pictographic && (cps[i] == 0x200D || grapheme_emoji_modifier(cps[i]) || + if (cps[i] == 0x20E3 || term_grapheme_regional_indicator(cps[i]) || + (pictographic && (cps[i] == 0x200D || term_grapheme_emoji_modifier(cps[i]) || (cps[i] >= 0xE0020 && cps[i] <= 0xE007F)))) emoji = true; } @@ -444,7 +444,7 @@ static void put_glyph(struct model *m, const uint32_t *cps, int n, uint16_t attr { if (n > 1) attrs = (uint16_t)((attrs & ~(TERM_ATTR_EMOJI | TERM_ATTR_TEXT)) | presentation(cps, n)); - int width = unicode_width(cps[0]) == 2 ? 2 : 1; + int width = term_unicode_width(cps[0]) == 2 ? 2 : 1; if (attrs & TERM_ATTR_EMOJI) width = 2; if (attrs & TERM_ATTR_TEXT) width = 1; if (m->pending) wrap_to_next_row(m); @@ -496,14 +496,14 @@ static void put_glyph(struct model *m, const uint32_t *cps, int n, uint16_t attr static bool joins(uint32_t cp, int width) { if (cp < 0x300) return false; - return width == 0 || grapheme_emoji_modifier(cp) || - (width == 1 && unicode_spacing_mark(cp)); + return width == 0 || term_grapheme_emoji_modifier(cp) || + (width == 1 && term_unicode_spacing_mark(cp)); } static bool cluster_joins(const uint32_t *cps, int n, uint32_t cp, int width) { if (joins(cp, width)) return true; - if (cps[n - 1] == 0x200D) return unicode_extended_pictographic(cp); + if (cps[n - 1] == 0x200D) return term_unicode_extended_pictographic(cp); return n == 1 && is_ri(cp) && is_ri(cps[0]); } @@ -528,10 +528,10 @@ static bool extend_cluster(struct model *m, uint32_t cp, int width) return joins(cp, width); if (!cluster_joins(prev->cp, prev->n, cp, width)) return false; - if (prev->n >= GRAPHEME_MAX_LEN) + if (prev->n >= TERM_GRAPHEME_MAX_LEN) return true; struct cell old = *prev; - uint32_t cps[GRAPHEME_MAX_LEN]; + uint32_t cps[TERM_GRAPHEME_MAX_LEN]; memcpy(cps, old.cp, (size_t)old.n * sizeof(*cps)); cps[old.n] = cp; int n = old.n + 1; @@ -591,7 +591,7 @@ static void print_cp(struct model *m, uint32_t cp) emit(m, cp); return; } - int width = unicode_width(cp); + int width = term_unicode_width(cp); if (!extend_cluster(m, cp, width)) emit(m, cp); } diff --git a/tests/model.h b/tests/model.h index 1707ef7..ca2bf96 100644 --- a/tests/model.h +++ b/tests/model.h @@ -19,7 +19,7 @@ #include <stdint.h> struct model_cell { - uint32_t cp[GRAPHEME_MAX_LEN]; + uint32_t cp[TERM_GRAPHEME_MAX_LEN]; uint8_t n; /* code points; 0 for the right half of a wide cell */ uint8_t width; /* 1, 2 for a wide cell, 0 for its right half */ uint16_t attrs; /* TERM_ATTR_* */ diff --git a/tests/model_test.c b/tests/model_test.c index e94307c..d3988c6 100644 --- a/tests/model_test.c +++ b/tests/model_test.c @@ -122,8 +122,8 @@ static void dump_all(struct model *m, struct term *t, struct term_snapshot *snap term_snapshot_update(snap, t); const struct term_cell *row = term_snapshot_row(snap, r < total ? 0 : r - total); for (int x = 0; x < size.x; x++) { - uint32_t cp[GRAPHEME_MAX_LEN] = {0}; - if (row[x].text) term_snapshot_cluster(snap, row[x].text, cp, GRAPHEME_MAX_LEN); + uint32_t cp[TERM_GRAPHEME_MAX_LEN] = {0}; + if (row[x].text) term_snapshot_cluster(snap, row[x].text, cp, TERM_GRAPHEME_MAX_LEN); fputc(glyph(cp[0]), log); } } else { @@ -201,9 +201,9 @@ static const char *compare(struct model *m, struct term *t, struct term_snapshot const struct model_cell *want_row = model_row(m, retained); for (int x = 0; x < size.x; x++) { const struct model_cell *e = &want_row[x]; - uint32_t cps[GRAPHEME_MAX_LEN] = {0}; + uint32_t cps[TERM_GRAPHEME_MAX_LEN] = {0}; int n = row[x].text ? term_snapshot_cluster(snap, row[x].text, cps, - GRAPHEME_MAX_LEN) : 0; + TERM_GRAPHEME_MAX_LEN) : 0; if (n == e->n && row[x].width == e->width && row[x].attrs == e->attrs && row[x].fg == e->fg && row[x].bg == e->bg && !memcmp(cps, e->cp, (size_t)n * sizeof(*cps))) @@ -211,9 +211,9 @@ static const char *compare(struct model *m, struct term *t, struct term_snapshot if (log) { fprintf(log, "retained row %d (offset %d):\n term: ", retained, offset); for (int k = 0; k < size.x; k++) { - uint32_t cp[GRAPHEME_MAX_LEN] = {0}; + uint32_t cp[TERM_GRAPHEME_MAX_LEN] = {0}; if (row[k].text) - term_snapshot_cluster(snap, row[k].text, cp, GRAPHEME_MAX_LEN); + term_snapshot_cluster(snap, row[k].text, cp, TERM_GRAPHEME_MAX_LEN); fputc(glyph(cp[0]), log); } fprintf(log, "\n model: "); diff --git a/tests/term_test.c b/tests/term_test.c index 62b827f..235e9df 100644 --- a/tests/term_test.c +++ b/tests/term_test.c @@ -2032,15 +2032,15 @@ int main(void) test_bulk_rows_survive_edits(); test_host_name_rejected(); - assert(!strcmp(UNICODE_DATA_VERSION, "18.0.0")); - assert(!strcmp(term_unicode_version(), UNICODE_DATA_VERSION)); - assert(unicode_width('A') == 1); - assert(unicode_width(0x0301) == 0); - assert(unicode_width(0x754C) == 2); - assert(unicode_width(0x1FAE0) == 2); - assert(unicode_emoji_presentation(0x1FAE0)); - assert(unicode_width(0x1FAEB) == 2); - assert(unicode_emoji_presentation(0x1FAEB)); + assert(!strcmp(TERM_UNICODE_DATA_VERSION, "18.0.0")); + assert(!strcmp(term_unicode_version(), TERM_UNICODE_DATA_VERSION)); + assert(term_unicode_width('A') == 1); + assert(term_unicode_width(0x0301) == 0); + assert(term_unicode_width(0x754C) == 2); + assert(term_unicode_width(0x1FAE0) == 2); + assert(term_unicode_emoji_presentation(0x1FAE0)); + assert(term_unicode_width(0x1FAEB) == 2); + assert(term_unicode_emoji_presentation(0x1FAEB)); { /* A Jamo Extended-B vowel draws inside its leading consonant. */ struct term *t = term_new(&(struct term_options){ .size = { .x = 10, .y = 2 } }); diff --git a/tests/unicode/unicode_test.c b/tests/unicode/unicode_test.c index 7fc6e3e..e3cf5a7 100644 --- a/tests/unicode/unicode_test.c +++ b/tests/unicode/unicode_test.c @@ -16,17 +16,17 @@ static void test_utf8_decode_one(void) for (size_t i = 0; i < sizeof(valid) / sizeof(*valid); i++) { uint32_t cp = 0xdeadbeef; for (int n = 0; n < valid[i].len; n++) { - int r = utf8_decode_one(valid[i].bytes, n, &cp); + int r = term_utf8_decode_one(valid[i].bytes, n, &cp); assert(r == 0); assert(cp == 0xdeadbeef); } - int r = utf8_decode_one(valid[i].bytes, valid[i].len, &cp); + int r = term_utf8_decode_one(valid[i].bytes, valid[i].len, &cp); assert(r == valid[i].len); assert(cp == valid[i].cp); char followed[8]; memcpy(followed, valid[i].bytes, valid[i].len); memcpy(followed + valid[i].len, "next", 4); - r = utf8_decode_one(followed, valid[i].len + 4, &cp); + r = term_utf8_decode_one(followed, valid[i].len + 4, &cp); assert(r == valid[i].len); assert(cp == valid[i].cp); } @@ -38,7 +38,7 @@ static void test_utf8_decode_one(void) }; for (size_t i = 0; i < sizeof(invalid) / sizeof(*invalid); i++) { uint32_t cp = 0xdeadbeef; - int r = utf8_decode_one(invalid[i], strlen(invalid[i]), &cp); + int r = term_utf8_decode_one(invalid[i], strlen(invalid[i]), &cp); assert(r == 0); assert(cp == 0xdeadbeef); } @@ -48,24 +48,24 @@ static void test_scalar_roundtrips(void) { for (uint32_t cp = 0; cp <= 0x10ffff; cp++) { if (cp >= 0xd800 && cp <= 0xdfff) continue; - char bytes[UTF8_MAX_BYTES]; - int len = utf8_encode(cp, bytes); - uint32_t scalar = 0, streamed = 0, state = UTF8_ACCEPT; - int r = utf8_decode_one(bytes, (size_t)len, &scalar); + char bytes[TERM_UTF8_MAX_BYTES]; + int len = term_utf8_encode(cp, bytes); + uint32_t scalar = 0, streamed = 0, state = TERM_UTF8_ACCEPT; + int r = term_utf8_decode_one(bytes, (size_t)len, &scalar); assert(r == len); assert(scalar == cp); for (int i = 0; i < len; i++) { - utf8_decode(&state, &streamed, (unsigned char)bytes[i]); - if (i + 1 < len) assert(state != UTF8_ACCEPT && state != UTF8_REJECT); + term_utf8_decode(&state, &streamed, (unsigned char)bytes[i]); + if (i + 1 < len) assert(state != TERM_UTF8_ACCEPT && state != TERM_UTF8_REJECT); } - assert(state == UTF8_ACCEPT && streamed == cp); + assert(state == TERM_UTF8_ACCEPT && streamed == cp); } static const uint32_t invalid[] = {0xd800, 0xdfff, 0x110000, UINT32_MAX}; for (size_t i = 0; i < sizeof(invalid) / sizeof(*invalid); i++) { - char bytes[UTF8_MAX_BYTES]; - int len = utf8_encode(invalid[i], bytes); + char bytes[TERM_UTF8_MAX_BYTES]; + int len = term_utf8_encode(invalid[i], bytes); uint32_t cp = 0; - int r = utf8_decode_one(bytes, len, &cp); + int r = term_utf8_decode_one(bytes, len, &cp); assert(len == 3 && r == len && cp == 0xfffd); } } @@ -74,26 +74,26 @@ static void test_utf8_sanitize(void) { char dst[64]; - utf8_sanitize(dst, sizeof(dst), "hello \xe2\x82\xac\xf0\x9f\x98\x80"); + term_utf8_sanitize(dst, sizeof(dst), "hello \xe2\x82\xac\xf0\x9f\x98\x80"); assert(!strcmp(dst, "hello \xe2\x82\xac\xf0\x9f\x98\x80")); - utf8_sanitize(dst, sizeof(dst), "a\xff\x80" "b\xed\xa0\x80" "c\xe2\x82"); + term_utf8_sanitize(dst, sizeof(dst), "a\xff\x80" "b\xed\xa0\x80" "c\xe2\x82"); assert(!strcmp(dst, "abc")); - utf8_sanitize(dst, sizeof(dst), ""); + term_utf8_sanitize(dst, sizeof(dst), ""); assert(!strcmp(dst, "")); - utf8_sanitize(dst, sizeof(dst), "\xff\xfe"); + term_utf8_sanitize(dst, sizeof(dst), "\xff\xfe"); assert(!strcmp(dst, "")); - utf8_sanitize(dst, 6, "ab\xe2\x82\xac" "cd"); + term_utf8_sanitize(dst, 6, "ab\xe2\x82\xac" "cd"); assert(!strcmp(dst, "ab\xe2\x82\xac")); - utf8_sanitize(dst, 5, "ab\xe2\x82\xac" "cd"); + term_utf8_sanitize(dst, 5, "ab\xe2\x82\xac" "cd"); assert(!strcmp(dst, "abcd")); memset(dst, 'x', sizeof(dst)); - utf8_sanitize(dst, 4, "abcdef"); + term_utf8_sanitize(dst, 4, "abcdef"); assert(!strcmp(dst, "abc")); memset(dst, 'x', sizeof(dst)); - utf8_sanitize(dst, 0, "abc"); + term_utf8_sanitize(dst, 0, "abc"); assert(dst[0] == 'x'); } @@ -101,30 +101,30 @@ static void test_utf8_sanitize(void) * stays unused. */ static void test_ground_invalid_subparts(void) { - uint32_t state = UTF8_ACCEPT, codep = 0, cp = 0xdead; - int n = utf8_decode_ground(&state, &codep, "\xe2\x80\x1b\xac", 4, &cp); + uint32_t state = TERM_UTF8_ACCEPT, codep = 0, cp = 0xdead; + int n = term_utf8_decode_ground(&state, &codep, "\xe2\x80\x1b\xac", 4, &cp); assert(n == 2); assert(cp == 0xFFFD); - assert(state == UTF8_ACCEPT); - n = utf8_decode_ground(&state, &codep, "\xac", 1, &cp); + assert(state == TERM_UTF8_ACCEPT); + n = term_utf8_decode_ground(&state, &codep, "\xac", 1, &cp); assert(n == 1); assert(cp == 0xFFFD); - assert(state == UTF8_ACCEPT); - n = utf8_decode_ground(&state, &codep, "\xe2\x82z", 3, &cp); + assert(state == TERM_UTF8_ACCEPT); + n = term_utf8_decode_ground(&state, &codep, "\xe2\x82z", 3, &cp); assert(n == 2); assert(cp == 0xFFFD); - assert(state == UTF8_ACCEPT); - n = utf8_decode_ground(&state, &codep, "\xe2\x82", 2, &cp); + assert(state == TERM_UTF8_ACCEPT); + n = term_utf8_decode_ground(&state, &codep, "\xe2\x82", 2, &cp); assert(n == 2); assert(cp == 0); - assert(state != UTF8_ACCEPT); + assert(state != TERM_UTF8_ACCEPT); - state = UTF8_ACCEPT; + state = TERM_UTF8_ACCEPT; codep = 0; - n = utf8_decode_ground(&state, &codep, "\xe2\x82\xac", 3, &cp); + n = term_utf8_decode_ground(&state, &codep, "\xe2\x82\xac", 3, &cp); assert(n == 3); assert(cp == 0x20ac); - assert(state == UTF8_ACCEPT); + assert(state == TERM_UTF8_ACCEPT); } int main(void) diff --git a/tools/generate_unicode.py b/tools/generate_unicode.py index 85c646d..22f12a6 100644 --- a/tools/generate_unicode.py +++ b/tools/generate_unicode.py @@ -71,7 +71,7 @@ def unicode_categories(path): return by_category def emit_table(out, name, ranges): - out.append(f"static const struct unicode_range {name}[] = {{") + out.append(f"static const struct term_unicode_range {name}[] = {{") for i in range(0, len(ranges), 4): chunk = ranges[i:i + 4] out.append("\t" + ",".join(f"{{0x{lo:X},0x{hi:X}}}" for lo, hi in chunk) + ",") @@ -104,13 +104,13 @@ def main(): emoji_presentation = field_ranges(args.emoji_data, {"Emoji_Presentation"}) out = [f"/* Generated from Unicode {version} data by tools/generate_unicode.py. */", "", - f'#define UNICODE_DATA_VERSION "{version}"', ""] - emit_table(out, "zero_width", zero) - emit_table(out, "nonprintable", nonprint) - emit_table(out, "unicode_wide", wide) - emit_table(out, "spacing_mark", spacing) - emit_table(out, "extended_pictographic", pictographic) - emit_table(out, "emoji_presentation", emoji_presentation) + f'#define TERM_UNICODE_DATA_VERSION "{version}"', ""] + emit_table(out, "term_zero_width", zero) + emit_table(out, "term_nonprintable", nonprint) + emit_table(out, "term_unicode_wide", wide) + emit_table(out, "term_spacing_mark", spacing) + emit_table(out, "term_extended_pictographic", pictographic) + emit_table(out, "term_emoji_presentation", emoji_presentation) args.output.write_text("\n".join(out)) if __name__ == "__main__": |
