diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 0db8c4b39caa..2b70cafd6fbf 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -1,112 +1,114 @@ set(TARGET_LIBC_ENTRYPOINTS # 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 libc.src.ctype.isgraph libc.src.ctype.islower libc.src.ctype.isprint libc.src.ctype.ispunct libc.src.ctype.isspace libc.src.ctype.isupper libc.src.ctype.isxdigit + libc.src.ctype.toascii libc.src.ctype.tolower libc.src.ctype.toupper # errno.h entrypoints libc.src.errno.__errno_location # stdlib.h entrypoints libc.src.stdlib.abs libc.src.stdlib.labs libc.src.stdlib.llabs # string.h entrypoints libc.src.string.bzero libc.src.string.memchr libc.src.string.memcmp libc.src.string.memcpy libc.src.string.memset libc.src.string.memrchr libc.src.string.strcat libc.src.string.strchr libc.src.string.strcpy libc.src.string.strcspn libc.src.string.strlen libc.src.string.strncpy libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr libc.src.string.strspn libc.src.string.strstr libc.src.string.strtok libc.src.string.strtok_r ) set(TARGET_LIBM_ENTRYPOINTS # math.h entrypoints libc.src.math.copysign libc.src.math.copysignf libc.src.math.copysignl libc.src.math.ceil libc.src.math.ceilf libc.src.math.ceill libc.src.math.cosf libc.src.math.expf libc.src.math.exp2f libc.src.math.fabs libc.src.math.fabsf libc.src.math.fabsl libc.src.math.fdim libc.src.math.fdimf libc.src.math.fdiml libc.src.math.floor libc.src.math.floorf libc.src.math.floorl libc.src.math.fmaf libc.src.math.fmax libc.src.math.fmaxf libc.src.math.fmaxl libc.src.math.fmin libc.src.math.fminf libc.src.math.fminl libc.src.math.frexp libc.src.math.frexpf libc.src.math.frexpl libc.src.math.hypot libc.src.math.hypotf libc.src.math.ilogb libc.src.math.ilogbf libc.src.math.ilogbl libc.src.math.ldexp libc.src.math.ldexpf libc.src.math.ldexpl libc.src.math.logb libc.src.math.logbf libc.src.math.logbl libc.src.math.modf libc.src.math.modff libc.src.math.modfl libc.src.math.nextafter libc.src.math.nextafterf libc.src.math.nextafterl libc.src.math.remainderf libc.src.math.remainder libc.src.math.remainderl libc.src.math.remquof libc.src.math.remquo libc.src.math.remquol libc.src.math.round libc.src.math.roundf libc.src.math.roundl libc.src.math.sincosf libc.src.math.sinf libc.src.math.sqrt libc.src.math.sqrtf libc.src.math.sqrtl libc.src.math.trunc libc.src.math.truncf libc.src.math.truncl ) diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index a80a8b4f105b..7c5367a9d528 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -1,171 +1,173 @@ set(TARGET_LIBC_ENTRYPOINTS # assert.h entrypoints libc.src.assert.__assert_fail # 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 libc.src.ctype.isgraph libc.src.ctype.islower libc.src.ctype.isprint libc.src.ctype.ispunct libc.src.ctype.isspace libc.src.ctype.isupper libc.src.ctype.isxdigit + libc.src.ctype.toascii libc.src.ctype.tolower libc.src.ctype.toupper # errno.h entrypoints libc.src.errno.__errno_location # fenv.h entrypoints libc.src.fenv.feclearexcept libc.src.fenv.fegetround libc.src.fenv.fesetround libc.src.fenv.feraiseexcept libc.src.fenv.fetestexcept # signal.h entrypoints libc.src.signal.raise libc.src.signal.sigaction libc.src.signal.sigdelset libc.src.signal.sigaddset libc.src.signal.sigemptyset libc.src.signal.sigprocmask libc.src.signal.sigfillset libc.src.signal.signal # stdlib.h entrypoints libc.src.stdlib._Exit libc.src.stdlib.abort libc.src.stdlib.abs libc.src.stdlib.labs libc.src.stdlib.llabs # string.h entrypoints libc.src.string.bzero libc.src.string.memchr libc.src.string.memcmp libc.src.string.memcpy libc.src.string.memrchr libc.src.string.memset libc.src.string.strcat libc.src.string.strchr libc.src.string.strcmp libc.src.string.strcpy libc.src.string.strcspn libc.src.string.strlen libc.src.string.strncpy libc.src.string.strnlen libc.src.string.strpbrk libc.src.string.strrchr libc.src.string.strspn libc.src.string.strstr libc.src.string.strtok libc.src.string.strtok_r # sys/mman.h entrypoints libc.src.sys.mman.mmap libc.src.sys.mman.munmap # threads.h entrypoints libc.src.threads.call_once libc.src.threads.mtx_init libc.src.threads.mtx_lock libc.src.threads.mtx_unlock libc.src.threads.thrd_create libc.src.threads.thrd_join # time.h entrypoints libc.src.time.mktime # unistd.h entrypoints libc.src.unistd.write ) set(TARGET_LIBM_ENTRYPOINTS # math.h entrypoints libc.src.math.copysign libc.src.math.copysignf libc.src.math.copysignl libc.src.math.ceil libc.src.math.ceilf libc.src.math.ceill libc.src.math.cosf libc.src.math.expf libc.src.math.exp2f libc.src.math.fabs libc.src.math.fabsf libc.src.math.fabsl libc.src.math.fdim libc.src.math.fdimf libc.src.math.fdiml libc.src.math.floor libc.src.math.floorf libc.src.math.floorl libc.src.math.fmaf libc.src.math.fmin libc.src.math.fminf libc.src.math.fminl libc.src.math.fmax libc.src.math.fmaxf libc.src.math.fmaxl libc.src.math.frexp libc.src.math.frexpf libc.src.math.frexpl libc.src.math.hypot libc.src.math.hypotf libc.src.math.ilogb libc.src.math.ilogbf libc.src.math.ilogbl libc.src.math.ldexp libc.src.math.ldexpf libc.src.math.ldexpl libc.src.math.llrint libc.src.math.llrintf libc.src.math.llrintl libc.src.math.llround libc.src.math.llroundf libc.src.math.llroundl libc.src.math.logb libc.src.math.logbf libc.src.math.logbl libc.src.math.lrint libc.src.math.lrintf libc.src.math.lrintl libc.src.math.lround libc.src.math.lroundf libc.src.math.lroundl libc.src.math.modf libc.src.math.modff libc.src.math.modfl libc.src.math.nearbyint libc.src.math.nearbyintf libc.src.math.nearbyintl libc.src.math.nextafter libc.src.math.nextafterf libc.src.math.nextafterl libc.src.math.remainderf libc.src.math.remainder libc.src.math.remainderl libc.src.math.remquof libc.src.math.remquo libc.src.math.remquol libc.src.math.rint libc.src.math.rintf libc.src.math.rintl libc.src.math.round libc.src.math.roundf libc.src.math.roundl libc.src.math.sincosf libc.src.math.sinf libc.src.math.sqrt libc.src.math.sqrtf libc.src.math.sqrtl libc.src.math.trunc libc.src.math.truncf libc.src.math.truncl ) diff --git a/libc/spec/gnu_ext.td b/libc/spec/gnu_ext.td index d85c562d9256..0b0b8ca38c40 100644 --- a/libc/spec/gnu_ext.td +++ b/libc/spec/gnu_ext.td @@ -1,33 +1,50 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> { + HeaderSpec CType = HeaderSpec< + "ctype.h", + [], // Macros + [], // Types + [], // Enumerations + [ + FunctionSpec< + "toascii", + RetValSpec, + [ArgSpec] + >, + ] + >; + HeaderSpec Math = HeaderSpec< "math.h", [], // Macros [], // Types [], // Enumerations [ FunctionSpec< "sincosf", RetValSpec, [ArgSpec, ArgSpec, ArgSpec] >, ] >; HeaderSpec String = HeaderSpec< "string.h", [], // Macros [], // Types [], // Enumerations [ FunctionSpec< "memrchr", RetValSpec, [ArgSpec, ArgSpec, ArgSpec] >, ] >; + let Headers = [ - Math, String, + CType, + Math, + String, ]; } diff --git a/libc/spec/posix.td b/libc/spec/posix.td index 1bf64f082c62..32f6ef5844b1 100644 --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -1,245 +1,260 @@ def SigSetType : NamedType<"sigset_t">; def SigSetPtrType : PtrType; def ConstSigSetPtrType : ConstType; def RestrictedSigSetType : RestrictedPtrType; def ConstRestrictedSigSetType : ConstType; def StructSigaction : NamedType<"struct sigaction">; def StructSigactionPtr : PtrType; def ConstStructSigactionPtr : ConstType; def RestrictedStructSigactionPtr : RestrictedPtrType; def ConstRestrictedStructSigactionPtr : ConstType; def POSIX : StandardSpec<"POSIX"> { PtrType CharPtr = PtrType; RestrictedPtrType RestrictedCharPtr = RestrictedPtrType; RestrictedPtrType CharRestrictedDoublePtr = RestrictedPtrType; ConstType ConstCharPtr = ConstType; ConstType ConstRestrictedCharPtr = ConstType; NamedType OffTType = NamedType<"off_t">; NamedType SSizeTType = NamedType<"ssize_t">; HeaderSpec Errno = HeaderSpec< "errno.h", [ Macro<"E2BIG">, Macro<"EACCES">, Macro<"EADDRINUSE">, Macro<"EADDRNOTAVAIL">, Macro<"EAFNOSUPPORT">, Macro<"EAGAIN">, Macro<"EALREADY">, Macro<"EBADF">, Macro<"EBADMSG">, Macro<"EBUSY">, Macro<"ECANCELED">, Macro<"ECHILD">, Macro<"ECONNABORTED">, Macro<"ECONNREFUSED">, Macro<"ECONNRESET">, Macro<"EDEADLK">, Macro<"EDESTADDRREQ">, Macro<"EDQUOT">, Macro<"EEXIST">, Macro<"EFAULT">, Macro<"EFBIG">, Macro<"EHOSTUNREACH">, Macro<"EIDRM">, Macro<"EINPROGRESS">, Macro<"EINTR">, Macro<"EINVAL">, Macro<"EIO">, Macro<"EISCONN">, Macro<"EISDIR">, Macro<"ELOOP">, Macro<"EMFILE">, Macro<"EMLINK">, Macro<"EMSGSIZE">, Macro<"EMULTIHOP">, Macro<"ENAMETOOLONG">, Macro<"ENETDOWN">, Macro<"ENETRESET">, Macro<"ENETUNREACH">, Macro<"ENFILE">, Macro<"ENOBUFS">, Macro<"ENODATA">, Macro<"ENODEV">, Macro<"ENOENT">, Macro<"ENOEXEC">, Macro<"ENOLCK">, Macro<"ENOLINK">, Macro<"ENOMEM">, Macro<"ENOMSG">, Macro<"ENOPROTOOPT">, Macro<"ENOSPC">, Macro<"ENOSR">, Macro<"ENOSTR">, Macro<"ENOSYS">, Macro<"ENOTCONN">, Macro<"ENOTDIR">, Macro<"ENOTEMPTY">, Macro<"ENOTRECOVERABLE">, Macro<"ENOTSOCK">, Macro<"ENOTSUP">, Macro<"ENOTTY">, Macro<"ENXIO">, Macro<"EOPNOTSUPP">, Macro<"EOVERFLOW">, Macro<"EOWNERDEAD">, Macro<"EPERM">, Macro<"EPIPE">, Macro<"EPROTO">, Macro<"EPROTONOSUPPORT">, Macro<"EPROTOTYPE">, Macro<"EROFS">, Macro<"ESPIPE">, Macro<"ESRCH">, Macro<"ESTALE">, Macro<"ETIME">, Macro<"ETIMEDOUT">, Macro<"ETXTBSY">, Macro<"EWOULDBLOCK">, Macro<"EXDEV">, ], [], // Types [], // Enumerations [] // Functions >; HeaderSpec SysMMan = HeaderSpec< "sys/mman.h", [ // TODO: Add a facility to bunch macros into bitwise-or-able groups. // POSIX requires it, so such thing should be captured in this spec. Macro<"PROT_EXEC">, Macro<"PROT_NONE">, Macro<"PROT_READ">, Macro<"PROT_WRITE">, Macro<"MAP_FIXED">, Macro<"MAP_PRIVATE">, Macro<"MAP_SHARED">, Macro<"MAP_FAILED">, ], [ SizeTType, OffTType, ], [], // Enumerations [ FunctionSpec< "mmap", RetValSpec, [ArgSpec, ArgSpec, ArgSpec, ArgSpec, ArgSpec, ArgSpec] >, FunctionSpec< "munmap", RetValSpec, [ArgSpec, ArgSpec] >, ] >; HeaderSpec Signal = HeaderSpec< "signal.h", [], // Macros [ SigSetType, StructSigaction, ], [], // Enumerations [ FunctionSpec< "sigaction", RetValSpec, [ArgSpec, ArgSpec, ArgSpec] >, FunctionSpec< "sigdelset", RetValSpec, [ArgSpec, ArgSpec] >, FunctionSpec< "sigprocmask", RetValSpec, [ArgSpec, ArgSpec, ArgSpec] >, FunctionSpec< "sigemptyset", RetValSpec, [ArgSpec] >, FunctionSpec< "sigaddset", RetValSpec, [ArgSpec, ArgSpec] >, FunctionSpec< "sigfillset", RetValSpec, [ArgSpec] >, ] >; HeaderSpec UniStd = HeaderSpec< "unistd.h", [], // Macros [ SSizeTType, SizeTType, ], [], // Enumerations [ FunctionSpec< "write", RetValSpec, [ArgSpec, ArgSpec, ArgSpec] >, ] >; HeaderSpec String = HeaderSpec< "string.h", [ Macro<"NULL">, ], [ SizeTType, ], [], // Enumerations [ FunctionSpec< "strnlen", RetValSpec, [ArgSpec, ArgSpec] >, FunctionSpec< "strtok_r", RetValSpec, [ArgSpec, ArgSpec, ArgSpec] >, ] >; + HeaderSpec CType = HeaderSpec< + "ctype.h", + [], // Macros + [], // Types + [], // Enumerations + [ + FunctionSpec< + "isascii", + RetValSpec, + [ArgSpec] + >, + ] + >; + let Headers = [ + CType, Errno, SysMMan, Signal, UniStd, String ]; } diff --git a/libc/src/ctype/CMakeLists.txt b/libc/src/ctype/CMakeLists.txt index da8c4403d959..dd7ee24520f8 100644 --- a/libc/src/ctype/CMakeLists.txt +++ b/libc/src/ctype/CMakeLists.txt @@ -1,137 +1,153 @@ add_header_library( ctype_utils HDRS ctype_utils.h ) add_entrypoint_object( isalnum SRCS isalnum.cpp HDRS isalnum.h DEPENDS .ctype_utils ) add_entrypoint_object( isalpha SRCS isalpha.cpp HDRS isalpha.h DEPENDS .ctype_utils ) +add_entrypoint_object( + isascii + SRCS + isascii.cpp + HDRS + isascii.h +) + add_entrypoint_object( isblank SRCS isblank.cpp HDRS isblank.h ) add_entrypoint_object( iscntrl SRCS iscntrl.cpp HDRS iscntrl.h ) add_entrypoint_object( isdigit SRCS isdigit.cpp HDRS isdigit.h DEPENDS .ctype_utils ) add_entrypoint_object( isgraph SRCS isgraph.cpp HDRS isgraph.h DEPENDS .ctype_utils ) add_entrypoint_object( islower SRCS islower.cpp HDRS islower.h DEPENDS .ctype_utils ) add_entrypoint_object( isprint SRCS isprint.cpp HDRS isprint.h ) add_entrypoint_object( ispunct SRCS ispunct.cpp HDRS ispunct.h DEPENDS .ctype_utils ) add_entrypoint_object( isspace SRCS isspace.cpp HDRS isspace.h ) add_entrypoint_object( isupper SRCS isupper.cpp HDRS isupper.h DEPENDS .ctype_utils ) add_entrypoint_object( isxdigit SRCS isxdigit.cpp HDRS isxdigit.h DEPENDS .ctype_utils ) add_entrypoint_object( tolower SRCS tolower.cpp HDRS tolower.h DEPENDS .ctype_utils ) +add_entrypoint_object( + toascii + SRCS + toascii.cpp + HDRS + toascii.h +) + add_entrypoint_object( toupper SRCS toupper.cpp HDRS toupper.h DEPENDS .ctype_utils ) diff --git a/libc/src/ctype/isascii.cpp b/libc/src/ctype/isascii.cpp new file mode 100644 index 000000000000..c12915ecd6ee --- /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/isascii.h b/libc/src/ctype/isascii.h new file mode 100644 index 000000000000..8ec304489b37 --- /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/toascii.cpp b/libc/src/ctype/toascii.cpp new file mode 100644 index 000000000000..19a97ae91791 --- /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/src/ctype/toascii.h b/libc/src/ctype/toascii.h new file mode 100644 index 000000000000..c3f48a38d84c --- /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/test/src/ctype/CMakeLists.txt b/libc/test/src/ctype/CMakeLists.txt index 4141708fc2b4..83ae6be20206 100644 --- a/libc/test/src/ctype/CMakeLists.txt +++ b/libc/test/src/ctype/CMakeLists.txt @@ -1,141 +1,161 @@ add_libc_testsuite(libc_ctype_unittests) add_libc_unittest( isalnum SUITE libc_ctype_unittests SRCS isalnum_test.cpp DEPENDS libc.src.ctype.isalnum ) add_libc_unittest( isalpha SUITE libc_ctype_unittests SRCS isalpha_test.cpp DEPENDS 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 libc_ctype_unittests SRCS isblank_test.cpp DEPENDS libc.src.ctype.isblank ) add_libc_unittest( iscntrl SUITE libc_ctype_unittests SRCS iscntrl_test.cpp DEPENDS libc.src.ctype.iscntrl ) add_libc_unittest( isdigit SUITE libc_ctype_unittests SRCS isdigit_test.cpp DEPENDS libc.src.ctype.isdigit ) add_libc_unittest( isgraph SUITE libc_ctype_unittests SRCS isgraph_test.cpp DEPENDS libc.src.ctype.isgraph ) add_libc_unittest( islower SUITE libc_ctype_unittests SRCS islower_test.cpp DEPENDS libc.src.ctype.islower ) add_libc_unittest( isprint SUITE libc_ctype_unittests SRCS isprint_test.cpp DEPENDS libc.src.ctype.isprint ) add_libc_unittest( ispunct SUITE libc_ctype_unittests SRCS ispunct_test.cpp DEPENDS libc.src.ctype.ispunct ) add_libc_unittest( isspace SUITE libc_ctype_unittests SRCS isspace_test.cpp DEPENDS libc.src.ctype.isspace ) add_libc_unittest( isupper SUITE libc_ctype_unittests SRCS isupper_test.cpp DEPENDS libc.src.ctype.isupper ) add_libc_unittest( isxdigit SUITE libc_ctype_unittests SRCS isxdigit_test.cpp DEPENDS 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 libc_ctype_unittests SRCS tolower_test.cpp DEPENDS libc.src.ctype.tolower ) add_libc_unittest( toupper SUITE libc_ctype_unittests SRCS toupper_test.cpp DEPENDS libc.src.ctype.toupper ) diff --git a/libc/test/src/ctype/isascii_test.cpp b/libc/test/src/ctype/isascii_test.cpp new file mode 100644 index 000000000000..b5f66d7aef57 --- /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 index 000000000000..1a47ae5b45c3 --- /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); + } +}