[libc-commits] [libc] [libc] Refactored internal wcrtomb (PR #145945)
via libc-commits
libc-commits at lists.llvm.org
Thu Jun 26 10:55:54 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Uzair Nawaz (uzairnawaz)
<details>
<summary>Changes</summary>
Removed output parameters for internal::wcrtomb and instead returned a struct containing the result of the conversion.
---
Full diff: https://github.com/llvm/llvm-project/pull/145945.diff
4 Files Affected:
- (modified) libc/src/__support/wchar/wcrtomb.cpp (+5-11)
- (modified) libc/src/__support/wchar/wcrtomb.h (+6-1)
- (modified) libc/src/wchar/wcrtomb.cpp (+4-4)
- (modified) libc/src/wchar/wctomb.cpp (+3-2)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/145945
More information about the libc-commits
mailing list