Merge pull request #4095 from yunusshaikh7/fix/libc-towctrans-descriptors

fix(libc): map _Towctrans descriptors 1 and 2 to lower and upper case
This commit is contained in:
Dean 2026-10-12 21:40:02 +13:00 committed by GitHub
commit 375e99ec33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 3 deletions

View File

@ -4,7 +4,7 @@
#include <cstdio>
#include <cstdint>
#include <cwchar>
#include <cwctype>
#include <cerrno>
#include <ios>
#include <locale>
#include <mutex>
@ -323,8 +323,15 @@ mbstate_t* APS5_VABI _Getpwcstate_nid_postfix() {
return &state;
}
wint_t APS5_VABI _Towctrans_nid_postfix(wint_t c, wctrans_t desc) {
return std::towctrans(c, desc);
std::uint32_t APS5_VABI _Towctrans_nid_postfix(std::uint32_t c, std::uint64_t desc) {
constexpr std::uint64_t ToLower = 1;
constexpr std::uint64_t ToUpper = 2;
if (desc != ToLower && desc != ToUpper) {
errno = 22;
return c;
}
if (c > UCHAR_MAX) return c;
return static_cast<std::uint32_t>((desc == ToLower ? g_lowerTable : g_upperTable)[c + 1]);
}
// Locale ids and stream objects the title imports besides the ones above; the streams are zeroed

View File

@ -1,5 +1,6 @@
#include "prx/libc/include/GuestLocale.hpp"
#include <array>
#include <cstdint>
#include <cstring>
#include <cwchar>
#include <climits>
@ -23,6 +24,8 @@ int APS5_VABI _Mbtowcx_nid_postfix(std::uint16_t* dst, const char* src, std::siz
int APS5_VABI _Wctombx_nid_postfix(char* dst, std::uint16_t src, std::mbstate_t* st);
void APS5_VABI _Locksyslock_nid_postfix();
void APS5_VABI _Unlocksyslock_nid_postfix();
std::uint32_t APS5_VABI _Towctrans_nid_postfix(std::uint32_t wc, std::uint64_t desc);
int* APS5_VABI __error_nid_postfix();
}
@ -144,12 +147,35 @@ static void CheckStreamDestruction() {
Require(object.stream.locale == &_ZSt21_sceLibcClassicLocale_nid_postfix);
}
static void CheckWideCaseTranslation() {
const auto* lower = _Getptolower_nid_postfix();
const auto* upper = _Getptoupper_nid_postfix();
Require(_Towctrans_nid_postfix(u'A', 1) == u'a' && _Towctrans_nid_postfix(u'a', 2) == u'A');
*__error_nid_postfix() = 0;
for (std::uint32_t value = 0; value < 256; ++value) {
Require(_Towctrans_nid_postfix(value, 1) == static_cast<std::uint32_t>(lower[value]));
Require(_Towctrans_nid_postfix(value, 2) == static_cast<std::uint32_t>(upper[value]));
}
const std::uint32_t uncased[] = {0x100u, 0x391u, 0x3b1u, 0xffffu, 0xffffffffu};
for (const std::uint32_t value : uncased) {
Require(_Towctrans_nid_postfix(value, 1) == value && _Towctrans_nid_postfix(value, 2) == value);
}
Require(*__error_nid_postfix() == 0);
const std::uint64_t invalidDescriptors[] = {0, 3};
for (const std::uint64_t descriptor : invalidDescriptors) {
*__error_nid_postfix() = 0;
Require(_Towctrans_nid_postfix(u'A', descriptor) == u'A' && _Towctrans_nid_postfix(u'7', descriptor) == u'7');
Require(*__error_nid_postfix() == 22);
}
}
int main() {
CheckGuestCalls();
CheckLocinfoAlignment();
CheckCharacterTables();
CheckCharacterConversions();
CheckStreamDestruction();
CheckWideCaseTranslation();
_Locksyslock_nid_postfix();
_Locksyslock_nid_postfix();
_Unlocksyslock_nid_postfix();