Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,7 @@ if(LLVM_LIBC_FULL_BUILD)

# wchar.h entrypoints
libc.src.wchar.mbrtowc
libc.src.wchar.mbsrtowcs
libc.src.wchar.mbtowc
libc.src.wchar.wcrtomb
libc.src.wchar.wctomb
Expand Down
9 changes: 9 additions & 0 deletions libc/include/wchar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ functions:
- type: const char *__restrict
- type: size_t
- type: mbstate_t *__restrict
- name: mbsrtowcs
standards:
- stdc
return_type: size_t
arguments:
- type: wchar_t *__restrict
- type: const char **__restrict
- type: size_t
- type: mbstate_t *__restrict
- name: mbtowc
standards:
- stdc
Expand Down
16 changes: 16 additions & 0 deletions libc/src/__support/wchar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,19 @@ add_object_library(
.character_converter
.mbstate
)

add_object_library(
mbsrtowcs
HDRS
mbsrtowcs.h
SRCS
mbsrtowcs.cpp
DEPENDS
libc.hdr.types.wchar_t
libc.hdr.types.size_t
libc.src.__support.common
libc.src.__support.error_or
libc.src.__support.macros.config
.mbstate
.mbrtowc
)
1 change: 0 additions & 1 deletion libc/src/__support/wchar/character_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ constexpr uint32_t MASK_ENCODED_BITS =
mask_trailing_ones<uint32_t, ENCODED_BITS_PER_UTF8>();
// Maximum value for utf-32 for a utf-8 sequence of a given length
constexpr char32_t MAX_VALUE_PER_UTF8_LEN[] = {0x7f, 0x7ff, 0xffff, 0x10ffff};
constexpr int MAX_UTF8_LENGTH = 4;

CharacterConverter::CharacterConverter(mbstate *mbstate) { state = mbstate; }

Expand Down
2 changes: 2 additions & 0 deletions libc/src/__support/wchar/character_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
namespace LIBC_NAMESPACE_DECL {
namespace internal {

constexpr int MAX_UTF8_LENGTH = 4;

class CharacterConverter {
private:
mbstate *state;
Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/wchar/mbrtowc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ErrorOr<size_t> mbrtowc(wchar_t *__restrict pwc, const char *__restrict s,
return Error(EILSEQ);
}
auto wc = char_conv.pop_utf32();
if (wc.has_value()) {
if (wc.has_value() && pwc != nullptr) {
*pwc = wc.value();
// null terminator -> return 0
if (wc.value() == L'\0')
Expand Down
50 changes: 50 additions & 0 deletions libc/src/__support/wchar/mbsrtowcs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===-- Implementation for mbsrtowcs function -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/__support/wchar/mbsrtowcs.h"
#include "hdr/types/mbstate_t.h"
#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
#include "src/__support/wchar/character_converter.h"
#include "src/__support/wchar/mbrtowc.h"
#include "src/__support/wchar/mbstate.h"

namespace LIBC_NAMESPACE_DECL {
namespace internal {

ErrorOr<size_t> mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src,
size_t len, mbstate *__restrict ps) {
size_t i = 0;
// Converting characters until we reach error or null terminator
for (; i < len; ++i) {
wchar_t temp;
auto check = internal::mbrtowc(dst == nullptr ? &temp : dst, *src,
MAX_UTF8_LENGTH, ps);
// Encoding error/invalid mbstate
if (!check.has_value())
return check;
// Successfully encoded, check for null terminator
if (temp == L'\0' || (dst != nullptr && *dst == L'\0')) {
*src = nullptr;
return i;
}
// Set src to point right after the last character converted
*src = *src + check.value();
// Incrementing destination
if (dst != nullptr)
++dst;
}
return i;
}

} // namespace internal

} // namespace LIBC_NAMESPACE_DECL
29 changes: 29 additions & 0 deletions libc/src/__support/wchar/mbsrtowcs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- Implementation header for mbsrtowcs function ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSRTOWCS
#define LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSRTOWCS

#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
#include "src/__support/wchar/mbstate.h"

namespace LIBC_NAMESPACE_DECL {
namespace internal {

ErrorOr<size_t> mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src,
size_t len, mbstate *__restrict ps);

} // namespace internal

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC___SUPPORT_WCHAR_MBSRTOWCS
18 changes: 18 additions & 0 deletions libc/src/wchar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ add_entrypoint_object(
libc.src.__support.wchar.mbstate
)

add_entrypoint_object(
mbsrtowcs
SRCS
mbsrtowcs.cpp
HDRS
mbsrtowcs.h
DEPENDS
libc.hdr.types.size_t
libc.hdr.types.mbstate_t
libc.hdr.types.wchar_t
libc.src.__support.common
libc.src.__support.macros.config
libc.src.__support.wchar.mbsrtowcs
libc.src.__support.libc_errno
libc.src.__support.wchar.mbstate
libc.src.__support.macros.null_check
)

add_entrypoint_object(
mbtowc
SRCS
Expand Down
41 changes: 41 additions & 0 deletions libc/src/wchar/mbsrtowcs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===-- Implementation of mbsrtowcs ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/wchar/mbsrtowcs.h"

#include "hdr/types/mbstate_t.h"
#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/null_check.h"
#include "src/__support/wchar/mbsrtowcs.h"
#include "src/__support/wchar/mbstate.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(size_t, mbsrtowcs,
(wchar_t *__restrict dst, const char **__restrict src,
size_t len, mbstate_t *__restrict ps)) {
LIBC_CRASH_ON_NULLPTR(src);
static internal::mbstate internal_mbstate;
len = dst == nullptr ? SIZE_MAX : len;
auto ret = internal::mbsrtowcs(
dst, src, len,
ps == nullptr ? &internal_mbstate
: reinterpret_cast<internal::mbstate *>(ps));
if (!ret.has_value()) {
// Encoding failure
libc_errno = ret.error();
return -1;
}
return ret.value();
}

} // namespace LIBC_NAMESPACE_DECL
24 changes: 24 additions & 0 deletions libc/src/wchar/mbsrtowcs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- Implementation header for mbsrtowcs -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_WCHAR_MBSRTOWCS_H
#define LLVM_LIBC_SRC_WCHAR_MBSRTOWCS_H

#include "hdr/types/mbstate_t.h"
#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

size_t mbsrtowcs(wchar_t *__restrict dst, const char **__restrict src,
size_t len, mbstate_t *__restrict ps);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_WCHAR_MBSRTOWCS_H
14 changes: 14 additions & 0 deletions libc/test/src/wchar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ add_libc_test(
libc.test.UnitTest.ErrnoCheckingTest
)

add_libc_test(
mbsrtowcs_test
SUITE
libc_wchar_unittests
SRCS
mbsrtowcs_test.cpp
DEPENDS
libc.src.__support.libc_errno
libc.src.string.memset
libc.src.wchar.mbsrtowcs
libc.hdr.types.mbstate_t
libc.hdr.types.wchar_t
)

add_libc_test(
mbtowc_test
SUITE
Expand Down
Loading
Loading