Skip to content

Commit 586497d

Browse files
committed
wcsrtombs tests
1 parent d4a86b2 commit 586497d

File tree

3 files changed

+144
-1
lines changed

3 files changed

+144
-1
lines changed

libc/src/wchar/wcsrtombs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ LLVM_LIBC_FUNCTION(size_t, wcsrtombs,
2525
size_t n, mbstate_t *ps)) {
2626
static internal::mbstate internal_mbstate;
2727
internal::StringConverter<char32_t> str_conv(
28-
reinterpret_cast<const char32_t *>(pwcs),
28+
reinterpret_cast<const char32_t *>(*pwcs),
2929
ps == nullptr ? &internal_mbstate
3030
: reinterpret_cast<internal::mbstate *>(ps),
3131
n);

libc/test/src/wchar/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,20 @@ add_libc_test(
113113
libc.hdr.types.wchar_t
114114
)
115115

116+
add_libc_test(
117+
wcsrtombs_test
118+
SUITE
119+
libc_wchar_unittests
120+
SRCS
121+
wcsrtombs_test.cpp
122+
DEPENDS
123+
libc.src.wchar.wcsrtombs
124+
libc.test.UnitTest.ErrnoCheckingTest
125+
libc.hdr.types.wchar_t
126+
libc.src.string.memset
127+
libc.hdr.types.mbstate_t
128+
)
129+
116130
add_libc_test(
117131
wmemset_test
118132
SUITE
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//===-- Unittests for wcsrtombs -------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "hdr/types/mbstate_t.h"
10+
#include "src/string/memset.h"
11+
#include "src/wchar/wcsrtombs.h"
12+
#include "test/UnitTest/ErrnoCheckingTest.h"
13+
#include "test/UnitTest/Test.h"
14+
15+
using LlvmLibcWcsrtombs = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
16+
17+
TEST_F(LlvmLibcWcsrtombs, AllMultibyteLengths) {
18+
mbstate_t state;
19+
LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
20+
21+
/// clown emoji, sigma symbol, y with diaeresis, letter A
22+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
23+
static_cast<wchar_t>(0x2211),
24+
static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
25+
static_cast<wchar_t>(0x0)};
26+
const wchar_t *cur = src;
27+
char mbs[11];
28+
29+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 11, &state),
30+
static_cast<size_t>(10));
31+
ASSERT_ERRNO_SUCCESS();
32+
ASSERT_EQ(cur, nullptr);
33+
ASSERT_EQ(mbs[0], '\xF0'); // clown begin
34+
ASSERT_EQ(mbs[1], '\x9F');
35+
ASSERT_EQ(mbs[2], '\xA4');
36+
ASSERT_EQ(mbs[3], '\xA1');
37+
ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
38+
ASSERT_EQ(mbs[5], '\x88');
39+
ASSERT_EQ(mbs[6], '\x91');
40+
ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
41+
ASSERT_EQ(mbs[8], '\xBF');
42+
ASSERT_EQ(mbs[9], '\x41'); // A begin
43+
ASSERT_EQ(mbs[10], '\0'); // null terminator
44+
}
45+
46+
TEST_F(LlvmLibcWcsrtombs, DestLimit) {
47+
mbstate_t state;
48+
LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
49+
50+
/// clown emoji, sigma symbol, y with diaeresis, letter A
51+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
52+
static_cast<wchar_t>(0x2211),
53+
static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
54+
static_cast<wchar_t>(0x0)};
55+
const wchar_t *cur = src;
56+
57+
char mbs[11];
58+
for (int i = 0; i < 11; ++i)
59+
mbs[i] = '\x01'; // dummy initial values
60+
61+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 4, &state),
62+
static_cast<size_t>(4));
63+
ASSERT_ERRNO_SUCCESS();
64+
ASSERT_EQ(cur, src + 1);
65+
ASSERT_EQ(mbs[0], '\xF0');
66+
ASSERT_EQ(mbs[1], '\x9F');
67+
ASSERT_EQ(mbs[2], '\xA4');
68+
ASSERT_EQ(mbs[3], '\xA1');
69+
ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
70+
71+
for (int i = 0; i < 11; ++i)
72+
mbs[i] = '\x01'; // dummy initial values
73+
LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
74+
75+
// not enough bytes to convert the second character, so only converts one
76+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 6, &state),
77+
static_cast<size_t>(4));
78+
ASSERT_ERRNO_SUCCESS();
79+
ASSERT_EQ(cur, src + 1);
80+
ASSERT_EQ(mbs[0], '\xF0');
81+
ASSERT_EQ(mbs[1], '\x9F');
82+
ASSERT_EQ(mbs[2], '\xA4');
83+
ASSERT_EQ(mbs[3], '\xA1');
84+
ASSERT_EQ(mbs[4], '\x01');
85+
}
86+
87+
TEST_F(LlvmLibcWcsrtombs, NullDest) {
88+
mbstate_t state;
89+
LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
90+
91+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
92+
static_cast<wchar_t>(0x2211),
93+
static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
94+
static_cast<wchar_t>(0x0)};
95+
const wchar_t *cur = src;
96+
97+
// n parameter ignored when dest is null
98+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(nullptr, &cur, 1, &state),
99+
static_cast<size_t>(10));
100+
ASSERT_ERRNO_SUCCESS();
101+
ASSERT_EQ(cur, nullptr);
102+
103+
LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
104+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(nullptr, &cur, 100, &state),
105+
static_cast<size_t>(10));
106+
ASSERT_ERRNO_SUCCESS();
107+
ASSERT_EQ(cur, nullptr);
108+
}
109+
110+
TEST_F(LlvmLibcWcsrtombs, ErrnoTest) {
111+
mbstate_t state;
112+
LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
113+
114+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
115+
static_cast<wchar_t>(0x2211),
116+
static_cast<wchar_t>(0x12ffff), // invalid widechar
117+
static_cast<wchar_t>(0x0)};
118+
const wchar_t *cur = src;
119+
120+
// n parameter ignored when dest is null
121+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(nullptr, &cur, 7, &state),
122+
static_cast<size_t>(7));
123+
ASSERT_ERRNO_SUCCESS();
124+
125+
LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
126+
ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(nullptr, &cur, 100, &state),
127+
static_cast<size_t>(-1));
128+
ASSERT_ERRNO_EQ(EILSEQ);
129+
}

0 commit comments

Comments
 (0)