#include "pocketpy/common/str.h" #include "pocketpy/common/sstream.h" #include "pocketpy/common/utils.h" #include #include #include c11_string* c11_string__new(const char* data) { return c11_string__new2(data, strlen(data)); } c11_string* c11_string__new2(const char* data, int size) { c11_string* retval = PK_MALLOC(sizeof(c11_string) + size + 1); c11_string__ctor2(retval, data, size); return retval; } c11_string* c11_string__new3(const char* fmt, ...) { c11_sbuf buf; c11_sbuf__ctor(&buf); va_list args; va_start(args, fmt); // c11_sbuf__write_vfmt(&buf, fmt, args); pk_vsprintf(&buf, fmt, args); va_end(args); return c11_sbuf__submit(&buf); } void c11_string__ctor(c11_string* self, const char* data) { c11_string__ctor2(self, data, strlen(data)); } void c11_string__ctor2(c11_string* self, const char* data, int size) { self->size = size; char* p = (char*)self->data; memcpy(p, data, size); p[size] = '\0'; } void c11_string__ctor3(c11_string* self, int size) { self->size = size; char* p = (char*)self->data; p[size] = '\0'; } c11_string* c11_string__copy(c11_string* self) { int total_size = sizeof(c11_string) + self->size + 1; c11_string* retval = PK_MALLOC(total_size); memcpy(retval, self, total_size); return retval; } void c11_string__delete(c11_string* self) { PK_FREE(self); } c11_sv c11_string__sv(c11_string* self) { return (c11_sv){self->data, self->size}; } c11_string* c11_sv__replace(c11_sv self, char old, char new_) { c11_string* retval = c11_string__new2(self.data, self.size); char* p = (char*)retval->data; for(int i = 0; i < retval->size; i++) { if(p[i] == old) p[i] = new_; } return retval; } c11_string* c11_sv__replace2(c11_sv self, c11_sv old, c11_sv new_) { c11_sbuf buf; c11_sbuf__ctor(&buf); int start = 0; while(true) { int i = c11_sv__index2(self, old, start); if(i == -1) break; c11_sv tmp = c11_sv__slice2(self, start, i); c11_sbuf__write_sv(&buf, tmp); c11_sbuf__write_sv(&buf, new_); start = i + old.size; } c11_sv tmp = c11_sv__slice2(self, start, self.size); c11_sbuf__write_sv(&buf, tmp); return c11_sbuf__submit(&buf); } int c11_sv__u8_length(c11_sv sv) { return c11__byte_index_to_unicode(sv.data, sv.size); } c11_sv c11_sv__u8_getitem(c11_sv sv, int i) { i = c11__unicode_index_to_byte(sv.data, i); int size = c11__u8_header(sv.data[i], false); return c11_sv__slice2(sv, i, i + size); } c11_string* c11_sv__u8_slice(c11_sv sv, int start, int stop, int step) { c11_sbuf ss; c11_sbuf__ctor(&ss); assert(step != 0); for(int i = start; step > 0 ? i < stop : i > stop; i += step) { c11_sv unicode = c11_sv__u8_getitem(sv, i); c11_sbuf__write_sv(&ss, unicode); } return c11_sbuf__submit(&ss); } ///////////////////////////////////////// c11_sv c11_sv__slice(c11_sv sv, int start) { return c11_sv__slice2(sv, start, sv.size); } c11_sv c11_sv__slice2(c11_sv sv, int start, int stop) { if(start < 0) start = 0; if(stop < start) stop = start; if(stop > sv.size) stop = sv.size; return (c11_sv){sv.data + start, stop - start}; } c11_sv c11_sv__strip(c11_sv sv, c11_sv chars, bool left, bool right) { int L = 0; int R = c11_sv__u8_length(sv); if(left) { while(L < R) { c11_sv tmp = c11_sv__u8_getitem(sv, L); bool found = c11_sv__index2(chars, tmp, 0) != -1; if(!found) break; L++; } } if(right) { while(L < R) { c11_sv tmp = c11_sv__u8_getitem(sv, R - 1); bool found = c11_sv__index2(chars, tmp, 0) != -1; if(!found) break; R--; } } int start = c11__unicode_index_to_byte(sv.data, L); int stop = c11__unicode_index_to_byte(sv.data, R); return c11_sv__slice2(sv, start, stop); } int c11_sv__index(c11_sv self, char c) { for(int i = 0; i < self.size; i++) { if(self.data[i] == c) return i; } return -1; } int c11_sv__rindex(c11_sv self, char c) { for(int i = self.size - 1; i >= 0; i--) { if(self.data[i] == c) return i; } return -1; } int c11_sv__index2(c11_sv self, c11_sv sub, int start) { if(sub.size == 0) return start; int max_end = self.size - sub.size; for(int i = start; i <= max_end; i++) { int res = memcmp(self.data + i, sub.data, sub.size); if(res == 0) return i; } return -1; } int c11_sv__count(c11_sv self, c11_sv sub) { if(sub.size == 0) return self.size + 1; int cnt = 0; int start = 0; while(true) { int i = c11_sv__index2(self, sub, start); if(i == -1) break; cnt++; start = i + sub.size; } return cnt; } bool c11_sv__startswith(c11_sv self, c11_sv prefix) { if(prefix.size > self.size) return false; return memcmp(self.data, prefix.data, prefix.size) == 0; } bool c11_sv__endswith(c11_sv self, c11_sv suffix) { if(suffix.size > self.size) return false; return memcmp(self.data + self.size - suffix.size, suffix.data, suffix.size) == 0; } uint64_t c11_sv__hash(c11_sv self) { uint64_t hash = 5381; for(int i = 0; i < self.size; i++) { // hash * 33 + c hash = ((hash << 5) + hash) + (unsigned char)self.data[i]; } return hash; } c11_vector /* T=c11_sv */ c11_sv__split(c11_sv self, char sep) { c11_vector retval; c11_vector__ctor(&retval, sizeof(c11_sv)); const char* data = self.data; int i = 0; for(int j = 0; j < self.size; j++) { if(data[j] == sep) { assert(j >= i); c11_sv tmp = {data + i, j - i}; c11_vector__push(c11_sv, &retval, tmp); i = j + 1; } } if(i <= self.size) { c11_sv tmp = {data + i, self.size - i}; c11_vector__push(c11_sv, &retval, tmp); } return retval; } c11_vector /* T=c11_sv */ c11_sv__split2(c11_sv self, c11_sv sep) { if(sep.size == 1) return c11_sv__split(self, sep.data[0]); c11_vector retval; c11_vector__ctor(&retval, sizeof(c11_sv)); int start = 0; const char* data = self.data; while(true) { int i = c11_sv__index2(self, sep, start); if(i == -1) break; c11_sv tmp = {data + start, i - start}; c11_vector__push(c11_sv, &retval, tmp); start = i + sep.size; } c11_sv tmp = {data + start, self.size - start}; c11_vector__push(c11_sv, &retval, tmp); return retval; } int c11__unicode_index_to_byte(const char* data, int i) { int j = 0; while(i > 0) { j += c11__u8_header(data[j], false); i--; } return j; } int c11__byte_index_to_unicode(const char* data, int n) { int cnt = 0; for(int i = 0; i < n; i++) { if((data[i] & 0xC0) != 0x80) cnt++; } return cnt; } ////////////// bool c11_bytes__eq(c11_bytes* self, c11_bytes* other) { if(self->size != other->size) return false; return memcmp(self->data, other->data, self->size) == 0; } int c11_sv__cmp(c11_sv self, c11_sv other) { int res = strncmp(self.data, other.data, c11__min(self.size, other.size)); if(res != 0) return res; return self.size - other.size; } int c11_sv__cmp2(c11_sv self, const char* other) { int size = strlen(other); int res = strncmp(self.data, other, c11__min(self.size, size)); if(res != 0) return res; return self.size - size; } bool c11__streq(const char* a, const char* b) { return strcmp(a, b) == 0; } bool c11__sveq(c11_sv a, c11_sv b) { if(a.size != b.size) return false; return memcmp(a.data, b.data, a.size) == 0; } bool c11__sveq2(c11_sv a, const char* b) { int size = strlen(b); if(a.size != size) return false; return memcmp(a.data, b, size) == 0; } int c11__u8_header(unsigned char c, bool suppress) { if((c & 0b10000000) == 0) return 1; if((c & 0b11100000) == 0b11000000) return 2; if((c & 0b11110000) == 0b11100000) return 3; if((c & 0b11111000) == 0b11110000) return 4; if((c & 0b11111100) == 0b11111000) return 5; if((c & 0b11111110) == 0b11111100) return 6; if(!suppress) c11__abort("invalid utf8 char"); return 0; } int c11__u8_value(int u8bytes, const char* data) { assert(u8bytes != 0); if(u8bytes == 1) return (int)data[0]; uint32_t value = 0; for(int k = 0; k < u8bytes; k++) { uint8_t b = data[k]; if(k == 0) { if(u8bytes == 2) value = (b & 0b00011111) << 6; else if(u8bytes == 3) value = (b & 0b00001111) << 12; else if(u8bytes == 4) value = (b & 0b00000111) << 18; } else { value |= (b & 0b00111111) << (6 * (u8bytes - k - 1)); } } return (int)value; } int c11__u32_to_u8(uint32_t utf32_char, char utf8_output[4]) { int length = 0; if(utf32_char <= 0x7F) { // 1-byte UTF-8 utf8_output[0] = (char)utf32_char; length = 1; } else if(utf32_char <= 0x7FF) { // 2-byte UTF-8 utf8_output[0] = (char)(0xC0 | ((utf32_char >> 6) & 0x1F)); utf8_output[1] = (char)(0x80 | (utf32_char & 0x3F)); length = 2; } else if(utf32_char <= 0xFFFF) { // 3-byte UTF-8 utf8_output[0] = (char)(0xE0 | ((utf32_char >> 12) & 0x0F)); utf8_output[1] = (char)(0x80 | ((utf32_char >> 6) & 0x3F)); utf8_output[2] = (char)(0x80 | (utf32_char & 0x3F)); length = 3; } else if(utf32_char <= 0x10FFFF) { // 4-byte UTF-8 utf8_output[0] = (char)(0xF0 | ((utf32_char >> 18) & 0x07)); utf8_output[1] = (char)(0x80 | ((utf32_char >> 12) & 0x3F)); utf8_output[2] = (char)(0x80 | ((utf32_char >> 6) & 0x3F)); utf8_output[3] = (char)(0x80 | (utf32_char & 0x3F)); length = 4; } else { // Invalid UTF-32 character return -1; } return length; } char* c11_strdup(const char* str) { int len = strlen(str); char* dst = PK_MALLOC(len + 1); memcpy(dst, str, len); dst[len] = '\0'; return dst; } unsigned char* c11_memdup(const unsigned char* src, int size) { unsigned char* dst = PK_MALLOC(size); memcpy(dst, src, size); return dst; } IntParsingResult c11__parse_uint(c11_sv text, int64_t* out, int base) { *out = 0; c11_sv prefix = {.data = text.data, .size = c11__min(2, text.size)}; if(base == -1) { if(c11__sveq2(prefix, "0b")) base = 2; else if(c11__sveq2(prefix, "0o")) base = 8; else if(c11__sveq2(prefix, "0x")) base = 16; else base = 10; } if(base == 10) { // 10-base 12334 if(text.size == 0) return IntParsing_FAILURE; for(int i = 0; i < text.size; i++) { char c = text.data[i]; if(c >= '0' && c <= '9') { *out = (*out * 10) + (c - '0'); } else { return IntParsing_FAILURE; } } // "9223372036854775807".__len__() == 19 if(text.size > 19) return IntParsing_OVERFLOW; return IntParsing_SUCCESS; } else if(base == 2) { // 2-base 0b101010 if(c11__sveq2(prefix, "0b")) { // text.remove_prefix(2); text = (c11_sv){text.data + 2, text.size - 2}; } if(text.size == 0) return IntParsing_FAILURE; for(int i = 0; i < text.size; i++) { char c = text.data[i]; if(c == '0' || c == '1') { *out = (*out << 1) | (c - '0'); } else { return IntParsing_FAILURE; } } // "111111111111111111111111111111111111111111111111111111111111111".__len__() == 63 if(text.size > 63) return IntParsing_OVERFLOW; return IntParsing_SUCCESS; } else if(base == 8) { // 8-base 0o123 if(c11__sveq2(prefix, "0o")) { // text.remove_prefix(2); text = (c11_sv){text.data + 2, text.size - 2}; } if(text.size == 0) return IntParsing_FAILURE; for(int i = 0; i < text.size; i++) { char c = text.data[i]; if(c >= '0' && c <= '7') { *out = (*out << 3) | (c - '0'); } else { return IntParsing_FAILURE; } } // "777777777777777777777".__len__() == 21 if(text.size > 21) return IntParsing_OVERFLOW; return IntParsing_SUCCESS; } else if(base == 16) { // 16-base 0x123 if(c11__sveq2(prefix, "0x")) { // text.remove_prefix(2); text = (c11_sv){text.data + 2, text.size - 2}; } if(text.size == 0) return IntParsing_FAILURE; for(int i = 0; i < text.size; i++) { char c = text.data[i]; if(c >= '0' && c <= '9') { *out = (*out << 4) | (c - '0'); } else if(c >= 'a' && c <= 'f') { *out = (*out << 4) | (c - 'a' + 10); } else if(c >= 'A' && c <= 'F') { *out = (*out << 4) | (c - 'A' + 10); } else { return IntParsing_FAILURE; } } // "7fffffffffffffff".__len__() == 16 if(text.size > 16) return IntParsing_OVERFLOW; return IntParsing_SUCCESS; } return IntParsing_FAILURE; } const char* c11__search_u32_ranges(int c, const c11_u32_range* p, int n_ranges) { int lbound = 0; int ubound = n_ranges - 1; if(c < p[0].start || c > p[ubound].end) return NULL; while(ubound >= lbound) { int mid = (lbound + ubound) / 2; if(c > p[mid].end) { lbound = mid + 1; } else if(c < p[mid].start) { ubound = mid - 1; } else { return p[mid].data; } } return NULL; } const static c11_u32_range kLoRanges[] = { {170, 170 }, {186, 186 }, {443, 443 }, {448, 451 }, {660, 660 }, {1488, 1514 }, {1519, 1522 }, {1568, 1599 }, {1601, 1610 }, {1646, 1647 }, {1649, 1747 }, {1749, 1749 }, {1774, 1775 }, {1786, 1788 }, {1791, 1791 }, {1808, 1808 }, {1810, 1839 }, {1869, 1957 }, {1969, 1969 }, {1994, 2026 }, {2048, 2069 }, {2112, 2136 }, {2144, 2154 }, {2160, 2183 }, {2185, 2190 }, {2208, 2248 }, {2308, 2361 }, {2365, 2365 }, {2384, 2384 }, {2392, 2401 }, {2418, 2432 }, {2437, 2444 }, {2447, 2448 }, {2451, 2472 }, {2474, 2480 }, {2482, 2482 }, {2486, 2489 }, {2493, 2493 }, {2510, 2510 }, {2524, 2525 }, {2527, 2529 }, {2544, 2545 }, {2556, 2556 }, {2565, 2570 }, {2575, 2576 }, {2579, 2600 }, {2602, 2608 }, {2610, 2611 }, {2613, 2614 }, {2616, 2617 }, {2649, 2652 }, {2654, 2654 }, {2674, 2676 }, {2693, 2701 }, {2703, 2705 }, {2707, 2728 }, {2730, 2736 }, {2738, 2739 }, {2741, 2745 }, {2749, 2749 }, {2768, 2768 }, {2784, 2785 }, {2809, 2809 }, {2821, 2828 }, {2831, 2832 }, {2835, 2856 }, {2858, 2864 }, {2866, 2867 }, {2869, 2873 }, {2877, 2877 }, {2908, 2909 }, {2911, 2913 }, {2929, 2929 }, {2947, 2947 }, {2949, 2954 }, {2958, 2960 }, {2962, 2965 }, {2969, 2970 }, {2972, 2972 }, {2974, 2975 }, {2979, 2980 }, {2984, 2986 }, {2990, 3001 }, {3024, 3024 }, {3077, 3084 }, {3086, 3088 }, {3090, 3112 }, {3114, 3129 }, {3133, 3133 }, {3160, 3162 }, {3165, 3165 }, {3168, 3169 }, {3200, 3200 }, {3205, 3212 }, {3214, 3216 }, {3218, 3240 }, {3242, 3251 }, {3253, 3257 }, {3261, 3261 }, {3293, 3294 }, {3296, 3297 }, {3313, 3314 }, {3332, 3340 }, {3342, 3344 }, {3346, 3386 }, {3389, 3389 }, {3406, 3406 }, {3412, 3414 }, {3423, 3425 }, {3450, 3455 }, {3461, 3478 }, {3482, 3505 }, {3507, 3515 }, {3517, 3517 }, {3520, 3526 }, {3585, 3632 }, {3634, 3635 }, {3648, 3653 }, {3713, 3714 }, {3716, 3716 }, {3718, 3722 }, {3724, 3747 }, {3749, 3749 }, {3751, 3760 }, {3762, 3763 }, {3773, 3773 }, {3776, 3780 }, {3804, 3807 }, {3840, 3840 }, {3904, 3911 }, {3913, 3948 }, {3976, 3980 }, {4096, 4138 }, {4159, 4159 }, {4176, 4181 }, {4186, 4189 }, {4193, 4193 }, {4197, 4198 }, {4206, 4208 }, {4213, 4225 }, {4238, 4238 }, {4352, 4680 }, {4682, 4685 }, {4688, 4694 }, {4696, 4696 }, {4698, 4701 }, {4704, 4744 }, {4746, 4749 }, {4752, 4784 }, {4786, 4789 }, {4792, 4798 }, {4800, 4800 }, {4802, 4805 }, {4808, 4822 }, {4824, 4880 }, {4882, 4885 }, {4888, 4954 }, {4992, 5007 }, {5121, 5740 }, {5743, 5759 }, {5761, 5786 }, {5792, 5866 }, {5873, 5880 }, {5888, 5905 }, {5919, 5937 }, {5952, 5969 }, {5984, 5996 }, {5998, 6000 }, {6016, 6067 }, {6108, 6108 }, {6176, 6210 }, {6212, 6264 }, {6272, 6276 }, {6279, 6312 }, {6314, 6314 }, {6320, 6389 }, {6400, 6430 }, {6480, 6509 }, {6512, 6516 }, {6528, 6571 }, {6576, 6601 }, {6656, 6678 }, {6688, 6740 }, {6917, 6963 }, {6981, 6988 }, {7043, 7072 }, {7086, 7087 }, {7098, 7141 }, {7168, 7203 }, {7245, 7247 }, {7258, 7287 }, {7401, 7404 }, {7406, 7411 }, {7413, 7414 }, {7418, 7418 }, {8501, 8504 }, {11568, 11623 }, {11648, 11670 }, {11680, 11686 }, {11688, 11694 }, {11696, 11702 }, {11704, 11710 }, {11712, 11718 }, {11720, 11726 }, {11728, 11734 }, {11736, 11742 }, {12294, 12294 }, {12348, 12348 }, {12353, 12438 }, {12447, 12447 }, {12449, 12538 }, {12543, 12543 }, {12549, 12591 }, {12593, 12686 }, {12704, 12735 }, {12784, 12799 }, {13312, 19903 }, {19968, 40980 }, {40982, 42124 }, {42192, 42231 }, {42240, 42507 }, {42512, 42527 }, {42538, 42539 }, {42606, 42606 }, {42656, 42725 }, {42895, 42895 }, {42999, 42999 }, {43003, 43009 }, {43011, 43013 }, {43015, 43018 }, {43020, 43042 }, {43072, 43123 }, {43138, 43187 }, {43250, 43255 }, {43259, 43259 }, {43261, 43262 }, {43274, 43301 }, {43312, 43334 }, {43360, 43388 }, {43396, 43442 }, {43488, 43492 }, {43495, 43503 }, {43514, 43518 }, {43520, 43560 }, {43584, 43586 }, {43588, 43595 }, {43616, 43631 }, {43633, 43638 }, {43642, 43642 }, {43646, 43695 }, {43697, 43697 }, {43701, 43702 }, {43705, 43709 }, {43712, 43712 }, {43714, 43714 }, {43739, 43740 }, {43744, 43754 }, {43762, 43762 }, {43777, 43782 }, {43785, 43790 }, {43793, 43798 }, {43808, 43814 }, {43816, 43822 }, {43968, 44002 }, {44032, 55203 }, {55216, 55238 }, {55243, 55291 }, {63744, 64109 }, {64112, 64217 }, {64285, 64285 }, {64287, 64296 }, {64298, 64310 }, {64312, 64316 }, {64318, 64318 }, {64320, 64321 }, {64323, 64324 }, {64326, 64433 }, {64467, 64829 }, {64848, 64911 }, {64914, 64967 }, {65008, 65019 }, {65136, 65140 }, {65142, 65276 }, {65382, 65391 }, {65393, 65437 }, {65440, 65470 }, {65474, 65479 }, {65482, 65487 }, {65490, 65495 }, {65498, 65500 }, {65536, 65547 }, {65549, 65574 }, {65576, 65594 }, {65596, 65597 }, {65599, 65613 }, {65616, 65629 }, {65664, 65786 }, {66176, 66204 }, {66208, 66256 }, {66304, 66335 }, {66349, 66368 }, {66370, 66377 }, {66384, 66421 }, {66432, 66461 }, {66464, 66499 }, {66504, 66511 }, {66640, 66717 }, {66816, 66855 }, {66864, 66915 }, {67072, 67382 }, {67392, 67413 }, {67424, 67431 }, {67584, 67589 }, {67592, 67592 }, {67594, 67637 }, {67639, 67640 }, {67644, 67644 }, {67647, 67669 }, {67680, 67702 }, {67712, 67742 }, {67808, 67826 }, {67828, 67829 }, {67840, 67861 }, {67872, 67897 }, {67968, 68023 }, {68030, 68031 }, {68096, 68096 }, {68112, 68115 }, {68117, 68119 }, {68121, 68149 }, {68192, 68220 }, {68224, 68252 }, {68288, 68295 }, {68297, 68324 }, {68352, 68405 }, {68416, 68437 }, {68448, 68466 }, {68480, 68497 }, {68608, 68680 }, {68864, 68899 }, {69248, 69289 }, {69296, 69297 }, {69376, 69404 }, {69415, 69415 }, {69424, 69445 }, {69488, 69505 }, {69552, 69572 }, {69600, 69622 }, {69635, 69687 }, {69745, 69746 }, {69749, 69749 }, {69763, 69807 }, {69840, 69864 }, {69891, 69926 }, {69956, 69956 }, {69959, 69959 }, {69968, 70002 }, {70006, 70006 }, {70019, 70066 }, {70081, 70084 }, {70106, 70106 }, {70108, 70108 }, {70144, 70161 }, {70163, 70187 }, {70272, 70278 }, {70280, 70280 }, {70282, 70285 }, {70287, 70301 }, {70303, 70312 }, {70320, 70366 }, {70405, 70412 }, {70415, 70416 }, {70419, 70440 }, {70442, 70448 }, {70450, 70451 }, {70453, 70457 }, {70461, 70461 }, {70480, 70480 }, {70493, 70497 }, {70656, 70708 }, {70727, 70730 }, {70751, 70753 }, {70784, 70831 }, {70852, 70853 }, {70855, 70855 }, {71040, 71086 }, {71128, 71131 }, {71168, 71215 }, {71236, 71236 }, {71296, 71338 }, {71352, 71352 }, {71424, 71450 }, {71488, 71494 }, {71680, 71723 }, {71935, 71942 }, {71945, 71945 }, {71948, 71955 }, {71957, 71958 }, {71960, 71983 }, {71999, 71999 }, {72001, 72001 }, {72096, 72103 }, {72106, 72144 }, {72161, 72161 }, {72163, 72163 }, {72192, 72192 }, {72203, 72242 }, {72250, 72250 }, {72272, 72272 }, {72284, 72329 }, {72349, 72349 }, {72368, 72440 }, {72704, 72712 }, {72714, 72750 }, {72768, 72768 }, {72818, 72847 }, {72960, 72966 }, {72968, 72969 }, {72971, 73008 }, {73030, 73030 }, {73056, 73061 }, {73063, 73064 }, {73066, 73097 }, {73112, 73112 }, {73440, 73458 }, {73648, 73648 }, {73728, 74649 }, {74880, 75075 }, {77712, 77808 }, {77824, 78894 }, {82944, 83526 }, {92160, 92728 }, {92736, 92766 }, {92784, 92862 }, {92880, 92909 }, {92928, 92975 }, {93027, 93047 }, {93053, 93071 }, {93952, 94026 }, {94032, 94032 }, {94208, 100343}, {100352, 101589}, {101632, 101640}, {110592, 110882}, {110928, 110930}, {110948, 110951}, {110960, 111355}, {113664, 113770}, {113776, 113788}, {113792, 113800}, {113808, 113817}, {122634, 122634}, {123136, 123180}, {123214, 123214}, {123536, 123565}, {123584, 123627}, {124896, 124902}, {124904, 124907}, {124909, 124910}, {124912, 124926}, {124928, 125124}, {126464, 126467}, {126469, 126495}, {126497, 126498}, {126500, 126500}, {126503, 126503}, {126505, 126514}, {126516, 126519}, {126521, 126521}, {126523, 126523}, {126530, 126530}, {126535, 126535}, {126537, 126537}, {126539, 126539}, {126541, 126543}, {126545, 126546}, {126548, 126548}, {126551, 126551}, {126553, 126553}, {126555, 126555}, {126557, 126557}, {126559, 126559}, {126561, 126562}, {126564, 126564}, {126567, 126570}, {126572, 126578}, {126580, 126583}, {126585, 126588}, {126590, 126590}, {126592, 126601}, {126603, 126619}, {126625, 126627}, {126629, 126633}, {126635, 126651}, {131072, 173791}, {173824, 177976}, {177984, 178205}, {178208, 183969}, {183984, 191456}, {194560, 195101}, {196608, 201546}, }; bool c11__is_unicode_Lo_char(int c) { if(c == 0x1f955) return true; const char* data = c11__search_u32_ranges(c, kLoRanges, sizeof(kLoRanges) / sizeof(c11_u32_range)); return data != NULL; }