Skip to content

[libc] Implement wcs to mbs family of functions #149421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,9 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.wchar.mbtowc
libc.src.wchar.wcrtomb
libc.src.wchar.wctomb
libc.src.wchar.wcstombs
libc.src.wchar.wcsrtombs
libc.src.wchar.wcsnrtombs
)
endif()

Expand Down
28 changes: 28 additions & 0 deletions libc/include/wchar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,31 @@ functions:
- type: const wchar_t *__restrict
- type: wchar_t **__restrict
- type: int
- name: wcstombs
standards:
- stdc
return_type: size_t
arguments:
- type: char *__restrict
- type: const wchar_t *__restrict
- type: size_t
- name: wcsrtombs
standards:
- stdc
return_type: size_t
arguments:
- type: char *__restrict
- type: const wchar_t **__restrict
- type: size_t
- type: mbstate_t
- name: wcsnrtombs
standards:
- stdc
return_type: size_t
arguments:
- type: char *__restrict
- type: const wchar_t **__restrict
- type: size_t
- type: size_t
- type: mbstate_t

17 changes: 17 additions & 0 deletions libc/src/__support/wchar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,20 @@ add_object_library(
.character_converter
.mbstate
)

add_header_library(
wcsnrtombs
HDRS
wcsnrtombs.h
DEPENDS
libc.hdr.errno_macros
libc.hdr.types.char8_t
libc.hdr.types.char32_t
libc.hdr.types.size_t
libc.hdr.types.wchar_t
libc.src.__support.error_or
libc.src.__support.common
.string_converter
.character_converter
.mbstate
)
69 changes: 69 additions & 0 deletions libc/src/__support/wchar/wcsnrtombs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//===-- Implementation header for wcsnrtombs ------------------------------===//
//
// 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_WCSNRTOMBS_H
#define LLVM_LIBC_SRC__SUPPORT_WCHAR_WCSNRTOMBS_H

#include "hdr/types/char32_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/mbstate.h"
#include "src/__support/wchar/string_converter.h"

namespace LIBC_NAMESPACE_DECL {
namespace internal {

LIBC_INLINE static ErrorOr<size_t> wcsnrtombs(char *__restrict s,
const wchar_t **__restrict pwcs,
size_t nwc, size_t len,
mbstate *ps) {
LIBC_CRASH_ON_NULLPTR(pwcs);
LIBC_CRASH_ON_NULLPTR(ps);

CharacterConverter cr(ps);
if (!cr.isValidState())
return Error(EINVAL);

if (s == nullptr)
len = SIZE_MAX;

StringConverter<char32_t> str_conv(reinterpret_cast<const char32_t *>(*pwcs),
ps, len, nwc);
size_t dst_idx = 0;
ErrorOr<char8_t> converted = str_conv.popUTF8();
while (converted.has_value()) {
if (s != nullptr)
s[dst_idx] = converted.value();

if (converted.value() == '\0') {
if (s != nullptr)
*pwcs = nullptr;
return dst_idx;
}

dst_idx++;
converted = str_conv.popUTF8();
}

if (s != nullptr)
*pwcs += str_conv.getSourceIndex();

if (converted.error() == -1) // if we hit conversion limit
return dst_idx;

return Error(converted.error());
}

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL

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

add_entrypoint_object(
wcstombs
SRCS
wcstombs.cpp
HDRS
wcstombs.h
DEPENDS
libc.hdr.types.wchar_t
libc.src.__support.wchar.mbstate
libc.src.__support.wchar.wcsnrtombs
libc.src.__support.libc_errno
)

add_entrypoint_object(
wcsrtombs
SRCS
wcsrtombs.cpp
HDRS
wcsrtombs.h
DEPENDS
libc.hdr.types.wchar_t
libc.hdr.types.mbstate_t
libc.src.__support.wchar.mbstate
libc.src.__support.wchar.wcsnrtombs
libc.src.__support.libc_errno
)

add_entrypoint_object(
wcsnrtombs
SRCS
wcsnrtombs.cpp
HDRS
wcsnrtombs.h
DEPENDS
libc.hdr.types.wchar_t
libc.hdr.types.mbstate_t
libc.src.__support.wchar.mbstate
libc.src.__support.wchar.wcsnrtombs
libc.src.__support.libc_errno
)

add_entrypoint_object(
wmemset
SRCS
Expand Down
40 changes: 40 additions & 0 deletions libc/src/wchar/wcsnrtombs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===-- Implementation of wcsnrtombs --------------------------------------===//
//
// 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/wcsnrtombs.h"

#include "hdr/types/char32_t.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/wchar/mbstate.h"
#include "src/__support/wchar/wcsnrtombs.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(size_t, wcsnrtombs,
(char *__restrict s, const wchar_t **__restrict pwcs,
size_t nwc, size_t len, mbstate_t *ps)) {
LIBC_CRASH_ON_NULLPTR(pwcs);
static internal::mbstate internal_mbstate;
auto result = internal::wcsnrtombs(
s, pwcs, nwc, len,
ps == nullptr ? &internal_mbstate
: reinterpret_cast<internal::mbstate *>(ps));
if (!result.has_value()) {
libc_errno = result.error();
return -1;
}

return result.value();
}

} // namespace LIBC_NAMESPACE_DECL
24 changes: 24 additions & 0 deletions libc/src/wchar/wcsnrtombs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- Implementation header for wcsnrtombs ------------------------------===//
//
// 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_WCSNRTOMBS_H
#define LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_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 wcsnrtombs(char *__restrict s, const wchar_t **__restrict pwcs,
size_t nwc, size_t len, mbstate_t *ps);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_H
40 changes: 40 additions & 0 deletions libc/src/wchar/wcsrtombs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===-- Implementation of wcsrtombs ---------------------------------------===//
//
// 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/wcsrtombs.h"

#include "hdr/types/char32_t.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/wchar/mbstate.h"
#include "src/__support/wchar/wcsnrtombs.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(size_t, wcsrtombs,
(char *__restrict s, const wchar_t **__restrict pwcs,
size_t n, mbstate_t *ps)) {
LIBC_CRASH_ON_NULLPTR(pwcs);
static internal::mbstate internal_mbstate;
auto result = internal::wcsnrtombs(
s, pwcs, SIZE_MAX, n,
ps == nullptr ? &internal_mbstate
: reinterpret_cast<internal::mbstate *>(ps));
if (!result.has_value()) {
libc_errno = result.error();
return -1;
}

return result.value();
}

} // namespace LIBC_NAMESPACE_DECL
24 changes: 24 additions & 0 deletions libc/src/wchar/wcsrtombs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- Implementation header for wcsrtombs -------------------------------===//
//
// 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_WCSRTOMBS_H
#define LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_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 wcsrtombs(char *__restrict s, const wchar_t **__restrict pwcs, size_t n,
mbstate_t *ps);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_H
38 changes: 38 additions & 0 deletions libc/src/wchar/wcstombs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===-- Implementation of wcstombs ----------------------------------------===//
//
// 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/wcstombs.h"

#include "hdr/types/char32_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/wchar/mbstate.h"
#include "src/__support/wchar/wcsnrtombs.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(size_t, wcstombs,
(char *__restrict s, const wchar_t *__restrict wcs,
size_t n)) {
LIBC_CRASH_ON_NULLPTR(wcs);
static internal::mbstate internal_mbstate;
const wchar_t *wcs_ptr_copy = wcs;
auto result =
internal::wcsnrtombs(s, &wcs_ptr_copy, SIZE_MAX, n, &internal_mbstate);
if (!result.has_value()) {
libc_errno = result.error();
return -1;
}

return result.value();
}

} // namespace LIBC_NAMESPACE_DECL
22 changes: 22 additions & 0 deletions libc/src/wchar/wcstombs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Implementation header for wcstombs --------------------------------===//
//
// 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_WCSTOMBS_H
#define LLVM_LIBC_SRC_WCHAR_WCSTOMBS_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 wcstombs(char *__restrict s, const wchar_t *__restrict pwcs, size_t n);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_WCHAR_WCSTOMBS_H
17 changes: 17 additions & 0 deletions libc/test/src/__support/wchar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,20 @@ add_libc_test(
libc.hdr.errno_macros
libc.hdr.types.char32_t
)

add_libc_test(
wcsnrtombs_test
SUITE
libc-support-tests
SRCS
wcsnrtombs_test.cpp
DEPENDS
libc.src.__support.wchar.string_converter
libc.src.__support.wchar.character_converter
libc.src.__support.wchar.mbstate
libc.src.__support.error_or
libc.src.__support.wchar.wcsnrtombs
libc.hdr.errno_macros
libc.hdr.types.char32_t
libc.hdr.types.char8_t
)
Loading
Loading