diff options
| author | Saikari <[email protected]> | 2026-01-17 19:38:05 +0300 |
|---|---|---|
| committer | Saikari <[email protected]> | 2026-01-17 19:38:05 +0300 |
| commit | 33bc0b8128a019a019378a08f789f8062b320fa1 (patch) | |
| tree | 2a36d409dc0e4726eb101054c0c3ea764a0d0d5e /core/src | |
| parent | e075b6cd6c49b28cd595f7f0db8907c27fb0ef28 (diff) | |
fixup
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/string/case.c | 116 |
1 files changed, 54 insertions, 62 deletions
diff --git a/core/src/xmake/string/case.c b/core/src/xmake/string/case.c index 0bdef51a3..3bbee07b6 100644 --- a/core/src/xmake/string/case.c +++ b/core/src/xmake/string/case.c @@ -30,31 +30,34 @@ */ #include "prefix.h" #include <ctype.h> -/* Include Tbox platform header for spinlocks */ +#include <wctype.h> #include "tbox/platform/spinlock.h" -#ifdef TB_CONFIG_OS_WINDOWS -# include <windows.h> -#else -# include <wctype.h> -# include <locale.h> -# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) -# include <xlocale.h> -# elif defined(__NetBSD__) -# include <string.h> +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) +# include <xlocale.h> +#endif + +/* ////////////////////////////////////////////////////////////////////////////////////// + * macros + */ + +/* Platforms that lack thread-safe uselocale() and must use setlocale() */ +#if defined(TB_CONFIG_OS_WINDOWS) || defined(__NetBSD__) +# include "tbox/libc/stdlib/setlocale.h" +# define XM_USE_SETLOCALE +#endif + /* ////////////////////////////////////////////////////////////////////////////////////// * globals */ -/* - * Define a static Tbox spinlock. - * setlocale() is not thread-safe on Windows or Linux, so we protect it globally. +#ifdef XM_USE_SETLOCALE +/* + * setlocale() is not thread-safe, so we protect it with a spinlock. */ static tb_spinlock_t g_locale_lock = TB_SPINLOCK_INIT; -# endif #endif - /* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ @@ -84,9 +87,9 @@ static tb_bool_t xm_string_case_ascii(lua_State* lua, tb_char_t const* str, tb_s for (i = 0; i < size; i++) { tb_byte_t c = (tb_byte_t)str[i]; if (lower) { - buf[i] = (tb_char_t)(isupper(c)? tolower(c) : c); + buf[i] = (tb_char_t)(isupper(c) ? tolower(c) : c); } else { - buf[i] = (tb_char_t)(islower(c)? toupper(c) : c); + buf[i] = (tb_char_t)(islower(c) ? toupper(c) : c); } } @@ -95,6 +98,20 @@ static tb_bool_t xm_string_case_ascii(lua_State* lua, tb_char_t const* str, tb_s return tb_true; } +/* Perform wide character case conversion in-place + */ +static tb_void_t xm_wchar_convert_case(tb_wchar_t* wb, tb_size_t wn, tb_bool_t lower) { + tb_size_t i; + for (i = 0; i < wn; i++) { + tb_wchar_t wc = wb[i]; + if (lower) { + if (!iswlower(wc)) wb[i] = towlower(wc); + } else { + if (!iswupper(wc)) wb[i] = towupper(wc); + } + } +} + /* Unicode case conversion using wide characters * Returns tb_true on success, tb_false on failure */ @@ -115,58 +132,38 @@ static tb_bool_t xm_string_case_unicode(lua_State* lua, tb_char_t const* str, tb } // Perform Case Conversion - tb_size_t i; -#ifdef TB_CONFIG_OS_WINDOWS - // Windows Implementation - for (i = 0; i < wn; i++) { - tb_wchar_t wc = wb[i]; - if (lower) { - if (!IsCharLowerW(wc)) { - CharLowerBuffW(&wb[i], 1); - } - } else { - if (!IsCharUpperW(wc)) { - CharUpperBuffW(&wb[i], 1); - } - } - } -#else -# if defined(__NetBSD__) - // NetBSD lacks of uselocale +#ifdef XM_USE_SETLOCALE + // Windows and NetBSD: Use setlocale (protected by spinlock) tb_spinlock_enter(&g_locale_lock); - char* saved_locale = tb_null; - char* current_locale = setlocale(LC_CTYPE, NULL); - + // Save current locale + char* saved_locale = tb_null; + char const* current_locale = setlocale(LC_CTYPE, tb_null); + if (current_locale) { - size_t len = tb_strlen(current_locale); + tb_size_t len = tb_strlen(current_locale); saved_locale = (char*)tb_malloc_bytes(len + 1); if (saved_locale) { tb_memcpy(saved_locale, current_locale, len + 1); } } - if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) { - setlocale(LC_CTYPE, "UTF-8"); - } + // Force UTF-8 locale + tb_setlocale(); - for (i = 0; i < wn; i++) { - tb_wchar_t wc = wb[i]; - if (lower) { - if (!iswlower(wc)) wb[i] = towlower(wc); - } else { - if (!iswupper(wc)) wb[i] = towupper(wc); - } - } + // Convert case + xm_wchar_convert_case(wb, wn, lower); + // Restore original locale if (saved_locale) { setlocale(LC_CTYPE, saved_locale); tb_free(saved_locale); } - + tb_spinlock_leave(&g_locale_lock); -# else - // POSIX Thread-Safe Implementation + +#else + // POSIX Thread-Safe Implementation (Linux/macOS/FreeBSD/DragonFly) locale_t new_loc = newlocale(LC_CTYPE_MASK, "en_US.UTF-8", (locale_t)0); if (!new_loc) { new_loc = newlocale(LC_CTYPE_MASK, "UTF-8", (locale_t)0); @@ -174,18 +171,13 @@ static tb_bool_t xm_string_case_unicode(lua_State* lua, tb_char_t const* str, tb if (new_loc) { locale_t old_loc = uselocale(new_loc); - for (i = 0; i < wn; i++) { - tb_wchar_t wc = wb[i]; - if (lower) { - if (!iswlower(wc)) wb[i] = towlower(wc); - } else { - if (!iswupper(wc)) wb[i] = towupper(wc); - } - } + xm_wchar_convert_case(wb, wn, lower); uselocale(old_loc); freelocale(new_loc); + } else { + // Fallback: try without locale change + xm_wchar_convert_case(wb, wn, lower); } -# endif #endif // Convert Wide Char back to UTF-8 |
