-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[libc] wchar string conversion functions mb to wc #149423
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
sribee8
wants to merge
9
commits into
llvm:main
Choose a base branch
from
sribee8:mbstowcs-implementation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
+957
−0
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-libc Author: None (sribee8) ChangesImplemented an internal multi-byte to wide character string conversion function, public functions, and tests Patch is 35.84 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/149423.diff 16 Files Affected:
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 9223911f04a93..e0a02abef001c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1261,6 +1261,9 @@ if(LLVM_LIBC_FULL_BUILD)
# wchar.h entrypoints
libc.src.wchar.mbrtowc
libc.src.wchar.mbtowc
+ libc.src.wchar.mbstowcs
+ libc.src.wchar.mbsrtowcs
+ libc.src.wchar.mbsnrtowcs
libc.src.wchar.wcrtomb
libc.src.wchar.wctomb
)
diff --git a/libc/include/wchar.yaml b/libc/include/wchar.yaml
index 123d3440aeec3..d3166d60c19de 100644
--- a/libc/include/wchar.yaml
+++ b/libc/include/wchar.yaml
@@ -53,6 +53,33 @@ functions:
- type: wchar_t *__restrict
- type: const char *__restrict
- type: size_t
+ - name: mbstowcs
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: wchar_t *__restrict
+ - type: const char *__restrict
+ - type: size_t
+ - name: mbsrtowcs
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: wchar_t *__restrict
+ - type: const char **__restrict
+ - type: size_t
+ - type: mbstate_t *__restrict
+ - name: mbsnrtowcs
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: wchar_t *__restrict
+ - type: const char **__restrict
+ - type: size_t
+ - type: size_t
+ - type: mbstate_t *__restrict
- name: wmemset
standards:
- stdc
diff --git a/libc/src/__support/wchar/CMakeLists.txt b/libc/src/__support/wchar/CMakeLists.txt
index 802441d37fe92..fa5139a8b68b4 100644
--- a/libc/src/__support/wchar/CMakeLists.txt
+++ b/libc/src/__support/wchar/CMakeLists.txt
@@ -68,3 +68,21 @@ add_object_library(
.character_converter
.mbstate
)
+
+add_object_library(
+ mbsnrtowcs
+ HDRS
+ mbsnrtowcs.h
+ SRCS
+ mbsnrtowcs.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.types.wchar_t
+ libc.hdr.types.size_t
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ .character_converter
+ .mbstate
+ .string_converter
+)
diff --git a/libc/src/__support/wchar/mbsnrtowcs.cpp b/libc/src/__support/wchar/mbsnrtowcs.cpp
new file mode 100644
index 0000000000000..9eb2b5423af87
--- /dev/null
+++ b/libc/src/__support/wchar/mbsnrtowcs.cpp
@@ -0,0 +1,59 @@
+//===-- Implementation for mbsnrtowcs function ------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/wchar/mbsnrtowcs.h"
+#include "hdr/errno_macros.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/character_converter.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/__support/wchar/string_converter.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
+ size_t nmc, size_t len, mbstate *__restrict ps) {
+ if (*src == nullptr)
+ return 0;
+ // Checking if mbstate is valid
+ CharacterConverter char_conv(ps);
+ if (!char_conv.isValidState())
+ return Error(EINVAL);
+
+ StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps,
+ len, nmc);
+ size_t dst_idx = 0;
+ ErrorOr<char32_t> converted = str_conv.popUTF32();
+ while (converted.has_value()) {
+ if (dst != nullptr)
+ dst[dst_idx] = converted.value();
+ // null terminator should not be counted in return value
+ if (converted.value() == L'\0') {
+ if (dst != nullptr)
+ *src = nullptr;
+ return dst_idx;
+ }
+ dst_idx++;
+ converted = str_conv.popUTF32();
+ }
+
+ if (converted.error() == -1) { // if we hit conversion limit
+ *src += str_conv.getSourceIndex();
+ return dst_idx;
+ }
+
+ return Error(converted.error());
+}
+
+} // namespace internal
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/wchar/mbsnrtowcs.h b/libc/src/__support/wchar/mbsnrtowcs.h
new file mode 100644
index 0000000000000..8ce497325fdad
--- /dev/null
+++ b/libc/src/__support/wchar/mbsnrtowcs.h
@@ -0,0 +1,29 @@
+//===-- Implementation header for mbsnrtowcs function -----------*- 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___SUPPORT_WCHAR_MBSNRTOWCS
+#define LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSNRTOWCS
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbstate.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
+ size_t nmc, size_t len, mbstate *__restrict ps);
+
+} // namespace internal
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSNRTOWCS
diff --git a/libc/src/wchar/CMakeLists.txt b/libc/src/wchar/CMakeLists.txt
index 7ace1a6ca66ba..ac359064ec10c 100644
--- a/libc/src/wchar/CMakeLists.txt
+++ b/libc/src/wchar/CMakeLists.txt
@@ -159,6 +159,56 @@ add_entrypoint_object(
libc.src.__support.wchar.mbstate
)
+add_entrypoint_object(
+ mbstowcs
+ SRCS
+ mbstowcs.cpp
+ HDRS
+ mbstowcs.h
+ DEPENDS
+ libc.hdr.types.size_t
+ libc.hdr.types.wchar_t
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbstate
+ libc.src.__support.wchar.mbsnrtowcs
+)
+
+add_entrypoint_object(
+ mbsrtowcs
+ SRCS
+ mbsrtowcs.cpp
+ HDRS
+ mbsrtowcs.h
+ DEPENDS
+ libc.hdr.types.size_t
+ libc.hdr.types.wchar_t
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbstate
+ libc.src.__support.wchar.mbsnrtowcs
+ libc.src.__support.wchar.mbstate
+)
+
+add_entrypoint_object(
+ mbsnrtowcs
+ SRCS
+ mbsnrtowcs.cpp
+ HDRS
+ mbsnrtowcs.h
+ DEPENDS
+ libc.hdr.types.size_t
+ libc.hdr.types.wchar_t
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbstate
+ libc.src.__support.wchar.mbsnrtowcs
+ libc.src.__support.wchar.mbstate
+)
+
add_entrypoint_object(
wmemset
SRCS
diff --git a/libc/src/wchar/mbsnrtowcs.cpp b/libc/src/wchar/mbsnrtowcs.cpp
new file mode 100644
index 0000000000000..28e0ff31b26c4
--- /dev/null
+++ b/libc/src/wchar/mbsnrtowcs.cpp
@@ -0,0 +1,39 @@
+//===-- Implementation of mbsnrtowcs --------------------------------------===//
+//
+// 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/mbsnrtowcs.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbsnrtowcs.h"
+#include "src/__support/wchar/mbstate.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, mbsnrtowcs,
+ (wchar_t *__restrict dst, const char **__restrict src,
+ size_t nmc, size_t len, mbstate_t *__restrict ps)) {
+ static internal::mbstate internal_mbstate;
+ // If destination is null, ignore len
+ len = dst == nullptr ? SIZE_MAX : len;
+ auto ret = internal::mbsnrtowcs(
+ dst, src, nmc, len,
+ ps == nullptr ? &internal_mbstate
+ : reinterpret_cast<internal::mbstate *>(ps));
+ if (!ret.has_value()) {
+ // Encoding failure
+ libc_errno = ret.error();
+ return -1;
+ }
+ return ret.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/mbsnrtowcs.h b/libc/src/wchar/mbsnrtowcs.h
new file mode 100644
index 0000000000000..5c9687b20b3fa
--- /dev/null
+++ b/libc/src/wchar/mbsnrtowcs.h
@@ -0,0 +1,24 @@
+//===-- Implementation header for mbsnrtowcs ------------------------------===//
+//
+// 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_MBSNRTOWCS_H
+#define LLVM_LIBC_SRC_WCHAR_MBSNRTOWCS_H
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
+ size_t nmc, size_t len, mbstate_t *__restrict ps);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_MBSNRTOWCS_H
diff --git a/libc/src/wchar/mbsrtowcs.cpp b/libc/src/wchar/mbsrtowcs.cpp
new file mode 100644
index 0000000000000..82ca25a3d863d
--- /dev/null
+++ b/libc/src/wchar/mbsrtowcs.cpp
@@ -0,0 +1,39 @@
+//===-- Implementation of mbsrtowcs ---------------------------------------===//
+//
+// 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/mbsrtowcs.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbsnrtowcs.h"
+#include "src/__support/wchar/mbstate.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, mbsrtowcs,
+ (wchar_t *__restrict dst, const char **__restrict src,
+ size_t len, mbstate_t *__restrict ps)) {
+ static internal::mbstate internal_mbstate;
+ // If destination is null, ignore len
+ len = dst == nullptr ? SIZE_MAX : len;
+ auto ret = internal::mbsnrtowcs(
+ dst, src, SIZE_MAX, len,
+ ps == nullptr ? &internal_mbstate
+ : reinterpret_cast<internal::mbstate *>(ps));
+ if (!ret.has_value()) {
+ // Encoding failure
+ libc_errno = ret.error();
+ return -1;
+ }
+ return ret.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/mbsrtowcs.h b/libc/src/wchar/mbsrtowcs.h
new file mode 100644
index 0000000000000..f8d4cc26e63ae
--- /dev/null
+++ b/libc/src/wchar/mbsrtowcs.h
@@ -0,0 +1,24 @@
+//===-- Implementation header for mbsrtowcs -------------------------------===//
+//
+// 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_MBSRTOWCS_H
+#define LLVM_LIBC_SRC_WCHAR_MBSRTOWCS_H
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src,
+ size_t len, mbstate_t *__restrict ps);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_MBSRTOWCS_H
diff --git a/libc/src/wchar/mbstowcs.cpp b/libc/src/wchar/mbstowcs.cpp
new file mode 100644
index 0000000000000..1a3232847fa71
--- /dev/null
+++ b/libc/src/wchar/mbstowcs.cpp
@@ -0,0 +1,38 @@
+//===-- Implementation of mbstowcs ----------------------------------------===//
+//
+// 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/mbstowcs.h"
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbsnrtowcs.h"
+#include "src/__support/wchar/mbstate.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, mbstowcs,
+ (wchar_t *__restrict pwcs, const char *__restrict s,
+ size_t n)) {
+ // If destination is null, ignore n
+ n = pwcs == nullptr ? SIZE_MAX : n;
+ static internal::mbstate internal_mbstate;
+ const char *temp = s;
+ auto ret = internal::mbsnrtowcs(pwcs, &temp, SIZE_MAX, n, &internal_mbstate);
+
+ if (!ret.has_value()) {
+ // Encoding failure
+ libc_errno = ret.error();
+ return -1;
+ }
+ return ret.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/mbstowcs.h b/libc/src/wchar/mbstowcs.h
new file mode 100644
index 0000000000000..7d08a838b2324
--- /dev/null
+++ b/libc/src/wchar/mbstowcs.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for mbstowcs --------------------------------===//
+//
+// 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_MBSTOWCS_H
+#define LLVM_LIBC_SRC_WCHAR_MBSTOWCS_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t mbstowcs(wchar_t *__restrict pwcs, const char *__restrict s, size_t n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_MBSTOWCS_H
diff --git a/libc/test/src/wchar/CMakeLists.txt b/libc/test/src/wchar/CMakeLists.txt
index 176cf7c3487cd..1a8f9981fc5bb 100644
--- a/libc/test/src/wchar/CMakeLists.txt
+++ b/libc/test/src/wchar/CMakeLists.txt
@@ -64,6 +64,51 @@ add_libc_test(
libc.test.UnitTest.ErrnoCheckingTest
)
+add_libc_test(
+ mbstowcs_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ mbstowcs_test.cpp
+ DEPENDS
+ libc.src.__support.libc_errno
+ libc.src.wchar.mbstowcs
+ libc.hdr.types.wchar_t
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
+add_libc_test(
+ mbsrtowcs_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ mbsrtowcs_test.cpp
+ DEPENDS
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbstate
+ libc.src.string.memset
+ libc.src.wchar.mbsrtowcs
+ libc.hdr.types.mbstate_t
+ libc.hdr.types.wchar_t
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
+add_libc_test(
+ mbsnrtowcs_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ mbsnrtowcs_test.cpp
+ DEPENDS
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbstate
+ libc.src.string.memset
+ libc.src.wchar.mbsnrtowcs
+ libc.hdr.types.mbstate_t
+ libc.hdr.types.wchar_t
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
add_libc_test(
wctob_test
SUITE
diff --git a/libc/test/src/wchar/mbsnrtowcs_test.cpp b/libc/test/src/wchar/mbsnrtowcs_test.cpp
new file mode 100644
index 0000000000000..a042794997b9f
--- /dev/null
+++ b/libc/test/src/wchar/mbsnrtowcs_test.cpp
@@ -0,0 +1,203 @@
+//===-- Unittests for mbsetowcs -------------------------------------------===//
+//
+// 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/mbstate_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/string/memset.h"
+#include "src/wchar/mbsnrtowcs.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcMBSNRToWCSTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcMBSNRToWCSTest, OneByteOneChar) {
+ const char *ch = "A";
+ const char *original = ch;
+ wchar_t dest[2];
+ mbstate_t *mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ size_t n = LIBC_NAMESPACE::mbsnrtowcs(dest, &ch, 1, 1, mb);
+ ASSERT_EQ(static_cast<char>(*dest), 'A');
+ ASSERT_EQ(static_cast<int>(n), 1);
+ // Should point to null terminator now
+ ASSERT_EQ(ch, original + 1);
+ ASSERT_ERRNO_SUCCESS();
+
+ n = LIBC_NAMESPACE::mbsnrtowcs(dest + 1, &ch, 1, 1, mb);
+ ASSERT_EQ(static_cast<char>(dest[1]), '\0');
+ // Should not include null terminator
+ ASSERT_EQ(static_cast<int>(n), 0);
+ // Should now be a nullptr
+ ASSERT_EQ(ch, nullptr);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBSNRToWCSTest, FourByteOneChar) {
+ const char *src = "\xf0\x9f\x98\xb9"; // laughing cat emoji 😹
+ const char *original = src;
+ wchar_t dest[2];
+ mbstate_t *mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ // Not enough bytes for the full character
+ size_t n = LIBC_NAMESPACE::mbsnrtowcs(dest, &src, 3, 2, mb);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(static_cast<int>(n), 0);
+ ASSERT_EQ(src, original + 3);
+ // Needs 2 more bytes (last byte of cat + null terminator)
+ n = LIBC_NAMESPACE::mbsnrtowcs(dest, &src, 2, 2, mb);
+ ASSERT_ERRNO_SUCCESS();
+ // Does not include null terminator
+ ASSERT_EQ(static_cast<int>(n), 1);
+ ASSERT_EQ(src, nullptr);
+ ASSERT_EQ(static_cast<int>(dest[0]), 128569);
+ ASSERT_TRUE(dest[1] == L'\0');
+}
+
+TEST_F(LlvmLibcMBSNRToWCSTest, MixedNumberOfBytes) {
+ // 'A', sigma symbol 'Σ', recycling symbol '♻', laughing cat emoji '😹'
+ const char *src = "A\xce\xa3\xe2\x99\xbb\xf0\x9f\x98\xb9";
+ const char *original = src;
+ wchar_t dest[5];
+ mbstate_t *mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+
+ // Read 'A'
+ size_t n = LIBC_NAMESPACE::mbsnrtowcs(dest, &src, 1, 1, mb);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(static_cast<char>(dest[0]), 'A');
+ ASSERT_EQ(static_cast<int>(n), 1);
+ ASSERT_EQ(src, original + 1);
+
+ // Read sigma 'Σ'
+ n = LIBC_NAMESPACE::mbsnrtowcs(dest + 1, &src, 2, 1, mb);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(static_cast<int>(dest[1]), 931);
+ ASSERT_EQ(static_cast<int>(n), 1);
+ ASSERT_EQ(src, original + 3);
+
+ // Read recycling '♻'
+ n = LIBC_NAMESPACE::mbsnrtowcs(dest + 2, &src, 2, 5, mb);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(static_cast<int>(n), 0);
+ ASSERT_EQ(src, original + 5);
+ n = LIBC_NAMESPACE::mbsnrtowcs(dest + 2, &src, 1, 1, mb);
+ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(static_cast<int>(n), 1);
+ ASSERT_EQ(src, original + 6);
+ ASSERT_EQ(static_cast<int>(dest[2]), 9851);
+
+ // Read laughing cat emoji '😹'
+ n = LIBC_NAMESPACE::mbsnrtowcs(dest + 3, &src, 4, 5, mb);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(static_cast<int>(n), 1);
+ ASSERT_EQ(src, original + 10);
+ ASSERT_EQ(static_cast<int>(dest[3]), 128569);
+
+
+ n = LIBC_NAMESPACE::mbsnrtowcs(dest + 4, &src, 4, 4, nullptr);
+ ASSERT_TRUE(dest[4] == L'\0');
+ ASSERT_ERRNO_SUCCESS();
+ // Should not count null terminator in number
+ ASSERT_EQ(static_cast<int>(n), 0);
+ // Should now be a nullptr
+ ASSERT_EQ(src, nullptr);
+}
+
+TEST_F(LlvmLibcMBSNRToWCSTest, ReadLessThanStringLength) {
+ // Four laughing cat emojis "😹😹😹😹"
+ const char *src =
+ "\xf0\x9f\x98\xb9\xf0\x9f\x98\xb9\xf0\x9f\x98\xb9\xf0\x9f\x98\xb9";
+ const char *original = src;
+ wchar_t dest[5] = {L'a', L'b', L'c', L'd', L'e'};
+ size_t n = LIBC_NAMESPACE::mbsnrtowcs(dest, &src, 100, 3, nullptr);
+ ASSERT_ERRNO...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Implemented an internal multi-byte to wide character string conversion function, public functions, and tests