Skip to content

Commit ad463ea

Browse files
sribee8Sriya Pratipati
authored andcommitted
[libc] wchar string conversion functions mb to wc (llvm#149423)
Implemented an internal multi-byte to wide character string conversion function, public functions, and tests --------- Co-authored-by: Sriya Pratipati <[email protected]>
1 parent 17a945c commit ad463ea

File tree

15 files changed

+967
-9
lines changed

15 files changed

+967
-9
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,9 @@ if(LLVM_LIBC_FULL_BUILD)
12661266
libc.src.wchar.mbrlen
12671267
libc.src.wchar.mbrtowc
12681268
libc.src.wchar.mbtowc
1269+
libc.src.wchar.mbstowcs
1270+
libc.src.wchar.mbsrtowcs
1271+
libc.src.wchar.mbsnrtowcs
12691272
libc.src.wchar.wcrtomb
12701273
libc.src.wchar.wctomb
12711274
libc.src.wchar.wcstombs

libc/include/wchar.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,33 @@ functions:
5353
- type: wchar_t *__restrict
5454
- type: const char *__restrict
5555
- type: size_t
56+
- name: mbsnrtowcs
57+
standards:
58+
- stdc
59+
return_type: size_t
60+
arguments:
61+
- type: wchar_t *__restrict
62+
- type: const char **__restrict
63+
- type: size_t
64+
- type: size_t
65+
- type: mbstate_t *__restrict
66+
- name: mbsrtowcs
67+
standards:
68+
- stdc
69+
return_type: size_t
70+
arguments:
71+
- type: wchar_t *__restrict
72+
- type: const char **__restrict
73+
- type: size_t
74+
- type: mbstate_t *__restrict
75+
- name: mbstowcs
76+
standards:
77+
- stdc
78+
return_type: size_t
79+
arguments:
80+
- type: wchar_t *__restrict
81+
- type: const char *__restrict
82+
- type: size_t
5683
- name: mblen
5784
standards:
5885
- stdc

libc/src/__support/wchar/CMakeLists.txt

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,31 @@ add_object_library(
6060
SRCS
6161
mbrtowc.cpp
6262
DEPENDS
63-
libc.hdr.errno_macros
64-
libc.hdr.types.wchar_t
65-
libc.hdr.types.size_t
66-
libc.src.__support.common
67-
libc.src.__support.error_or
68-
libc.src.__support.macros.config
69-
.character_converter
70-
.mbstate
63+
libc.hdr.errno_macros
64+
libc.hdr.types.wchar_t
65+
libc.hdr.types.size_t
66+
libc.src.__support.common
67+
libc.src.__support.error_or
68+
libc.src.__support.macros.config
69+
.character_converter
70+
.mbstate
71+
)
72+
73+
add_header_library(
74+
mbsnrtowcs
75+
HDRS
76+
mbsnrtowcs.h
77+
DEPENDS
78+
libc.hdr.errno_macros
79+
libc.hdr.types.wchar_t
80+
libc.hdr.types.size_t
81+
libc.src.__support.common
82+
libc.src.__support.error_or
83+
libc.src.__support.macros.config
84+
libc.src.__support.macros.null_check
85+
.character_converter
86+
.mbstate
87+
.string_converter
7188
)
7289

7390
add_header_library(

libc/src/__support/wchar/mbsnrtowcs.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===-- Implementation for mbsnrtowcs function ------------------*- C++ -*-===//
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_MBSNRTOWCS_H
10+
#define LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSNRTOWCS_H
11+
12+
#include "hdr/errno_macros.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/error_or.h"
17+
#include "src/__support/macros/config.h"
18+
#include "src/__support/macros/null_check.h"
19+
#include "src/__support/wchar/character_converter.h"
20+
#include "src/__support/wchar/mbstate.h"
21+
#include "src/__support/wchar/string_converter.h"
22+
23+
namespace LIBC_NAMESPACE_DECL {
24+
namespace internal {
25+
26+
LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,
27+
const char **__restrict src,
28+
size_t nmc, size_t len,
29+
mbstate *__restrict ps) {
30+
LIBC_CRASH_ON_NULLPTR(src);
31+
// Checking if mbstate is valid
32+
CharacterConverter char_conv(ps);
33+
if (!char_conv.isValidState())
34+
return Error(EINVAL);
35+
36+
StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps,
37+
len, nmc);
38+
size_t dst_idx = 0;
39+
ErrorOr<char32_t> converted = str_conv.popUTF32();
40+
while (converted.has_value()) {
41+
if (dst != nullptr)
42+
dst[dst_idx] = converted.value();
43+
// null terminator should not be counted in return value
44+
if (converted.value() == L'\0') {
45+
if (dst != nullptr)
46+
*src = nullptr;
47+
return dst_idx;
48+
}
49+
dst_idx++;
50+
converted = str_conv.popUTF32();
51+
}
52+
53+
if (converted.error() == -1) { // if we hit conversion limit
54+
if (dst != nullptr)
55+
*src += str_conv.getSourceIndex();
56+
return dst_idx;
57+
}
58+
59+
return Error(converted.error());
60+
}
61+
62+
} // namespace internal
63+
64+
} // namespace LIBC_NAMESPACE_DECL
65+
66+
#endif // LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSNRTOWCS_H

libc/src/wchar/CMakeLists.txt

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

172+
add_entrypoint_object(
173+
mbstowcs
174+
SRCS
175+
mbstowcs.cpp
176+
HDRS
177+
mbstowcs.h
178+
DEPENDS
179+
libc.hdr.types.size_t
180+
libc.hdr.types.wchar_t
181+
libc.src.__support.common
182+
libc.src.__support.macros.config
183+
libc.src.__support.libc_errno
184+
libc.src.__support.wchar.mbstate
185+
libc.src.__support.wchar.mbsnrtowcs
186+
)
187+
188+
add_entrypoint_object(
189+
mbsrtowcs
190+
SRCS
191+
mbsrtowcs.cpp
192+
HDRS
193+
mbsrtowcs.h
194+
DEPENDS
195+
libc.hdr.types.size_t
196+
libc.hdr.types.wchar_t
197+
libc.src.__support.common
198+
libc.src.__support.macros.config
199+
libc.src.__support.libc_errno
200+
libc.src.__support.wchar.mbstate
201+
libc.src.__support.wchar.mbsnrtowcs
202+
)
203+
204+
add_entrypoint_object(
205+
mbsnrtowcs
206+
SRCS
207+
mbsnrtowcs.cpp
208+
HDRS
209+
mbsnrtowcs.h
210+
DEPENDS
211+
libc.hdr.types.size_t
212+
libc.hdr.types.wchar_t
213+
libc.src.__support.common
214+
libc.src.__support.macros.config
215+
libc.src.__support.libc_errno
216+
libc.src.__support.wchar.mbstate
217+
libc.src.__support.wchar.mbsnrtowcs
218+
)
219+
172220
add_entrypoint_object(
173221
wcstombs
174222
SRCS

libc/src/wchar/mbsnrtowcs.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===-- Implementation of mbsnrtowcs --------------------------------------===//
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/mbsnrtowcs.h"
10+
11+
#include "hdr/types/size_t.h"
12+
#include "hdr/types/wchar_t.h"
13+
#include "src/__support/common.h"
14+
#include "src/__support/libc_errno.h"
15+
#include "src/__support/macros/config.h"
16+
#include "src/__support/wchar/mbsnrtowcs.h"
17+
#include "src/__support/wchar/mbstate.h"
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
21+
LLVM_LIBC_FUNCTION(size_t, mbsnrtowcs,
22+
(wchar_t *__restrict dst, const char **__restrict src,
23+
size_t nmc, size_t len, mbstate_t *__restrict ps)) {
24+
static internal::mbstate internal_mbstate;
25+
// If destination is null, ignore len
26+
len = dst == nullptr ? SIZE_MAX : len;
27+
auto ret = internal::mbsnrtowcs(
28+
dst, src, nmc, len,
29+
ps == nullptr ? &internal_mbstate
30+
: reinterpret_cast<internal::mbstate *>(ps));
31+
if (!ret.has_value()) {
32+
// Encoding failure
33+
libc_errno = ret.error();
34+
return -1;
35+
}
36+
return ret.value();
37+
}
38+
39+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/mbsnrtowcs.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===-- Implementation header for mbsnrtowcs ------------------------------===//
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_MBSNRTOWCS_H
10+
#define LLVM_LIBC_SRC_WCHAR_MBSNRTOWCS_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 mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
20+
size_t nmc, size_t len, mbstate_t *__restrict ps);
21+
22+
} // namespace LIBC_NAMESPACE_DECL
23+
24+
#endif // LLVM_LIBC_SRC_WCHAR_MBSNRTOWCS_H

libc/src/wchar/mbsrtowcs.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===-- Implementation of mbsrtowcs ---------------------------------------===//
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/mbsrtowcs.h"
10+
11+
#include "hdr/types/size_t.h"
12+
#include "hdr/types/wchar_t.h"
13+
#include "src/__support/common.h"
14+
#include "src/__support/libc_errno.h"
15+
#include "src/__support/macros/config.h"
16+
#include "src/__support/wchar/mbsnrtowcs.h"
17+
#include "src/__support/wchar/mbstate.h"
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
21+
LLVM_LIBC_FUNCTION(size_t, mbsrtowcs,
22+
(wchar_t *__restrict dst, const char **__restrict src,
23+
size_t len, mbstate_t *__restrict ps)) {
24+
static internal::mbstate internal_mbstate;
25+
// If destination is null, ignore len
26+
len = dst == nullptr ? SIZE_MAX : len;
27+
auto ret = internal::mbsnrtowcs(
28+
dst, src, SIZE_MAX, len,
29+
ps == nullptr ? &internal_mbstate
30+
: reinterpret_cast<internal::mbstate *>(ps));
31+
if (!ret.has_value()) {
32+
// Encoding failure
33+
libc_errno = ret.error();
34+
return -1;
35+
}
36+
return ret.value();
37+
}
38+
39+
} // namespace LIBC_NAMESPACE_DECL

libc/src/wchar/mbsrtowcs.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===-- Implementation header for mbsrtowcs -------------------------------===//
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_MBSRTOWCS_H
10+
#define LLVM_LIBC_SRC_WCHAR_MBSRTOWCS_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 mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src,
20+
size_t len, mbstate_t *__restrict ps);
21+
22+
} // namespace LIBC_NAMESPACE_DECL
23+
24+
#endif // LLVM_LIBC_SRC_WCHAR_MBSRTOWCS_H

libc/src/wchar/mbstowcs.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===-- Implementation of mbstowcs ----------------------------------------===//
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/mbstowcs.h"
10+
11+
#include "hdr/types/size_t.h"
12+
#include "hdr/types/wchar_t.h"
13+
#include "src/__support/common.h"
14+
#include "src/__support/libc_errno.h"
15+
#include "src/__support/macros/config.h"
16+
#include "src/__support/wchar/mbsnrtowcs.h"
17+
#include "src/__support/wchar/mbstate.h"
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
21+
LLVM_LIBC_FUNCTION(size_t, mbstowcs,
22+
(wchar_t *__restrict pwcs, const char *__restrict s,
23+
size_t n)) {
24+
// If destination is null, ignore n
25+
n = pwcs == nullptr ? SIZE_MAX : n;
26+
static internal::mbstate internal_mbstate;
27+
const char *temp = s;
28+
auto ret = internal::mbsnrtowcs(pwcs, &temp, SIZE_MAX, n, &internal_mbstate);
29+
30+
if (!ret.has_value()) {
31+
// Encoding failure
32+
libc_errno = ret.error();
33+
return -1;
34+
}
35+
return ret.value();
36+
}
37+
38+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)