From 24f78f57cc6148c8a8dcb14fb27de3fb20918347 Mon Sep 17 00:00:00 2001 From: boykopovar Date: Sat, 22 Aug 2026 16:50:55 +0300 Subject: [PATCH] feat(libs): implement missing locale and mbstate stubs for libc --- core/libs/prx/libc/src/LocaleSupport.cpp | 143 ++++++++++++++++------- 1 file changed, 101 insertions(+), 42 deletions(-) diff --git a/core/libs/prx/libc/src/LocaleSupport.cpp b/core/libs/prx/libc/src/LocaleSupport.cpp index 8fbaec5f3..c0a4511e7 100644 --- a/core/libs/prx/libc/src/LocaleSupport.cpp +++ b/core/libs/prx/libc/src/LocaleSupport.cpp @@ -1,72 +1,131 @@ #include #include +#include +#include #include #include #include namespace { - std::mutex g_localeInitMutex; - bool g_localeInitialized = false; +std::mutex g_localeInitMutex; +bool g_localeInitialized = false; - constexpr std::size_t LocinfoStorageSize = 64; +constexpr std::size_t LocinfoStorageSize = 64; - struct LocinfoStorage { - alignas(std::max_align_t) unsigned char bytes[LocinfoStorageSize]; - }; +struct LocinfoStorage { + alignas(std::max_align_t) unsigned char bytes[LocinfoStorageSize]; +}; + +const std::locale& ClassicLocaleInstance() { + static const std::locale instance = std::locale::classic(); + return instance; +} } extern "C" { - std::streamoff _ZSt7_BADOFF_nid_postfix = -1; - std::fpos_t _ZSt4_Fpz_nid_postfix {}; - long _ZNSt6locale2id7_Id_cntE_nid_postfix = 0; +std::streamoff _ZSt7_BADOFF_nid_postfix = -1; +std::fpos_t _ZSt4_Fpz_nid_postfix {}; +long _ZNSt6locale2id7_Id_cntE_nid_postfix = 0; +const std::locale* _ZSt21_sceLibcClassicLocale_nid_postfix = &ClassicLocaleInstance(); + +void _ZNSt6locale5_InitEv_nid_postfix() { + std::lock_guard lock(g_localeInitMutex); + if (!g_localeInitialized) { + ClassicLocaleInstance(); + g_localeInitialized = true; + } } -namespace { - - const std::locale& ClassicLocaleInstance() { - static const std::locale instance = std::locale::classic(); - return instance; - } - +void _ZNSt6locale5facet9_RegisterEv_nid_postfix() { } -extern "C" { +const std::locale* _ZNSt6locale16_GetgloballocaleEv_nid_postfix() { + return &ClassicLocaleInstance(); +} - const std::locale* _ZSt21_sceLibcClassicLocale_nid_postfix = &ClassicLocaleInstance(); +void _ZNSt7collateIwE7_GetcatEPPKNSt6locale5facetEPKS1__nid_postfix( + const std::locale::facet** targetFacet, const std::locale* sourceLocale +) { + const std::locale& effectiveLocale = sourceLocale != nullptr ? *sourceLocale : ClassicLocaleInstance(); + *targetFacet = &std::use_facet>(effectiveLocale); +} - void _ZNSt6locale5_InitEv_nid_postfix() { - std::lock_guard lock(g_localeInitMutex); - if (!g_localeInitialized) { - ClassicLocaleInstance(); - g_localeInitialized = true; - } +void _ZNSt8_LocinfoC1EPKc_nid_postfix(LocinfoStorage* self, const char* localeName) { + (void)localeName; + new (self) LocinfoStorage {}; +} + +void _ZNSt8_LocinfoD1Ev_nid_postfix(LocinfoStorage* self) { + (void)self; +} + +wchar_t* _Mbtowcx_nid_postfix(wchar_t* dst, const char* src, std::size_t count, mbstate_t* st) { + while (count > 0) { + std::size_t result = std::mbrtowc(dst, src, count, st); + if (result == static_cast(-1) || result == static_cast(-2)) + return nullptr; + if (result == 0) + return dst; + src += result; + count -= result; + ++dst; } + return dst; +} - void _ZNSt6locale5facet9_RegisterEv_nid_postfix() { - } +char* _Wctombx_nid_postfix(char* dst, wchar_t src, mbstate_t* st) { + std::size_t result = std::wcrtomb(dst, src, st); + if (result == static_cast(-1)) + return nullptr; + return dst + result; +} - const std::locale* _ZNSt6locale16_GetgloballocaleEv_nid_postfix() { - return &ClassicLocaleInstance(); - } +const short* _Getpctype_nid_postfix() { + const auto& facet = std::use_facet>(ClassicLocaleInstance()); + return reinterpret_cast(facet.table()); +} - void _ZNSt7collateIwE7_GetcatEPPKNSt6locale5facetEPKS1__nid_postfix( - const std::locale::facet** targetFacet, const std::locale* sourceLocale - ) { - const std::locale& effectiveLocale = sourceLocale != nullptr ? *sourceLocale : ClassicLocaleInstance(); - *targetFacet = &std::use_facet>(effectiveLocale); - } +const short* _Getptolower_nid_postfix() { + static short table[std::ctype::table_size]; + static std::once_flag flag; + std::call_once(flag, []() { + const auto& facet = std::use_facet>(ClassicLocaleInstance()); + for (int i = 0; i < std::ctype::table_size; ++i) + table[i] = static_cast(facet.tolower(static_cast(i))); + }); + return table; +} - void _ZNSt8_LocinfoC1EPKc_nid_postfix(LocinfoStorage* self, const char* localeName) { - (void)localeName; - new (self) LocinfoStorage {}; - } +const short* _Getptoupper_nid_postfix() { + static short table[std::ctype::table_size]; + static std::once_flag flag; + std::call_once(flag, []() { + const auto& facet = std::use_facet>(ClassicLocaleInstance()); + for (int i = 0; i < std::ctype::table_size; ++i) + table[i] = static_cast(facet.toupper(static_cast(i))); + }); + return table; +} - void _ZNSt8_LocinfoD1Ev_nid_postfix(LocinfoStorage* self) { - (void)self; - } +mbstate_t* _Getpmbstate_nid_postfix() { + thread_local mbstate_t state {}; + return &state; +} + +mbstate_t* _Getpwcstate_nid_postfix() { + thread_local mbstate_t state {}; + return &state; +} + +wint_t _Towctrans_nid_postfix(wint_t c, wctrans_t desc) { + return std::towctrans(c, desc); +} + +void _init_env_nid_postfix() { +} }