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