Skip to content

Commit 7884c07

Browse files
authored
[libc] Implement wcs to mbs family of functions (#149421)
Implemented internal wcs to mbs internal function + tests Impelemented wcs to mbs public functions
1 parent 74ce508 commit 7884c07

File tree

17 files changed

+1041
-0
lines changed

17 files changed

+1041
-0
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,9 @@ if(LLVM_LIBC_FULL_BUILD)
12681268
libc.src.wchar.mbtowc
12691269
libc.src.wchar.wcrtomb
12701270
libc.src.wchar.wctomb
1271+
libc.src.wchar.wcstombs
1272+
libc.src.wchar.wcsrtombs
1273+
libc.src.wchar.wcsnrtombs
12711274
)
12721275
endif()
12731276

libc/include/wchar.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,25 @@ functions:
204204
- type: wchar_t *__restrict
205205
- type: const wchar_t *__restrict
206206
- type: size_t
207+
- name: wcsnrtombs
208+
standards:
209+
- stdc
210+
return_type: size_t
211+
arguments:
212+
- type: char *__restrict
213+
- type: const wchar_t **__restrict
214+
- type: size_t
215+
- type: size_t
216+
- type: mbstate_t
217+
- name: wcsrtombs
218+
standards:
219+
- stdc
220+
return_type: size_t
221+
arguments:
222+
- type: char *__restrict
223+
- type: const wchar_t **__restrict
224+
- type: size_t
225+
- type: mbstate_t
207226
- name: wcrtomb
208227
standards:
209228
- stdc
@@ -279,6 +298,14 @@ functions:
279298
- type: const wchar_t *__restrict
280299
- type: wchar_t **__restrict
281300
- type: int
301+
- name: wcstombs
302+
standards:
303+
- stdc
304+
return_type: size_t
305+
arguments:
306+
- type: char *__restrict
307+
- type: const wchar_t *__restrict
308+
- type: size_t
282309
- name: wcstoul
283310
standards:
284311
- stdc

libc/src/__support/wchar/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,20 @@ add_object_library(
6969
.character_converter
7070
.mbstate
7171
)
72+
73+
add_header_library(
74+
wcsnrtombs
75+
HDRS
76+
wcsnrtombs.h
77+
DEPENDS
78+
libc.hdr.errno_macros
79+
libc.hdr.types.char8_t
80+
libc.hdr.types.char32_t
81+
libc.hdr.types.size_t
82+
libc.hdr.types.wchar_t
83+
libc.src.__support.error_or
84+
libc.src.__support.common
85+
.string_converter
86+
.character_converter
87+
.mbstate
88+
)

libc/src/__support/wchar/wcsnrtombs.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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__SUPPORT_WCHAR_WCSNRTOMBS_H
10+
#define LLVM_LIBC_SRC__SUPPORT_WCHAR_WCSNRTOMBS_H
11+
12+
#include "hdr/types/char32_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/macros/null_check.h"
19+
#include "src/__support/wchar/mbstate.h"
20+
#include "src/__support/wchar/string_converter.h"
21+
22+
namespace LIBC_NAMESPACE_DECL {
23+
namespace internal {
24+
25+
LIBC_INLINE static ErrorOr<size_t>
26+
wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
27+
size_t num_src_widechars, size_t dest_len, mbstate *ps) {
28+
LIBC_CRASH_ON_NULLPTR(ptr_to_src);
29+
LIBC_CRASH_ON_NULLPTR(ps);
30+
31+
CharacterConverter cr(ps);
32+
if (!cr.isValidState())
33+
return Error(EINVAL);
34+
35+
if (dest == nullptr)
36+
dest_len = SIZE_MAX;
37+
38+
StringConverter<char32_t> str_conv(
39+
reinterpret_cast<const char32_t *>(*ptr_to_src), ps, dest_len,
40+
num_src_widechars);
41+
size_t dst_idx = 0;
42+
ErrorOr<char8_t> converted = str_conv.popUTF8();
43+
while (converted.has_value()) {
44+
if (dest != nullptr)
45+
dest[dst_idx] = converted.value();
46+
47+
if (converted.value() == '\0') {
48+
if (dest != nullptr)
49+
*ptr_to_src = nullptr;
50+
return dst_idx;
51+
}
52+
53+
dst_idx++;
54+
converted = str_conv.popUTF8();
55+
}
56+
57+
if (dest != nullptr)
58+
*ptr_to_src += str_conv.getSourceIndex();
59+
60+
if (converted.error() == -1) // if we hit conversion limit
61+
return dst_idx;
62+
63+
return Error(converted.error());
64+
}
65+
66+
} // namespace internal
67+
} // namespace LIBC_NAMESPACE_DECL
68+
69+
#endif // LLVM_LIBC_SRC__SUPPORT_WCHAR_WCSNRTOMBS_H

libc/src/wchar/CMakeLists.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,47 @@ add_entrypoint_object(
169169
libc.src.__support.wchar.mbstate
170170
)
171171

172+
add_entrypoint_object(
173+
wcstombs
174+
SRCS
175+
wcstombs.cpp
176+
HDRS
177+
wcstombs.h
178+
DEPENDS
179+
libc.hdr.types.wchar_t
180+
libc.src.__support.wchar.mbstate
181+
libc.src.__support.wchar.wcsnrtombs
182+
libc.src.__support.libc_errno
183+
)
184+
185+
add_entrypoint_object(
186+
wcsrtombs
187+
SRCS
188+
wcsrtombs.cpp
189+
HDRS
190+
wcsrtombs.h
191+
DEPENDS
192+
libc.hdr.types.wchar_t
193+
libc.hdr.types.mbstate_t
194+
libc.src.__support.wchar.mbstate
195+
libc.src.__support.wchar.wcsnrtombs
196+
libc.src.__support.libc_errno
197+
)
198+
199+
add_entrypoint_object(
200+
wcsnrtombs
201+
SRCS
202+
wcsnrtombs.cpp
203+
HDRS
204+
wcsnrtombs.h
205+
DEPENDS
206+
libc.hdr.types.wchar_t
207+
libc.hdr.types.mbstate_t
208+
libc.src.__support.wchar.mbstate
209+
libc.src.__support.wchar.wcsnrtombs
210+
libc.src.__support.libc_errno
211+
)
212+
172213
add_entrypoint_object(
173214
mblen
174215
SRCS

libc/src/wchar/wcsnrtombs.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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/wcsnrtombs.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/wcsnrtombs.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+
LIBC_CRASH_ON_NULLPTR(pwcs);
27+
static internal::mbstate internal_mbstate;
28+
auto result = internal::wcsnrtombs(
29+
s, pwcs, nwc, len,
30+
ps == nullptr ? &internal_mbstate
31+
: reinterpret_cast<internal::mbstate *>(ps));
32+
if (!result.has_value()) {
33+
libc_errno = result.error();
34+
return -1;
35+
}
36+
37+
return result.value();
38+
}
39+
40+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcsnrtombs.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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,
20+
size_t nwc, size_t len, mbstate_t *ps);
21+
22+
} // namespace LIBC_NAMESPACE_DECL
23+
24+
#endif // LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_H

libc/src/wchar/wcsrtombs.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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/wcsnrtombs.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+
LIBC_CRASH_ON_NULLPTR(pwcs);
27+
static internal::mbstate internal_mbstate;
28+
auto result = internal::wcsnrtombs(
29+
s, pwcs, SIZE_MAX, n,
30+
ps == nullptr ? &internal_mbstate
31+
: reinterpret_cast<internal::mbstate *>(ps));
32+
if (!result.has_value()) {
33+
libc_errno = result.error();
34+
return -1;
35+
}
36+
37+
return result.value();
38+
}
39+
40+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/wcsrtombs.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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,
20+
mbstate_t *ps);
21+
22+
} // namespace LIBC_NAMESPACE_DECL
23+
24+
#endif // LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_H

libc/src/wchar/wcstombs.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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/wcsnrtombs.h"
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
LLVM_LIBC_FUNCTION(size_t, wcstombs,
23+
(char *__restrict s, const wchar_t *__restrict wcs,
24+
size_t n)) {
25+
LIBC_CRASH_ON_NULLPTR(wcs);
26+
static internal::mbstate internal_mbstate;
27+
const wchar_t *wcs_ptr_copy = wcs;
28+
auto result =
29+
internal::wcsnrtombs(s, &wcs_ptr_copy, SIZE_MAX, n, &internal_mbstate);
30+
if (!result.has_value()) {
31+
libc_errno = result.error();
32+
return -1;
33+
}
34+
35+
return result.value();
36+
}
37+
38+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)