From 8637db490602e54e0307c1a9eafc704480a80fbb Mon Sep 17 00:00:00 2001 From: Uzair Nawaz Date: Thu, 26 Jun 2025 17:53:09 +0000 Subject: [PATCH] Refactored internal wcrtomb --- libc/src/__support/wchar/wcrtomb.cpp | 16 +++++----------- libc/src/__support/wchar/wcrtomb.h | 7 ++++++- libc/src/wchar/wcrtomb.cpp | 8 ++++---- libc/src/wchar/wctomb.cpp | 5 +++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libc/src/__support/wchar/wcrtomb.cpp b/libc/src/__support/wchar/wcrtomb.cpp index a74a6f3ec34a6..4a365c84c605c 100644 --- a/libc/src/__support/wchar/wcrtomb.cpp +++ b/libc/src/__support/wchar/wcrtomb.cpp @@ -21,32 +21,26 @@ namespace LIBC_NAMESPACE_DECL { namespace internal { -ErrorOr wcrtomb(char *__restrict s, wchar_t wc, - mbstate *__restrict ps) { +ErrorOr wcrtomb(wchar_t wc, mbstate *ps) { static_assert(sizeof(wchar_t) == 4); + wcrtomb_result out; CharacterConverter cr(ps); if (!cr.isValidState()) return Error(EINVAL); - if (s == nullptr) - return Error(EILSEQ); - int status = cr.push(static_cast(wc)); if (status != 0) return Error(EILSEQ); - size_t count = 0; while (!cr.isEmpty()) { auto utf8 = cr.pop_utf8(); // can never fail as long as the push succeeded LIBC_ASSERT(utf8.has_value()); - - *s = utf8.value(); - s++; - count++; + out.mbs[out.count++] = utf8.value(); } - return count; + + return out; } } // namespace internal diff --git a/libc/src/__support/wchar/wcrtomb.h b/libc/src/__support/wchar/wcrtomb.h index bcd39a92a3b76..b255fd41d6cc9 100644 --- a/libc/src/__support/wchar/wcrtomb.h +++ b/libc/src/__support/wchar/wcrtomb.h @@ -18,7 +18,12 @@ namespace LIBC_NAMESPACE_DECL { namespace internal { -ErrorOr wcrtomb(char *__restrict s, wchar_t wc, mbstate *__restrict ps); +struct wcrtomb_result { + char mbs[4]; + size_t count = 0; +}; + +ErrorOr wcrtomb(wchar_t wc, mbstate* ps); } // namespace internal } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/wcrtomb.cpp b/libc/src/wchar/wcrtomb.cpp index 3e9df0599431e..119aa0da8344e 100644 --- a/libc/src/wchar/wcrtomb.cpp +++ b/libc/src/wchar/wcrtomb.cpp @@ -30,16 +30,16 @@ LLVM_LIBC_FUNCTION(size_t, wcrtomb, } auto result = internal::wcrtomb( - s, wc, - ps == nullptr ? &internal_mbstate - : reinterpret_cast(ps)); + wc, ps == nullptr ? &internal_mbstate + : reinterpret_cast(ps)); if (!result.has_value()) { libc_errno = result.error(); return -1; } - return result.value(); + __builtin_memcpy(s, result.value().mbs, result.value().count); + return result.value().count; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/wctomb.cpp b/libc/src/wchar/wctomb.cpp index 142302e6ae09b..7dbb5347df5da 100644 --- a/libc/src/wchar/wctomb.cpp +++ b/libc/src/wchar/wctomb.cpp @@ -22,14 +22,15 @@ LLVM_LIBC_FUNCTION(int, wctomb, (char *s, wchar_t wc)) { if (s == nullptr) return 0; - auto result = internal::wcrtomb(s, wc, &internal_mbstate); + auto result = internal::wcrtomb(wc, &internal_mbstate); if (!result.has_value()) { // invalid wide character libc_errno = EILSEQ; return -1; } - return static_cast(result.value()); + __builtin_memcpy(s, result.value().mbs, result.value().count); + return static_cast(result.value().count); } } // namespace LIBC_NAMESPACE_DECL