diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -2,6 +2,7 @@ # ctype.h entrypoints libc.src.ctype.isalnum libc.src.ctype.isalpha + libc.src.ctype.isascii libc.src.ctype.isblank libc.src.ctype.iscntrl libc.src.ctype.isdigit @@ -12,6 +13,7 @@ libc.src.ctype.isspace libc.src.ctype.isupper libc.src.ctype.isxdigit + libc.src.ctype.toascii libc.src.ctype.tolower libc.src.ctype.toupper diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -5,6 +5,7 @@ # ctype.h entrypoints libc.src.ctype.isalnum libc.src.ctype.isalpha + libc.src.ctype.isascii libc.src.ctype.isblank libc.src.ctype.iscntrl libc.src.ctype.isdigit @@ -15,6 +16,7 @@ libc.src.ctype.isspace libc.src.ctype.isupper libc.src.ctype.isxdigit + libc.src.ctype.toascii libc.src.ctype.tolower libc.src.ctype.toupper diff --git a/libc/spec/gnu_ext.td b/libc/spec/gnu_ext.td --- a/libc/spec/gnu_ext.td +++ b/libc/spec/gnu_ext.td @@ -1,4 +1,18 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> { + HeaderSpec CType = HeaderSpec< + "ctype.h", + [], // Macros + [], // Types + [], // Enumerations + [ + FunctionSpec< + "toascii", + RetValSpec, + [ArgSpec] + >, + ] + >; + HeaderSpec Math = HeaderSpec< "math.h", [], // Macros @@ -27,7 +41,10 @@ ] >; + let Headers = [ - Math, String, + CType, + Math, + String, ]; } diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -235,7 +235,22 @@ ] >; + HeaderSpec CType = HeaderSpec< + "ctype.h", + [], // Macros + [], // Types + [], // Enumerations + [ + FunctionSpec< + "isascii", + RetValSpec, + [ArgSpec] + >, + ] + >; + let Headers = [ + CType, Errno, SysMMan, Signal, diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt --- a/libc/src/ctype/CMakeLists.txt +++ b/libc/src/ctype/CMakeLists.txt @@ -24,6 +24,14 @@ .ctype_utils ) +add_entrypoint_object( + isascii + SRCS + isascii.cpp + HDRS + isascii.h +) + add_entrypoint_object( isblank SRCS @@ -126,6 +134,14 @@ .ctype_utils ) +add_entrypoint_object( + toascii + SRCS + toascii.cpp + HDRS + toascii.h +) + add_entrypoint_object( toupper SRCS diff --git a/libc/src/ctype/isascii.h b/libc/src/ctype/isascii.h new file mode 100644 --- /dev/null +++ b/libc/src/ctype/isascii.h @@ -0,0 +1,18 @@ +//===-- Implementation header for isascii -------------------------*-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_CTYPE_ISASCII_H +#define LLVM_LIBC_SRC_CTYPE_ISASCII_H + +namespace __llvm_libc { + +int isascii(int c); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_CTYPE_ISASCII_H diff --git a/libc/src/ctype/isascii.cpp b/libc/src/ctype/isascii.cpp new file mode 100644 --- /dev/null +++ b/libc/src/ctype/isascii.cpp @@ -0,0 +1,17 @@ +//===-- Implementation of isascii------------------------------------------===// +// +// 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/ctype/isascii.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, isascii, (int c)) { return (c & (~0x7f)) == 0; } + +} // namespace __llvm_libc diff --git a/libc/src/ctype/toascii.h b/libc/src/ctype/toascii.h new file mode 100644 --- /dev/null +++ b/libc/src/ctype/toascii.h @@ -0,0 +1,18 @@ +//===-- Implementation header for toascii -------------------------*-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_CTYPE_TOASCII_H +#define LLVM_LIBC_SRC_CTYPE_TOASCII_H + +namespace __llvm_libc { + +int toascii(int c); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_CTYPE_TOASCII_H diff --git a/libc/src/ctype/toascii.cpp b/libc/src/ctype/toascii.cpp new file mode 100644 --- /dev/null +++ b/libc/src/ctype/toascii.cpp @@ -0,0 +1,17 @@ +//===-- Implementation of toascii------------------------------------------===// +// +// 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/ctype/toascii.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, toascii, (int c)) { return (c & 0x7f); } + +} // namespace __llvm_libc diff --git a/libc/test/src/ctype/CMakeLists.txt b/libc/test/src/ctype/CMakeLists.txt --- a/libc/test/src/ctype/CMakeLists.txt +++ b/libc/test/src/ctype/CMakeLists.txt @@ -20,6 +20,16 @@ libc.src.ctype.isalpha ) +add_libc_unittest( + isascii + SUITE + libc_ctype_unittests + SRCS + isascii_test.cpp + DEPENDS + libc.src.ctype.isascii +) + add_libc_unittest( isblank SUITE @@ -120,6 +130,16 @@ libc.src.ctype.isxdigit ) +add_libc_unittest( + toascii + SUITE + libc_ctype_unittests + SRCS + toascii_test.cpp + DEPENDS + libc.src.ctype.toascii +) + add_libc_unittest( tolower SUITE diff --git a/libc/test/src/ctype/isascii_test.cpp b/libc/test/src/ctype/isascii_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/ctype/isascii_test.cpp @@ -0,0 +1,23 @@ +//===-- Unittests for isascii----------------------------------------------===// +// +// 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/ctype/isascii.h" + +#include "utils/UnitTest/Test.h" + +TEST(IsAscii, DefaultLocale) { + // Loops through all characters, verifying that ascii characters + // (which are all 7 bit unsigned integers) + // return a non-zero integer and everything else returns zero. + for (int ch = 0; ch < 255; ++ch) { + if (ch <= 0x7f) + EXPECT_NE(__llvm_libc::isascii(ch), 0); + else + EXPECT_EQ(__llvm_libc::isascii(ch), 0); + } +} diff --git a/libc/test/src/ctype/toascii_test.cpp b/libc/test/src/ctype/toascii_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/ctype/toascii_test.cpp @@ -0,0 +1,24 @@ +//===-- Unittests for toascii----------------------------------------------===// +// +// 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/ctype/toascii.h" + +#include "utils/UnitTest/Test.h" + +TEST(ToAscii, DefaultLocale) { + // Loops through all characters, verifying that ascii characters + // (which are all 7 bit unsigned integers) + // return themself, and that all other characters return themself + // mod 128 (which is equivalent to & 0x7f) + for (int ch = 0; ch < 255; ++ch) { + if (ch <= 0x7f) + EXPECT_EQ(__llvm_libc::toascii(ch), ch); + else + EXPECT_EQ(__llvm_libc::toascii(ch), ch & 0x7f); + } +}