diff options
Diffstat (limited to 'libc/src/wchar')
28 files changed, 817 insertions, 59 deletions
diff --git a/libc/src/wchar/CMakeLists.txt b/libc/src/wchar/CMakeLists.txt index 7ace1a6..9ba0a06 100644 --- a/libc/src/wchar/CMakeLists.txt +++ b/libc/src/wchar/CMakeLists.txt @@ -1,3 +1,13 @@ +add_header_library( + wchar_utils + HDRS + wchar_utils.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.types.wchar_t + libc.src.__support.common +) + add_entrypoint_object( wcslen SRCS @@ -127,6 +137,21 @@ add_entrypoint_object( ) add_entrypoint_object( + mbsinit + SRCS + mbsinit.cpp + HDRS + mbsinit.h + DEPENDS + libc.hdr.types.wchar_t + libc.hdr.types.mbstate_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.wchar.character_converter + libc.src.__support.wchar.mbstate +) + +add_entrypoint_object( mbrtowc SRCS mbrtowc.cpp @@ -160,6 +185,127 @@ add_entrypoint_object( ) add_entrypoint_object( + mbstowcs + SRCS + mbstowcs.cpp + HDRS + mbstowcs.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.types.wchar_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.null_check + libc.src.__support.libc_errno + libc.src.__support.wchar.mbstate + libc.src.__support.wchar.mbsnrtowcs +) + +add_entrypoint_object( + mbsrtowcs + SRCS + mbsrtowcs.cpp + HDRS + mbsrtowcs.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.types.wchar_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.libc_errno + libc.src.__support.wchar.mbstate + libc.src.__support.wchar.mbsnrtowcs +) + +add_entrypoint_object( + mbsnrtowcs + SRCS + mbsnrtowcs.cpp + HDRS + mbsnrtowcs.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.types.wchar_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.libc_errno + libc.src.__support.wchar.mbstate + libc.src.__support.wchar.mbsnrtowcs +) + +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( + mblen + SRCS + mblen.cpp + HDRS + mblen.h + DEPENDS + libc.hdr.types.size_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.libc_errno + libc.src.__support.wchar.mbrtowc + libc.src.__support.wchar.mbstate +) + +add_entrypoint_object( + mbrlen + SRCS + mbrlen.cpp + HDRS + mbrlen.h + DEPENDS + libc.hdr.types.size_t + libc.hdr.types.mbstate_t + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.wchar.mbrtowc + libc.src.__support.libc_errno + libc.src.__support.wchar.mbstate +) + +add_entrypoint_object( wmemset SRCS wmemset.cpp @@ -215,6 +361,19 @@ add_entrypoint_object( ) add_entrypoint_object( + wcsdup + SRCS + wcsdup.cpp + HDRS + wcsdup.h + DEPENDS + libc.hdr.types.wchar_t + libc.src.__support.libc_errno + libc.src.__support.macros.config + libc.src.string.allocating_string_utils +) + +add_entrypoint_object( wcspbrk SRCS wcspbrk.cpp @@ -255,6 +414,8 @@ add_entrypoint_object( DEPENDS libc.hdr.wchar_macros libc.hdr.types.size_t + libc.src.wchar.wchar_utils + libc.src.__support.macros.null_check ) add_entrypoint_object( @@ -266,6 +427,8 @@ add_entrypoint_object( DEPENDS libc.hdr.wchar_macros libc.hdr.types.size_t + libc.src.wchar.wchar_utils + libc.src.__support.macros.null_check ) add_entrypoint_object( diff --git a/libc/src/wchar/mblen.cpp b/libc/src/wchar/mblen.cpp new file mode 100644 index 0000000..2d15b3e --- /dev/null +++ b/libc/src/wchar/mblen.cpp @@ -0,0 +1,35 @@ +//===-- Implementation of mblen -------------------------------------------===// +// +// 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/mblen.h" + +#include "hdr/types/size_t.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/mbrtowc.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, mblen, (const char *s, size_t n)) { + // returns 0 since UTF-8 encoding is not state-dependent + if (s == nullptr) + return 0; + internal::mbstate internal_mbstate; + auto ret = internal::mbrtowc(nullptr, s, n, &internal_mbstate); + if (!ret.has_value() || static_cast<int>(ret.value()) == -2) { + // Encoding failure + if (!ret.has_value()) + libc_errno = EILSEQ; + return -1; + } + return static_cast<int>(ret.value()); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/mblen.h b/libc/src/wchar/mblen.h new file mode 100644 index 0000000..a315a2f --- /dev/null +++ b/libc/src/wchar/mblen.h @@ -0,0 +1,21 @@ +//===-- Implementation header for mblen -----------------------------------===// +// +// 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_MBLEN_H +#define LLVM_LIBC_SRC_WCHAR_MBLEN_H + +#include "hdr/types/size_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int mblen(const char *s, size_t n); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_MBLEN_H diff --git a/libc/src/wchar/mbrlen.cpp b/libc/src/wchar/mbrlen.cpp new file mode 100644 index 0000000..8de78e0 --- /dev/null +++ b/libc/src/wchar/mbrlen.cpp @@ -0,0 +1,37 @@ +//===-- Implementation of mbrlen ------------------------------------------===// +// +// 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/mbrlen.h" + +#include "hdr/types/mbstate_t.h" +#include "hdr/types/size_t.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/mbrtowc.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(size_t, mbrlen, + (const char *__restrict s, size_t n, + mbstate_t *__restrict ps)) { + static internal::mbstate internal_mbstate; + auto ret = internal::mbrtowc(nullptr, s, n, + 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 diff --git a/libc/src/wchar/mbrlen.h b/libc/src/wchar/mbrlen.h new file mode 100644 index 0000000..08b59cf --- /dev/null +++ b/libc/src/wchar/mbrlen.h @@ -0,0 +1,22 @@ +//===-- Implementation header for mbrlen ----------------------------------===// +// +// 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_MBRLEN_H +#define LLVM_LIBC_SRC_WCHAR_MBRLEN_H + +#include "hdr/types/mbstate_t.h" +#include "hdr/types/size_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +size_t mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_MBRLEN_H diff --git a/libc/src/wchar/mbsinit.cpp b/libc/src/wchar/mbsinit.cpp new file mode 100644 index 0000000..23ba542 --- /dev/null +++ b/libc/src/wchar/mbsinit.cpp @@ -0,0 +1,26 @@ +//===-- Implementation of mbsinit -----------------------------------------===// +// +// 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/mbsinit.h" + +#include "hdr/types/mbstate_t.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/__support/wchar/character_converter.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, mbsinit, (mbstate_t * ps)) { + if (ps == nullptr) + return true; + internal::CharacterConverter cr(reinterpret_cast<internal::mbstate *>(ps)); + return cr.isValidState() && cr.isEmpty(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/mbsinit.h b/libc/src/wchar/mbsinit.h new file mode 100644 index 0000000..fa6be0f --- /dev/null +++ b/libc/src/wchar/mbsinit.h @@ -0,0 +1,22 @@ +//===-- Implementation header for mbsinit ---------------------------------===// +// +// 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_MBSINIT_H +#define LLVM_LIBC_SRC_WCHAR_MBSINIT_H + +#include "hdr/types/mbstate_t.h" +#include "hdr/types/size_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int mbsinit(mbstate_t *ps); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_MBSINIT_H diff --git a/libc/src/wchar/mbsnrtowcs.cpp b/libc/src/wchar/mbsnrtowcs.cpp new file mode 100644 index 0000000..28e0ff3 --- /dev/null +++ b/libc/src/wchar/mbsnrtowcs.cpp @@ -0,0 +1,39 @@ +//===-- Implementation of mbsnrtowcs --------------------------------------===// +// +// 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/mbsnrtowcs.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/mbsnrtowcs.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(size_t, mbsnrtowcs, + (wchar_t *__restrict dst, const char **__restrict src, + size_t nmc, size_t len, mbstate_t *__restrict ps)) { + static internal::mbstate internal_mbstate; + // If destination is null, ignore len + len = dst == nullptr ? SIZE_MAX : len; + auto ret = internal::mbsnrtowcs( + dst, src, nmc, 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 diff --git a/libc/src/wchar/mbsnrtowcs.h b/libc/src/wchar/mbsnrtowcs.h new file mode 100644 index 0000000..0d66b95 --- /dev/null +++ b/libc/src/wchar/mbsnrtowcs.h @@ -0,0 +1,24 @@ +//===-- Implementation header for mbsnrtowcs ------------------------------===// +// +// 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_MBSNRTOWCS_H +#define LLVM_LIBC_SRC_WCHAR_MBSNRTOWCS_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 mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, + size_t nmc, size_t len, mbstate_t *__restrict ps); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_MBSNRTOWCS_H diff --git a/libc/src/wchar/mbsrtowcs.cpp b/libc/src/wchar/mbsrtowcs.cpp new file mode 100644 index 0000000..82ca25a --- /dev/null +++ b/libc/src/wchar/mbsrtowcs.cpp @@ -0,0 +1,39 @@ +//===-- 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/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/mbsnrtowcs.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)) { + static internal::mbstate internal_mbstate; + // If destination is null, ignore len + len = dst == nullptr ? SIZE_MAX : len; + auto ret = internal::mbsnrtowcs( + dst, src, SIZE_MAX, 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 diff --git a/libc/src/wchar/mbsrtowcs.h b/libc/src/wchar/mbsrtowcs.h new file mode 100644 index 0000000..f8d4cc2 --- /dev/null +++ b/libc/src/wchar/mbsrtowcs.h @@ -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 diff --git a/libc/src/wchar/mbstowcs.cpp b/libc/src/wchar/mbstowcs.cpp new file mode 100644 index 0000000..43e953c --- /dev/null +++ b/libc/src/wchar/mbstowcs.cpp @@ -0,0 +1,40 @@ +//===-- Implementation of mbstowcs ----------------------------------------===// +// +// 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/mbstowcs.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/mbsnrtowcs.h" +#include "src/__support/wchar/mbstate.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(size_t, mbstowcs, + (wchar_t *__restrict pwcs, const char *__restrict s, + size_t n)) { + LIBC_CRASH_ON_NULLPTR(s); + // If destination is null, ignore n + n = pwcs == nullptr ? SIZE_MAX : n; + static internal::mbstate internal_mbstate; + const char *temp = s; + auto ret = internal::mbsnrtowcs(pwcs, &temp, SIZE_MAX, n, &internal_mbstate); + + if (!ret.has_value()) { + // Encoding failure + libc_errno = ret.error(); + return -1; + } + return ret.value(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/mbstowcs.h b/libc/src/wchar/mbstowcs.h new file mode 100644 index 0000000..7d08a83 --- /dev/null +++ b/libc/src/wchar/mbstowcs.h @@ -0,0 +1,22 @@ +//===-- Implementation header for mbstowcs --------------------------------===// +// +// 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_MBSTOWCS_H +#define LLVM_LIBC_SRC_WCHAR_MBSTOWCS_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 mbstowcs(wchar_t *__restrict pwcs, const char *__restrict s, size_t n); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_MBSTOWCS_H diff --git a/libc/src/wchar/mbtowc.cpp b/libc/src/wchar/mbtowc.cpp index eae39ba..6d099d4 100644 --- a/libc/src/wchar/mbtowc.cpp +++ b/libc/src/wchar/mbtowc.cpp @@ -25,10 +25,7 @@ LLVM_LIBC_FUNCTION(int, mbtowc, if (s == nullptr) return 0; internal::mbstate internal_mbstate; - // temp ptr to use if pwc is nullptr - wchar_t buf[1]; - auto ret = - internal::mbrtowc(pwc == nullptr ? buf : pwc, s, n, &internal_mbstate); + auto ret = internal::mbrtowc(pwc, s, n, &internal_mbstate); if (!ret.has_value() || static_cast<int>(ret.value()) == -2) { // Encoding failure libc_errno = EILSEQ; diff --git a/libc/src/wchar/wchar_utils.h b/libc/src/wchar/wchar_utils.h new file mode 100644 index 0000000..55a3cee --- /dev/null +++ b/libc/src/wchar/wchar_utils.h @@ -0,0 +1,42 @@ +//===-- wchar utils ---------------------------------------------*- 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_WCHAR_WCHAR_UTILS_H +#define LLVM_LIBC_SRC_WCHAR_WCHAR_UTILS_H + +#include "hdr/types/size_t.h" +#include "hdr/types/wchar_t.h" +#include "src/__support/common.h" +#include "src/__support/macros/attributes.h" // LIBC_INLINE + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +LIBC_INLINE static const wchar_t *wcschr(const wchar_t *s, wchar_t c) { + for (; *s && *s != c; ++s) + ; + return (*s == c) ? s : nullptr; +} + +// bool should be true for wcscspn for complimentary span +// should be false for wcsspn since we want it to span +LIBC_INLINE static size_t wcsspn(const wchar_t *s1, const wchar_t *s2, + bool not_match_set) { + size_t i = 0; + for (; s1[i]; ++i) { + bool in_set = internal::wcschr(s2, s1[i]); + if (in_set == not_match_set) + return i; + } + return i; +} + +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_WCHAR_UTILS_H diff --git a/libc/src/wchar/wcschr.cpp b/libc/src/wchar/wcschr.cpp index defc2ce..8ac4916 100644 --- a/libc/src/wchar/wcschr.cpp +++ b/libc/src/wchar/wcschr.cpp @@ -11,15 +11,14 @@ #include "hdr/types/wchar_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" +#include "wchar_utils.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(const wchar_t *, wcschr, (const wchar_t *s, wchar_t c)) { - for (; *s && *s != c; ++s) - ; - if (*s == c) - return s; - return nullptr; + LIBC_CRASH_ON_NULLPTR(s); + return internal::wcschr(s, c); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/wcscspn.cpp b/libc/src/wchar/wcscspn.cpp index 8869d84..34f3451 100644 --- a/libc/src/wchar/wcscspn.cpp +++ b/libc/src/wchar/wcscspn.cpp @@ -12,23 +12,15 @@ #include "hdr/types/wchar_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" +#include "wchar_utils.h" namespace LIBC_NAMESPACE_DECL { -bool check(wchar_t c, const wchar_t *s2) { - for (int n = 0; s2[n]; ++n) { - if (s2[n] == c) - return false; - } - return true; -} LLVM_LIBC_FUNCTION(size_t, wcscspn, (const wchar_t *s1, const wchar_t *s2)) { - size_t i = 0; - for (; s1[i]; ++i) { - if (!check(s1[i], s2)) - return i; - } - return i; + LIBC_CRASH_ON_NULLPTR(s1); + LIBC_CRASH_ON_NULLPTR(s2); + return internal::wcsspn(s1, s2, /*not_match_set=*/true); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/wcsdup.cpp b/libc/src/wchar/wcsdup.cpp new file mode 100644 index 0000000..d4a13d3 --- /dev/null +++ b/libc/src/wchar/wcsdup.cpp @@ -0,0 +1,27 @@ +//===-- Implementation of wcsdup -----------------------------------------===// +// +// 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/wcsdup.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/string/allocating_string_utils.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(wchar_t *, wcsdup, (const wchar_t *wcs)) { + auto dup = internal::strdup(wcs); + if (dup) + return *dup; + if (wcs != nullptr) + libc_errno = ENOMEM; + return nullptr; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/wcsdup.h b/libc/src/wchar/wcsdup.h new file mode 100644 index 0000000..80b3e52 --- /dev/null +++ b/libc/src/wchar/wcsdup.h @@ -0,0 +1,21 @@ +//===-- Implementation header for wcsdup ----------------------------------===// +// +// 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_WCSDUP_H +#define LLVM_LIBC_SRC_WCHAR_WCSDUP_H + +#include "hdr/types/wchar_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +wchar_t *wcsdup(const wchar_t *wcs); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_WCHAR_WCSDUP_H diff --git a/libc/src/wchar/wcsnrtombs.cpp b/libc/src/wchar/wcsnrtombs.cpp new file mode 100644 index 0000000..7f25b24 --- /dev/null +++ b/libc/src/wchar/wcsnrtombs.cpp @@ -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 diff --git a/libc/src/wchar/wcsnrtombs.h b/libc/src/wchar/wcsnrtombs.h new file mode 100644 index 0000000..bf8add7 --- /dev/null +++ b/libc/src/wchar/wcsnrtombs.h @@ -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 diff --git a/libc/src/wchar/wcspbrk.cpp b/libc/src/wchar/wcspbrk.cpp index a00ba99..f329b73 100644 --- a/libc/src/wchar/wcspbrk.cpp +++ b/libc/src/wchar/wcspbrk.cpp @@ -11,17 +11,10 @@ #include "hdr/types/wchar_t.h" #include "src/__support/common.h" #include "src/__support/macros/null_check.h" +#include "src/wchar/wchar_utils.h" namespace LIBC_NAMESPACE_DECL { -bool contains_char(const wchar_t *str, wchar_t target) { - for (; *str != L'\0'; str++) - if (*str == target) - return true; - - return false; -} - LLVM_LIBC_FUNCTION(const wchar_t *, wcspbrk, (const wchar_t *src, const wchar_t *breakset)) { LIBC_CRASH_ON_NULLPTR(src); @@ -29,7 +22,7 @@ LLVM_LIBC_FUNCTION(const wchar_t *, wcspbrk, // currently O(n * m), can be further optimized to O(n + m) with a hash set for (int src_idx = 0; src[src_idx] != 0; src_idx++) - if (contains_char(breakset, src[src_idx])) + if (internal::wcschr(breakset, src[src_idx])) return src + src_idx; return nullptr; diff --git a/libc/src/wchar/wcsrtombs.cpp b/libc/src/wchar/wcsrtombs.cpp new file mode 100644 index 0000000..9d2508c --- /dev/null +++ b/libc/src/wchar/wcsrtombs.cpp @@ -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 diff --git a/libc/src/wchar/wcsrtombs.h b/libc/src/wchar/wcsrtombs.h new file mode 100644 index 0000000..d23573f --- /dev/null +++ b/libc/src/wchar/wcsrtombs.h @@ -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 diff --git a/libc/src/wchar/wcsspn.cpp b/libc/src/wchar/wcsspn.cpp index 23de381..ae2cf5a 100644 --- a/libc/src/wchar/wcsspn.cpp +++ b/libc/src/wchar/wcsspn.cpp @@ -12,23 +12,15 @@ #include "hdr/types/wchar_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/null_check.h" +#include "wchar_utils.h" namespace LIBC_NAMESPACE_DECL { -bool check(wchar_t c, const wchar_t *s2) { - for (int n = 0; s2[n]; ++n) { - if (s2[n] == c) - return true; - } - return false; -} LLVM_LIBC_FUNCTION(size_t, wcsspn, (const wchar_t *s1, const wchar_t *s2)) { - size_t i = 0; - for (; s1[i]; ++i) { - if (!check(s1[i], s2)) - return i; - } - return i; + LIBC_CRASH_ON_NULLPTR(s1); + LIBC_CRASH_ON_NULLPTR(s2); + return internal::wcsspn(s1, s2, /*not_match_set=*/false); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/wcstok.cpp b/libc/src/wchar/wcstok.cpp index 291efc1..ed4f0aa 100644 --- a/libc/src/wchar/wcstok.cpp +++ b/libc/src/wchar/wcstok.cpp @@ -10,18 +10,12 @@ #include "hdr/types/wchar_t.h" #include "src/__support/common.h" +#include "wchar_utils.h" namespace LIBC_NAMESPACE_DECL { -bool isADelimeter(wchar_t wc, const wchar_t *delimiters) { - for (const wchar_t *delim_ptr = delimiters; *delim_ptr != L'\0'; ++delim_ptr) - if (wc == *delim_ptr) - return true; - return false; -} - LLVM_LIBC_FUNCTION(wchar_t *, wcstok, - (wchar_t *__restrict str, const wchar_t *__restrict delim, + (wchar_t *__restrict str, const wchar_t *__restrict delims, wchar_t **__restrict context)) { if (str == nullptr) { if (*context == nullptr) @@ -30,14 +24,13 @@ LLVM_LIBC_FUNCTION(wchar_t *, wcstok, str = *context; } - wchar_t *tok_start, *tok_end; - for (tok_start = str; *tok_start != L'\0' && isADelimeter(*tok_start, delim); - ++tok_start) - ; + wchar_t *tok_start = str; + while (*tok_start != L'\0' && internal::wcschr(delims, *tok_start)) + ++tok_start; - for (tok_end = tok_start; *tok_end != L'\0' && !isADelimeter(*tok_end, delim); - ++tok_end) - ; + wchar_t *tok_end = tok_start; + while (*tok_end != L'\0' && !internal::wcschr(delims, *tok_end)) + ++tok_end; if (*tok_end != L'\0') { *tok_end = L'\0'; diff --git a/libc/src/wchar/wcstombs.cpp b/libc/src/wchar/wcstombs.cpp new file mode 100644 index 0000000..c3793cb --- /dev/null +++ b/libc/src/wchar/wcstombs.cpp @@ -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 diff --git a/libc/src/wchar/wcstombs.h b/libc/src/wchar/wcstombs.h new file mode 100644 index 0000000..cd0008a --- /dev/null +++ b/libc/src/wchar/wcstombs.h @@ -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 |