-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] Implemented wctomb #145554
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
[libc] Implemented wctomb #145554
Conversation
@llvm/pr-subscribers-libc Author: Uzair Nawaz (uzairnawaz) ChangesImplemented wctomb by calling internal wcrtomb function Full diff: https://github.com/llvm/llvm-project/pull/145554.diff 7 Files Affected:
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 4d94f10196fd7..60f70fcba2448 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1248,6 +1248,7 @@ if(LLVM_LIBC_FULL_BUILD)
# wchar.h entrypoints
libc.src.wchar.mbrtowc
libc.src.wchar.wcrtomb
+ libc.src.wchar.wctomb
)
endif()
diff --git a/libc/include/wchar.yaml b/libc/include/wchar.yaml
index 64eb381710668..9c798b101b53f 100644
--- a/libc/include/wchar.yaml
+++ b/libc/include/wchar.yaml
@@ -167,6 +167,13 @@ functions:
- type: char *__restrict
- type: wchar_t
- type: mbstate_t *__restrict
+ - name: wctomb
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: char *
+ - type: wchar_t
- name: wcscpy
standards:
- stdc
diff --git a/libc/src/wchar/CMakeLists.txt b/libc/src/wchar/CMakeLists.txt
index ec33caccb16d5..812afab66cf87 100644
--- a/libc/src/wchar/CMakeLists.txt
+++ b/libc/src/wchar/CMakeLists.txt
@@ -48,6 +48,18 @@ add_entrypoint_object(
libc.src.__support.wchar.mbstate
)
+add_entrypoint_object(
+ wctomb
+ SRCS
+ wctomb.cpp
+ HDRS
+ wctomb.h
+ DEPENDS
+ libc.hdr.types.wchar_t
+ libc.src.__support.wchar.wcrtomb
+ libc.src.__support.wchar.mbstate
+)
+
add_entrypoint_object(
mbrtowc
SRCS
diff --git a/libc/src/wchar/wctomb.cpp b/libc/src/wchar/wctomb.cpp
new file mode 100644
index 0000000000000..3278051eb196f
--- /dev/null
+++ b/libc/src/wchar/wctomb.cpp
@@ -0,0 +1,32 @@
+//===-- Implementation of wctomb ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wctomb.h"
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/__support/wchar/wcrtomb.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, wctomb, (char *s, wchar_t wc)) {
+ internal::mbstate internal_mbstate;
+ if (s == nullptr)
+ return 0;
+
+ auto result = internal::wcrtomb(s, wc, &internal_mbstate);
+
+ if (!result.has_value()) // invalid wide character
+ return -1;
+
+ return static_cast<int>(result.value());
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wctomb.h b/libc/src/wchar/wctomb.h
new file mode 100644
index 0000000000000..02a34e5ad229f
--- /dev/null
+++ b/libc/src/wchar/wctomb.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for wctomb ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_WCHAR_WCTOMB_H
+#define LLVM_LIBC_SRC_WCHAR_WCTOMB_H
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int wctomb(char *s, wchar_t wc);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCTOMB_H
diff --git a/libc/test/src/wchar/CMakeLists.txt b/libc/test/src/wchar/CMakeLists.txt
index 184e482c895b1..95a4374abf0a2 100644
--- a/libc/test/src/wchar/CMakeLists.txt
+++ b/libc/test/src/wchar/CMakeLists.txt
@@ -61,6 +61,17 @@ add_libc_test(
libc.src.__support.libc_errno
)
+add_libc_test(
+ wctomb_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ wctomb_test.cpp
+ DEPENDS
+ libc.src.wchar.wctomb
+ libc.hdr.types.wchar_t
+)
+
add_libc_test(
wmemset_test
SUITE
diff --git a/libc/test/src/wchar/wctomb_test.cpp b/libc/test/src/wchar/wctomb_test.cpp
new file mode 100644
index 0000000000000..1fcb51b2cb583
--- /dev/null
+++ b/libc/test/src/wchar/wctomb_test.cpp
@@ -0,0 +1,68 @@
+//===-- Unittests for wctomb ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/wchar/wctomb.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcWCToMBTest, OneByte) {
+ wchar_t wc = L'U';
+ char mb[4];
+ int cnt = LIBC_NAMESPACE::wctomb(mb, wc);
+ ASSERT_EQ(cnt, 1);
+ ASSERT_EQ(mb[0], 'U');
+}
+
+TEST(LlvmLibcWCToMBTest, TwoByte) {
+ // testing utf32: 0xff -> utf8: 0xc3 0xbf
+ wchar_t wc = 0xff;
+ char mb[4];
+ int cnt = LIBC_NAMESPACE::wctomb(mb, wc);
+ ASSERT_EQ(cnt, 2);
+ ASSERT_EQ(mb[0], static_cast<char>(0xc3));
+ ASSERT_EQ(mb[1], static_cast<char>(0xbf));
+}
+
+TEST(LlvmLibcWCToMBTest, ThreeByte) {
+ // testing utf32: 0xac15 -> utf8: 0xea 0xb0 0x95
+ wchar_t wc = 0xac15;
+ char mb[4];
+ int cnt = LIBC_NAMESPACE::wctomb(mb, wc);
+ ASSERT_EQ(cnt, 3);
+ ASSERT_EQ(mb[0], static_cast<char>(0xea));
+ ASSERT_EQ(mb[1], static_cast<char>(0xb0));
+ ASSERT_EQ(mb[2], static_cast<char>(0x95));
+}
+
+TEST(LlvmLibcWCToMBTest, FourByte) {
+ // testing utf32: 0x1f921 -> utf8: 0xf0 0x9f 0xa4 0xa1
+ wchar_t wc = 0x1f921;
+ char mb[4];
+ int cnt = LIBC_NAMESPACE::wctomb(mb, wc);
+ ASSERT_EQ(cnt, 4);
+ ASSERT_EQ(mb[0], static_cast<char>(0xf0));
+ ASSERT_EQ(mb[1], static_cast<char>(0x9f));
+ ASSERT_EQ(mb[2], static_cast<char>(0xa4));
+ ASSERT_EQ(mb[3], static_cast<char>(0xa1));
+}
+
+TEST(LlvmLibcWCToMBTest, NullString) {
+ wchar_t wc = L'A';
+
+ int cnt = LIBC_NAMESPACE::wctomb(nullptr, wc);
+
+ // no state-dependent encoding
+ ASSERT_EQ(cnt, 0);
+}
+
+TEST(LlvmLibcWCToMBTest, InvalidWchar) {
+ wchar_t wc = 0x12ffff;
+ char mb[4];
+ int cnt = LIBC_NAMESPACE::wctomb(mb, wc);
+ ASSERT_EQ(cnt, -1);
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall pretty good, just need to add errno things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Implemented wctomb by calling internal wcrtomb function Added tests
Implemented wctomb by calling internal wcrtomb function
Added tests