diff options
| author | Saikari <[email protected]> | 2026-01-17 05:07:46 +0300 |
|---|---|---|
| committer | Saikari <[email protected]> | 2026-01-17 05:07:46 +0300 |
| commit | bd366e385b14cd0a3942918830c63b6f0760f4a8 (patch) | |
| tree | 766496b8dc573c020fd720553f0721169f92bed4 | |
| parent | 501ca613b96d0dde01b4f77bbf61dca1a58f64aa (diff) | |
try use utf8proc
| -rw-r--r-- | core/src/xmake/string/case.c | 104 | ||||
| -rw-r--r-- | core/src/xmake/xmake.lua | 2 | ||||
| -rw-r--r-- | core/xmake.lua | 2 |
3 files changed, 22 insertions, 86 deletions
diff --git a/core/src/xmake/string/case.c b/core/src/xmake/string/case.c index d87b3e9a7..d83aa1731 100644 --- a/core/src/xmake/string/case.c +++ b/core/src/xmake/string/case.c @@ -31,13 +31,7 @@ #include "prefix.h" #include "../utils/charset.h" #include <wctype.h> -#if defined(TB_CONFIG_OS_WINDOWS) -# include <windows.h> -#endif -#if defined(TB_CONFIG_OS_MACOSX) || defined(TB_CONFIG_OS_IOS) -# include <CoreFoundation/CoreFoundation.h> -#endif -#include "tbox/libc/stdlib/setlocale.h" +#include <utf8proc.h> /* ////////////////////////////////////////////////////////////////////////////////////// * helper @@ -47,9 +41,6 @@ static tb_int_t xm_string_case(lua_State* lua, tb_bool_t lower) { // check tb_assert_and_check_return_val(lua, 0); - // init locale - tb_setlocale(); - // get the string size_t size = 0; tb_char_t const* str = luaL_checklstring(lua, 1, &size); @@ -61,91 +52,32 @@ static tb_int_t xm_string_case(lua_State* lua, tb_bool_t lower) { return 1; } -#if defined(TB_CONFIG_OS_MACOSX) || defined(TB_CONFIG_OS_IOS) - CFStringRef cf_str = CFStringCreateWithBytes(kCFAllocatorDefault, (tb_byte_t const*)str, size, kCFStringEncodingUTF8, false); - if (cf_str) { - CFMutableStringRef cf_mutable = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, cf_str); - CFRelease(cf_str); - if (cf_mutable) { - if (lower) CFStringLowercase(cf_mutable, NULL); - else CFStringUppercase(cf_mutable, NULL); - - CFIndex len = CFStringGetLength(cf_mutable); - CFIndex max_size = CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8) + 1; - tb_char_t* buffer = tb_malloc_bytes(max_size); - if (buffer) { - if (CFStringGetCString(cf_mutable, buffer, max_size, kCFStringEncodingUTF8)) { - lua_pushstring(lua, buffer); - } else { - lua_pushnil(lua); - } - tb_free(buffer); - } else { - lua_pushnil(lua); - } - CFRelease(cf_mutable); - return 1; - } - } -#endif - - // find charsets - xm_charset_entry_ref_t fcharset = xm_charset_find_by_name("utf8"); -#if defined(TB_CONFIG_OS_WINDOWS) - xm_charset_entry_ref_t tcharset = xm_charset_find_by_name("utf16"); -#else - xm_charset_entry_ref_t tcharset = xm_charset_find_by_name("utf32"); -#endif - tb_check_return_val(fcharset && tcharset, 0); - // convert string - tb_long_t dst_size = 0; tb_size_t dst_maxn = (tb_size_t)(size + 1) * 4; tb_byte_t* dst_data = tb_malloc_bytes(dst_maxn); - if (dst_data && dst_maxn && - (dst_size = tb_charset_conv_data(fcharset->type, tcharset->type, (tb_byte_t const*)str, (tb_size_t)size, dst_data, dst_maxn)) >= 0 && - dst_size < dst_maxn) { - - // to lower/upper -#if defined(TB_CONFIG_OS_WINDOWS) - if (lower) CharLowerBuffW((LPWSTR)dst_data, (DWORD)(dst_size / 2)); - else CharUpperBuffW((LPWSTR)dst_data, (DWORD)(dst_size / 2)); -#else - tb_uint32_t* p = (tb_uint32_t*)dst_data; - tb_size_t n = (tb_size_t)dst_size / 4; - while (n--) { - if (*p < 0x2000) { - if (lower) { - if (iswupper((wint_t)*p)) - *p = towlower((wint_t)*p); - } else { - if (iswlower((wint_t)*p)) - *p = towupper((wint_t)*p); - } + if (dst_data) { + tb_byte_t* p = dst_data; + tb_byte_t const* s = (tb_byte_t const*)str; + tb_byte_t const* e = s + size; + while (s < e) { + utf8proc_int32_t codepoint; + utf8proc_ssize_t len = utf8proc_iterate((utf8proc_uint8_t const*)s, e - s, &codepoint); + if (len > 0) { + if (lower) codepoint = utf8proc_tolower(codepoint); + else codepoint = utf8proc_toupper(codepoint); + utf8proc_ssize_t wlen = utf8proc_encode_char(codepoint, (utf8proc_uint8_t*)p); + if (wlen > 0) p += wlen; + s += len; + } else { + *p++ = *s++; } - p++; } -#endif - - // convert string back - tb_long_t res_size = 0; - tb_size_t res_maxn = dst_maxn * 2; - tb_byte_t* res_data = tb_malloc_bytes(res_maxn); - if (res_data && res_maxn && - (res_size = tb_charset_conv_data(tcharset->type, fcharset->type, dst_data, (tb_size_t)dst_size, res_data, res_maxn)) >= 0 && - res_size < res_maxn) { - lua_pushlstring(lua, (tb_char_t const*)res_data, res_size); - } else { - lua_pushnil(lua); - } - if (res_data) tb_free(res_data); + lua_pushlstring(lua, (tb_char_t const*)dst_data, p - dst_data); + tb_free(dst_data); } else { lua_pushnil(lua); } - // free data - if (dst_data) tb_free(dst_data); - // ok return 1; } diff --git a/core/src/xmake/xmake.lua b/core/src/xmake/xmake.lua index 90f761b30..0c2e15991 100644 --- a/core/src/xmake/xmake.lua +++ b/core/src/xmake/xmake.lua @@ -20,6 +20,8 @@ target("xmake") add_deps("pdcurses") end + add_packages("utf8proc") + -- add definitions add_defines("__tb_prefix__=\"xmake\"") if is_mode("debug") then diff --git a/core/xmake.lua b/core/xmake.lua index 7b1ae6cbd..e160d000f 100644 --- a/core/xmake.lua +++ b/core/xmake.lua @@ -59,6 +59,8 @@ end -- use cosmocc toolchain option("cosmocc", {default = false, description = "Use cosmocc toolchain to build once and run anywhere."}) +add_requires("utf8proc") + -- embed all script files option("embed", {default = false, description = "Embed all script files."}) |
