Skip to content

Commit 953eca5

Browse files
committed
implemented public functions
1 parent a4dab50 commit 953eca5

File tree

10 files changed

+348
-0
lines changed

10 files changed

+348
-0
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,9 @@ if(LLVM_LIBC_FULL_BUILD)
12631263
libc.src.wchar.mbtowc
12641264
libc.src.wchar.wcrtomb
12651265
libc.src.wchar.wctomb
1266+
libc.src.wchar.wcstombs
1267+
libc.src.wchar.wcsrtombs
1268+
libc.src.wchar.wcsnrtombs
12661269
)
12671270
endif()
12681271

libc/include/wchar.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,31 @@ functions:
274274
- type: const wchar_t *__restrict
275275
- type: wchar_t **__restrict
276276
- type: int
277+
- name: wcstombs
278+
standards:
279+
- stdc
280+
return_type: size_t
281+
arguments:
282+
- type: char *__restrict
283+
- type: const wchar_t *__restrict
284+
- type: size_t
285+
- name: wcsrtombs
286+
standards:
287+
- stdc
288+
return_type: size_t
289+
arguments:
290+
- type: char *__restrict
291+
- type: const wchar_t **__restrict
292+
- type: size_t
293+
- type: mbstate_t
294+
- name: wcsnrtombs
295+
standards:
296+
- stdc
297+
return_type: size_t
298+
arguments:
299+
- type: char *__restrict
300+
- type: const wchar_t *__restrict
301+
- type: size_t
302+
- type: size_t
303+
- type: mbstate_t
304+

libc/src/wchar/CMakeLists.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,47 @@ add_entrypoint_object(
159159
libc.src.__support.wchar.mbstate
160160
)
161161

162+
add_entrypoint_object(
163+
wcstombs
164+
SRCS
165+
wcstombs.cpp
166+
HDRS
167+
wcstombs.h
168+
DEPENDS
169+
libc.hdr.types.wchar_t
170+
libc.src.__support.wchar.mbstate
171+
libc.src.__support.wchar.string_converter
172+
libc.src.__support.libc_errno
173+
)
174+
175+
add_entrypoint_object(
176+
wcsrtombs
177+
SRCS
178+
wcsrtombs.cpp
179+
HDRS
180+
wcsrtombs.h
181+
DEPENDS
182+
libc.hdr.types.wchar_t
183+
libc.hdr.types.mbstate_t
184+
libc.src.__support.wchar.mbstate
185+
libc.src.__support.wchar.string_converter
186+
libc.src.__support.libc_errno
187+
)
188+
189+
add_entrypoint_object(
190+
wcstombs
191+
SRCS
192+
wcsnrtombs.cpp
193+
HDRS
194+
wcsnrtombs.h
195+
DEPENDS
196+
libc.hdr.types.wchar_t
197+
libc.hdr.types.mbstate_t
198+
libc.src.__support.wchar.mbstate
199+
libc.src.__support.wchar.string_converter
200+
libc.src.__support.libc_errno
201+
)
202+
162203
add_entrypoint_object(
163204
wmemset
164205
SRCS

libc/src/wchar/wcsnrtombs.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===-- Implementation of wcsnrtombs --------------------------------------===//
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 "src/wchar/wcsrtombs.h"
10+
11+
#include "hdr/types/char32_t.h"
12+
#include "hdr/types/mbstate_t.h"
13+
#include "hdr/types/size_t.h"
14+
#include "hdr/types/wchar_t.h"
15+
#include "src/__support/common.h"
16+
#include "src/__support/libc_errno.h"
17+
#include "src/__support/macros/config.h"
18+
#include "src/__support/wchar/mbstate.h"
19+
#include "src/__support/wchar/string_converter.h"
20+
21+
namespace LIBC_NAMESPACE_DECL {
22+
23+
LLVM_LIBC_FUNCTION(size_t, wcsnrtombs,
24+
(char *__restrict s, const wchar_t **__restrict pwcs,
25+
size_t nwc, size_t len, mbstate_t *ps)) {
26+
static internal::mbstate internal_mbstate;
27+
internal::StringConverter<char32_t> str_conv(
28+
reinterpret_cast<const char32_t *>(pwcs),
29+
ps == nullptr ? &internal_mbstate
30+
: reinterpret_cast<internal::mbstate *>(ps),
31+
len, nwc);
32+
33+
int dst_idx = 0;
34+
ErrorOr<char8_t> converted = str_conv.popUTF8();
35+
while (converted.has_value()) {
36+
if (s != nullptr)
37+
s[dst_idx] = converted.value();
38+
dst_idx++;
39+
converted = str_conv.popUTF8();
40+
}
41+
42+
pwcs += str_conv.getSourceIndex();
43+
if (converted.error() == -1) // if we hit conversion limit
44+
return dst_idx;
45+
46+
libc_errno = converted.error();
47+
return -1;
48+
}
49+
50+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcsnrtombs.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header for wcsnrtombs -------------------------------===//
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+
#ifndef LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_H
10+
#define LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_H
11+
12+
#include "hdr/types/mbstate_t.h"
13+
#include "hdr/types/size_t.h"
14+
#include "hdr/types/wchar_t.h"
15+
#include "src/__support/macros/config.h"
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
size_t wcsnrtombs(char *__restrict s, const wchar_t **__restrict pwcs, size_t nwc, size_t len, mbstate_t* ps);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_H

libc/src/wchar/wcsrtombs.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===-- Implementation of 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 "src/wchar/wcsrtombs.h"
10+
11+
#include "hdr/types/char32_t.h"
12+
#include "hdr/types/mbstate_t.h"
13+
#include "hdr/types/size_t.h"
14+
#include "hdr/types/wchar_t.h"
15+
#include "src/__support/common.h"
16+
#include "src/__support/libc_errno.h"
17+
#include "src/__support/macros/config.h"
18+
#include "src/__support/wchar/mbstate.h"
19+
#include "src/__support/wchar/string_converter.h"
20+
21+
namespace LIBC_NAMESPACE_DECL {
22+
23+
LLVM_LIBC_FUNCTION(size_t, wcsrtombs,
24+
(char *__restrict s, const wchar_t **__restrict pwcs,
25+
size_t n, mbstate_t *ps)) {
26+
static internal::mbstate internal_mbstate;
27+
internal::StringConverter<char32_t> str_conv(
28+
reinterpret_cast<const char32_t *>(pwcs),
29+
ps == nullptr ? &internal_mbstate
30+
: reinterpret_cast<internal::mbstate *>(ps),
31+
n);
32+
33+
int dst_idx = 0;
34+
ErrorOr<char8_t> converted = str_conv.popUTF8();
35+
while (converted.has_value()) {
36+
if (s != nullptr)
37+
s[dst_idx] = converted.value();
38+
dst_idx++;
39+
converted = str_conv.popUTF8();
40+
}
41+
42+
pwcs += str_conv.getSourceIndex();
43+
if (converted.error() == -1) // if we hit conversion limit
44+
return dst_idx;
45+
46+
libc_errno = converted.error();
47+
return -1;
48+
}
49+
50+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcsrtombs.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header 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+
#ifndef LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_H
10+
#define LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_H
11+
12+
#include "hdr/types/mbstate_t.h"
13+
#include "hdr/types/size_t.h"
14+
#include "hdr/types/wchar_t.h"
15+
#include "src/__support/macros/config.h"
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
size_t wcsrtombs(char *__restrict s, const wchar_t **__restrict pwcs, size_t n, mbstate_t* ps);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_H

libc/src/wchar/wcstombs.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===-- Implementation of wcstombs ----------------------------------------===//
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 "src/wchar/wcstombs.h"
10+
11+
#include "hdr/types/char32_t.h"
12+
#include "hdr/types/size_t.h"
13+
#include "hdr/types/wchar_t.h"
14+
#include "src/__support/common.h"
15+
#include "src/__support/libc_errno.h"
16+
#include "src/__support/macros/config.h"
17+
#include "src/__support/wchar/mbstate.h"
18+
#include "src/__support/wchar/string_converter.h"
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
LLVM_LIBC_FUNCTION(size_t, wcstombs,
23+
(char *__restrict s, const wchar_t *__restrict pwcs,
24+
size_t n)) {
25+
static internal::mbstate internal_mbstate;
26+
internal::StringConverter<char32_t> str_conv(
27+
reinterpret_cast<const char32_t *>(pwcs), &internal_mbstate, n);
28+
29+
int dst_idx = 0;
30+
ErrorOr<char8_t> converted = str_conv.popUTF8();
31+
while (converted.has_value()) {
32+
if (s != nullptr)
33+
s[dst_idx] = converted.value();
34+
dst_idx++;
35+
converted = str_conv.popUTF8();
36+
}
37+
38+
if (converted.error() == -1) // if we hit conversion limit
39+
return dst_idx;
40+
41+
libc_errno = converted.error();
42+
return -1;
43+
}
44+
45+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcstombs.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Implementation header for wcstombs --------------------------------===//
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+
#ifndef LLVM_LIBC_SRC_WCHAR_WCSTOMBS_H
10+
#define LLVM_LIBC_SRC_WCHAR_WCSTOMBS_H
11+
12+
#include "hdr/types/size_t.h"
13+
#include "hdr/types/wchar_t.h"
14+
#include "src/__support/macros/config.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
size_t wcstombs(char *__restrict s, const wchar_t *__restrict pwcs, size_t n);
19+
20+
} // namespace LIBC_NAMESPACE_DECL
21+
22+
#endif // LLVM_LIBC_SRC_WCHAR_WCSTOMBS_H
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===-- Unittests for wcstombs --------------------------------------------===//
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 "src/wchar/wcstombs.h"
10+
#include "test/UnitTest/ErrnoCheckingTest.h"
11+
#include "test/UnitTest/Test.h"
12+
13+
using LlvmLibcWcstombs = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
14+
15+
TEST_F(LlvmLibcWcstombs, AllMultibyteLengths) {
16+
/// clown emoji, sigma symbol, y with diaeresis, letter A
17+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
18+
static_cast<wchar_t>(0x2211),
19+
static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
20+
static_cast<wchar_t>(0x0)};
21+
char mbs[11];
22+
23+
ASSERT_EQ(wcstombs(mbs, src, 11), static_cast<size_t>(11));
24+
ASSERT_ERRNO_SUCCESS();
25+
ASSERT_EQ(mbs[0], '\xF0'); // clown begin
26+
ASSERT_EQ(mbs[1], '\x9F');
27+
ASSERT_EQ(mbs[2], '\xA4');
28+
ASSERT_EQ(mbs[3], '\xA1');
29+
ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
30+
ASSERT_EQ(mbs[5], '\x88');
31+
ASSERT_EQ(mbs[6], '\x91');
32+
ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
33+
ASSERT_EQ(mbs[8], '\xBF');
34+
ASSERT_EQ(mbs[9], '\x41'); // A begin
35+
ASSERT_EQ(mbs[10], '\0'); // null terminator
36+
}
37+
38+
TEST_F(LlvmLibcWcstombs, PartialConversion) {
39+
/// clown emoji, sigma symbol, y with diaeresis, letter A
40+
const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
41+
static_cast<wchar_t>(0x2211),
42+
static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
43+
static_cast<wchar_t>(0x0)};
44+
char mbs[11] = {0};
45+
46+
ASSERT_EQ(wcstombs(mbs, src, 6), static_cast<size_t>(4));
47+
ASSERT_ERRNO_SUCCESS();
48+
ASSERT_EQ(mbs[0], '\xF0'); // clown begin
49+
ASSERT_EQ(mbs[1], '\x9F');
50+
ASSERT_EQ(mbs[2], '\xA4');
51+
ASSERT_EQ(mbs[3], '\xA1');
52+
ASSERT_EQ(mbs[4], '\0');
53+
54+
ASSERT_EQ(wcstombs(mbs, src, 6), static_cast<size_t>(4));
55+
56+
ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
57+
ASSERT_EQ(mbs[5], '\x88');
58+
ASSERT_EQ(mbs[6], '\x91');
59+
ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
60+
ASSERT_EQ(mbs[8], '\xBF');
61+
ASSERT_EQ(mbs[9], '\x41'); // A begin
62+
ASSERT_EQ(mbs[10], '\0'); // null terminator
63+
}

0 commit comments

Comments
 (0)