Index: libc/src/CMakeLists.txt =================================================================== --- libc/src/CMakeLists.txt +++ libc/src/CMakeLists.txt @@ -4,6 +4,7 @@ add_subdirectory(signal) add_subdirectory(stdlib) add_subdirectory(string) +add_subdirectory(uchar) # TODO: Add this target conditional to the target OS. add_subdirectory(sys) add_subdirectory(threads) Index: libc/src/uchar/CMakeLists.txt =================================================================== --- /dev/null +++ libc/src/uchar/CMakeLists.txt @@ -0,0 +1,35 @@ +add_entrypoint_object( + mbrtoc16 + SRCS + mbrtoc16.cpp + HDRS + mbrtoc16.h + #DEPENDS +) + +add_entrypoint_object( + c16rtomb + SRCS + c16rtomb.cpp + HDRS + c16rtomb.h + #DEPENDS +) + +add_entrypoint_object( + mbrtoc32 + SRCS + mbrtoc32.cpp + HDRS + mbrtoc32.h + #DEPENDS +) + +add_entrypoint_object( + c32rtomb + SRCS + c32rtomb.cpp + HDRS + c32rtomb.h + #DEPENDS +) Index: libc/src/uchar/c16rtomb.h =================================================================== --- /dev/null +++ libc/src/uchar/c16rtomb.h @@ -0,0 +1,20 @@ +//===--------------- Implementation header for c16rtomb -----------------===// +// +// 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_UCHAR_C16RTOMB_H +#define LLVM_LIBC_SRC_UCHAR_C16RTOMB_H + +#include "include/uchar.h" + +namespace __llvm_libc { + +size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UCHAR_C16RTOMB_H Index: libc/src/uchar/c16rtomb.cpp =================================================================== --- /dev/null +++ libc/src/uchar/c16rtomb.cpp @@ -0,0 +1,39 @@ +//===-------------------- Implementation of c16rtomb +//-----------------------===// +// +// 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/uchar/c16rtomb.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +size_t LLVM_LIBC_ENTRYPOINT(c16rtomb)(char *restrict s, char16_t c16, + mbstate_t *restrict ps) { + size_t StringSize = 0; + if (c16 >= 0xD800 && c16 <= 0xDFFF) { + c16 = 0xFFFD; // Invalid Replacement Character + } + + if (c16 <= 0x7F) { + StringSize = 1; + s[0] = c16 & 0x7F; + } else if (c16 <= 0x7FF) { + StringSize = 2; + s[0] = 0xC0 | (c16 & ((0x1F << 6) >> 6)); + s[1] = 0x80 | (c16 & 0x3F); + } else if (c16 <= 0xFFFF) { + StringSize = 3; + s[0] = 0xE0 | (c16 & ((0x0F << 12) >> 12)); + s[1] = 0x80 | (c16 & ((0x3F << 6) >> 6)); + s[2] = 0x80 | (c16 & 0x3F); + } + return StringSize; +} + +} // namespace __llvm_libc Index: libc/src/uchar/c32rtomb.h =================================================================== --- /dev/null +++ libc/src/uchar/c32rtomb.h @@ -0,0 +1,20 @@ +//===--------------- Implementation header for c32rtomb -----------------===// +// +// 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_UCHAR_C32RTOMB_H +#define LLVM_LIBC_SRC_UCHAR_C32RTOMB_H + +#include "include/uchar.h" + +namespace __llvm_libc { + +size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UCHAR_C16RTOMB_H Index: libc/src/uchar/c32rtomb.cpp =================================================================== --- /dev/null +++ libc/src/uchar/c32rtomb.cpp @@ -0,0 +1,41 @@ +//===-------------------- Implementation of c32rtomb +//-----------------------===// +// +// 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/uchar/c32rtomb.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +size_t LLVM_LIBC_ENTRYPOINT(c32rtomb)(char *restrict s, char32_t c32, + mbstate_t *restrict ps) { + size_t StringSize = 0; + if (c32 <= 0x7F) { + StringSize = 1; + s[0] = c32 & 0x7F; + } else if (c32 <= 0x7FF) { + StringSize = 2; + s[0] = 0xC0 | (c32 & ((0x1F << 6) >> 6)); + s[1] = 0x80 | (c32 & 0x3F); + } else if (c32 <= 0xFFFF) { + StringSize = 3; + s[0] = 0xE0 | (c32 & ((0x0F << 12) >> 12)); + s[1] = 0x80 | (c32 & ((0x3F << 6) >> 6)); + s[2] = 0x80 | (c32 & 0x3F); + } else if (c32 <= 0x10FFFF) { + StringSize = 4; + s[0] = 0xF0 | (c32 & 0x1C0000) >> 18; + s[1] = 0x80 | (c32 & 0x3F000) >> 12; + s[2] = 0x80 | (c32 & 0xFC0) >> 6; + s[3] = 0x80 | (c32 & 0x3F); + } + return StringSize; +} + +} // namespace __llvm_libc Index: libc/src/uchar/mbrtoc16.h =================================================================== --- /dev/null +++ libc/src/uchar/mbrtoc16.h @@ -0,0 +1,20 @@ +//===---------------- Implementation header for mbrtoc16 -----------------===// +// +// 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_UCHAR_MBRTOC16_H +#define LLVM_LIBC_SRC_UCHAR_MBRTOC16_H + +#include "include/uchar.h" + +namespace __llvm_libc { + +size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, + mbstate_t *restrict ps); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UCHAR_MBRTOC16_H Index: libc/src/uchar/mbrtoc16.cpp =================================================================== --- /dev/null +++ libc/src/uchar/mbrtoc16.cpp @@ -0,0 +1,54 @@ +//===-------------------- Implementation of mbrtoc16 +//-----------------------===// +// +// 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/uchar/mbrtoc16.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +size_t LLVM_LIBC_ENTRYPOINT(mbrtoc16)(char16_t *restrict pc16, + const char *restrict s, size_t n, + mbstate_t *restrict ps) { + size_t StringSize = 0; + char32_t Decoded = 0; + + switch (n) { + case 1: + Decoded = s[0] & 0x7F; + break; + case 2: + Decoded |= (s[0] & 0x1F) << 6; + Decoded |= (s[1] & 0x3F) << 0; + break; + case 3: + Decoded |= (s[0] & 0x0F) << 12; + Decoded |= (s[1] & 0x1F) << 6; + Decoded |= (s[2] & 0x1F) << 0; + break; + case 4: + Decoded |= (s[0] & 0x07) << 18; + Decoded |= (s[1] & 0x3F) << 12; + Decoded |= (s[2] & 0x3F) << 6; + Decoded |= (s[3] & 0x3F) << 0; + break; + } + + if (Decoded <= 0xFFFF) { + StringSize = 1; + pc16[0] = Decoded & 0xFFFF; + } else if (Decoded <= 0x10FFFF) { + StringSize = 2; + pc16[0] = 0xD800 + ((Decoded & 0xFFC00) >> 10); + pc16[1] = 0xDC00 + (Decoded & 0x3FF); + } + return StringSize; +} + +} // namespace __llvm_libc Index: libc/src/uchar/mbrtoc32.h =================================================================== --- /dev/null +++ libc/src/uchar/mbrtoc32.h @@ -0,0 +1,21 @@ +//===---------------- Implementation header for mbrtoc32 -----------------===// +// +// 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_UCHAR_MBRTOC32_H +#define LLVM_LIBC_SRC_UCHAR_MBRTOC32_H + +#include "include/uchar.h" + +namespace __llvm_libc { + +size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, + mbstate_t *restrict ps); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UCHAR_MBRTOC32_H Index: libc/src/uchar/mbrtoc32.cpp =================================================================== --- /dev/null +++ libc/src/uchar/mbrtoc32.cpp @@ -0,0 +1,44 @@ +//===-------------------- Implementation of mbrtoc32 +//-----------------------===// +// +// 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/uchar/mbrtoc32.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +size_t LLVM_LIBC_ENTRYPOINT(mbrtoc32)(char32_t *restrict pc32, + const char *restrict s, size_t n, + mbstate_t *restrict ps) { + size_t StringSize = 1; + + switch (n) { + case 1: + pc32[0] = s[0] & 0x7F; + break; + case 2: + pc32[0] |= (s[0] & 0x1F) << 6; + pc32[0] |= (s[1] & 0x3F) << 0; + break; + case 3: + pc32[0] |= (s[0] & 0x0F) << 12; + pc32[0] |= (s[1] & 0x1F) << 6; + pc32[0] |= (s[2] & 0x1F) << 0; + break; + case 4: + pc32[0] |= (s[0] & 0x07) << 18; + pc32[0] |= (s[1] & 0x3F) << 12; + pc32[0] |= (s[2] & 0x3F) << 6; + pc32[0] |= (s[3] & 0x3F) << 0; + break; + } + return StringSize; +} + +} // namespace __llvm_libc Index: libc/test/src/CMakeLists.txt =================================================================== --- libc/test/src/CMakeLists.txt +++ libc/test/src/CMakeLists.txt @@ -5,3 +5,5 @@ add_subdirectory(string) add_subdirectory(sys) add_subdirectory(threads) +add_subdirectory(uchar) +add_subdirectory(threads)