[libc-commits] [libc] [libc] Refactored internal wcrtomb (PR #145945)
Uzair Nawaz via libc-commits
libc-commits at lists.llvm.org
Thu Jun 26 10:55:26 PDT 2025
https://github.com/uzairnawaz created https://github.com/llvm/llvm-project/pull/145945
Removed output parameters for internal::wcrtomb and instead returned a struct containing the result of the conversion.
>From 8637db490602e54e0307c1a9eafc704480a80fbb Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
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<size_t> wcrtomb(char *__restrict s, wchar_t wc,
- mbstate *__restrict ps) {
+ErrorOr<wcrtomb_result> 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<char32_t>(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<size_t> wcrtomb(char *__restrict s, wchar_t wc, mbstate *__restrict ps);
+struct wcrtomb_result {
+ char mbs[4];
+ size_t count = 0;
+};
+
+ErrorOr<wcrtomb_result> 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<internal::mbstate *>(ps));
+ wc, ps == nullptr ? &internal_mbstate
+ : reinterpret_cast<internal::mbstate *>(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<int>(result.value());
+ __builtin_memcpy(s, result.value().mbs, result.value().count);
+ return static_cast<int>(result.value().count);
}
} // namespace LIBC_NAMESPACE_DECL
More information about the libc-commits
mailing list