Skip to content

[libc] Refactored internal wcrtomb #145945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

uzairnawaz
Copy link
Contributor

Removed output parameters for internal::wcrtomb and instead returned a struct containing the result of the conversion.

@llvmbot
Copy link
Member

llvmbot commented Jun 26, 2025

@llvm/pr-subscribers-libc

Author: Uzair Nawaz (uzairnawaz)

Changes

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 --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

Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- libc/src/__support/wchar/wcrtomb.cpp libc/src/__support/wchar/wcrtomb.h libc/src/wchar/wcrtomb.cpp libc/src/wchar/wctomb.cpp
View the diff from clang-format here.
diff --git a/libc/src/__support/wchar/wcrtomb.h b/libc/src/__support/wchar/wcrtomb.h
index b255fd41d..c76846357 100644
--- a/libc/src/__support/wchar/wcrtomb.h
+++ b/libc/src/__support/wchar/wcrtomb.h
@@ -19,11 +19,11 @@ namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
 struct wcrtomb_result {
-    char mbs[4];
-    size_t count = 0;    
+  char mbs[4];
+  size_t count = 0;
 };
 
-ErrorOr<wcrtomb_result> wcrtomb(wchar_t wc, mbstate* ps);
+ErrorOr<wcrtomb_result> wcrtomb(wchar_t wc, mbstate *ps);
 
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL

Copy link
Contributor

@sribee8 sribee8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after fixing formatting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants