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 @@ -45,6 +45,10 @@ libc.src.string.strtok libc.src.string.strtok_r + # inttypes.h entrypoints + libc.src.inttypes.strtoimax + libc.src.inttypes.strtoumax + # stdlib.h entrypoints libc.src.stdlib.atoi libc.src.stdlib.atol diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt --- a/libc/config/linux/aarch64/headers.txt +++ b/libc/config/linux/aarch64/headers.txt @@ -2,6 +2,7 @@ libc.include.ctype libc.include.errno libc.include.fenv + libc.include.inttypes libc.include.math libc.include.stdlib libc.include.string 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 @@ -45,6 +45,10 @@ libc.src.string.strtok libc.src.string.strtok_r + # inttypes.h entrypoints + libc.src.inttypes.strtoimax + libc.src.inttypes.strtoumax + # stdlib.h entrypoints libc.src.stdlib.atoi libc.src.stdlib.atol diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt --- a/libc/config/linux/x86_64/headers.txt +++ b/libc/config/linux/x86_64/headers.txt @@ -2,6 +2,7 @@ libc.include.assert_h libc.include.ctype libc.include.errno + libc.include.inttypes libc.include.math libc.include.signal libc.include.stdio diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt --- a/libc/config/windows/entrypoints.txt +++ b/libc/config/windows/entrypoints.txt @@ -45,6 +45,10 @@ libc.src.string.strtok libc.src.string.strtok_r + # inttypes.h entrypoints + libc.src.inttypes.strtoimax + libc.src.inttypes.strtoumax + # stdlib.h entrypoints libc.src.stdlib.atoi libc.src.stdlib.atol diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -33,6 +33,14 @@ .llvm_libc_common_h ) +add_gen_header( + inttypes + DEF_FILE inttypes.h.def + GEN_HDR inttypes.h + DEPENDS + .llvm_libc_common_h +) + add_gen_header( math DEF_FILE math.h.def diff --git a/libc/include/inttypes.h.def b/libc/include/inttypes.h.def new file mode 100644 --- /dev/null +++ b/libc/include/inttypes.h.def @@ -0,0 +1,17 @@ +//===-- C standard library header inttypes.h ------------------------------===// +// +// 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_INTTYPES_H +#define LLVM_LIBC_INTTYPES_H + +#include <__llvm-libc-common.h> +#include + +%%public_api() + +#endif // LLVM_LIBC_INTTYPES_H diff --git a/libc/spec/spec.td b/libc/spec/spec.td --- a/libc/spec/spec.td +++ b/libc/spec/spec.td @@ -54,6 +54,9 @@ def SizeTType : NamedType<"size_t">; def LongDoublePtr : PtrType; +def IntMaxTType : NamedType<"intmax_t">; +def UIntMaxTType : NamedType<"uintmax_t">; + // _Noreturn is really not a type, but it is convenient to treat it as a type. def NoReturn : NamedType<"_Noreturn void">; diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -489,6 +489,19 @@ ] >; + HeaderSpec IntTypes = HeaderSpec< + "inttypes.h", + [], // Macros + [], // Types + [], // Enumerations + [ + FunctionSpec<"imaxabs", RetValSpec, [ArgSpec]>, + FunctionSpec<"imaxdiv", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"strtoimax", RetValSpec, [ArgSpec, ArgSpec, ArgSpec]>, + FunctionSpec<"strtoumax", RetValSpec, [ArgSpec, ArgSpec, ArgSpec]>, + ] + >; + HeaderSpec Errno = HeaderSpec< "errno.h", [ @@ -653,6 +666,7 @@ String, StdIO, StdLib, + IntTypes, Signal, Threads, Time, diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt --- a/libc/src/CMakeLists.txt +++ b/libc/src/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(ctype) add_subdirectory(errno) add_subdirectory(fenv) +add_subdirectory(inttypes) add_subdirectory(math) add_subdirectory(string) add_subdirectory(stdlib) diff --git a/libc/src/inttypes/CMakeLists.txt b/libc/src/inttypes/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/inttypes/CMakeLists.txt @@ -0,0 +1,19 @@ +add_entrypoint_object( + strtoimax + SRCS + strtoimax.cpp + HDRS + strtoimax.h + DEPENDS + libc.src.__support.str_conv_utils +) + +add_entrypoint_object( + strtoumax + SRCS + strtoumax.cpp + HDRS + strtoumax.h + DEPENDS + libc.src.__support.str_conv_utils +) diff --git a/libc/src/inttypes/strtoimax.h b/libc/src/inttypes/strtoimax.h new file mode 100644 --- /dev/null +++ b/libc/src/inttypes/strtoimax.h @@ -0,0 +1,21 @@ +//===-- Implementation header for strtoimax ---------------------*- 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_INTTYPES_STRTOIMAX_H +#define LLVM_LIBC_SRC_INTTYPES_STRTOIMAX_H + +#include + +namespace __llvm_libc { + +intmax_t strtoimax(const char *__restrict str, char **__restrict str_end, + int base); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_INTTYPES_STRTOIMAX_H diff --git a/libc/src/inttypes/strtoimax.cpp b/libc/src/inttypes/strtoimax.cpp new file mode 100644 --- /dev/null +++ b/libc/src/inttypes/strtoimax.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of strtoimax ---------------------------------------===// +// +// 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/inttypes/strtoimax.h" +#include "src/__support/common.h" +#include "src/__support/str_conv_utils.h" + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(intmax_t, strtoimax, + (const char *__restrict str, char **__restrict str_end, + int base)) { + return internal::strtointeger(str, str_end, base); +} + +} // namespace __llvm_libc diff --git a/libc/src/inttypes/strtoumax.h b/libc/src/inttypes/strtoumax.h new file mode 100644 --- /dev/null +++ b/libc/src/inttypes/strtoumax.h @@ -0,0 +1,21 @@ +//===-- Implementation header for strtoumax ---------------------*- 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_INTTYPES_STRTOUMAX_H +#define LLVM_LIBC_SRC_INTTYPES_STRTOUMAX_H + +#include + +namespace __llvm_libc { + +uintmax_t strtoumax(const char *__restrict str, char **__restrict str_end, + int base); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_INTTYPES_STRTOUMAX_H diff --git a/libc/src/inttypes/strtoumax.cpp b/libc/src/inttypes/strtoumax.cpp new file mode 100644 --- /dev/null +++ b/libc/src/inttypes/strtoumax.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of strtoumax ---------------------------------------===// +// +// 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/inttypes/strtoumax.h" +#include "src/__support/common.h" +#include "src/__support/str_conv_utils.h" + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(uintmax_t, strtoumax, + (const char *__restrict str, char **__restrict str_end, + int base)) { + return internal::strtointeger(str, str_end, base); +} + +} // namespace __llvm_libc diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -29,6 +29,7 @@ add_subdirectory(ctype) add_subdirectory(errno) add_subdirectory(fenv) +add_subdirectory(inttypes) add_subdirectory(math) add_subdirectory(string) add_subdirectory(stdlib) diff --git a/libc/test/src/inttypes/CMakeLists.txt b/libc/test/src/inttypes/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/test/src/inttypes/CMakeLists.txt @@ -0,0 +1,21 @@ +add_libc_testsuite(libc_inttypes_unittests) + +add_libc_unittest( + strtoimax_test + SUITE + libc_inttypes_unittests + SRCS + strtoimax_test.cpp + DEPENDS + libc.src.inttypes.strtoimax +) + +add_libc_unittest( + strtoumax_test + SUITE + libc_inttypes_unittests + SRCS + strtoumax_test.cpp + DEPENDS + libc.src.inttypes.strtoumax +) diff --git a/libc/test/src/inttypes/strtoimax_test.cpp b/libc/test/src/inttypes/strtoimax_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/inttypes/strtoimax_test.cpp @@ -0,0 +1,26 @@ +//===-- Unittests for strtoimax -------------------------------------------===// +// +// 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/inttypes/strtoimax.h" + +#include "utils/UnitTest/Test.h" + +#include +#include +#include + +// strtoimax is equivalent to strtoll on all currently supported configurations. +// Thus to avoid duplicating code there is just one test to make sure that +// strtoimax works at all. For real tests see stdlib/strtoll_test.cpp. + +TEST(LlvmLibcStrToIMaxTest, SimpleCheck) { + const char *ten = "10"; + errno = 0; + ASSERT_EQ(__llvm_libc::strtoimax(ten, nullptr, 10), intmax_t(10)); + ASSERT_EQ(errno, 0); +} diff --git a/libc/test/src/inttypes/strtoumax_test.cpp b/libc/test/src/inttypes/strtoumax_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/inttypes/strtoumax_test.cpp @@ -0,0 +1,27 @@ +//===-- Unittests for strtoumax -------------------------------------------===// +// +// 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/inttypes/strtoumax.h" + +#include "utils/UnitTest/Test.h" + +#include +#include +#include + +// strtoumax is equivalent to strtoull on all currently supported +// configurations. Thus to avoid duplicating code there is just one test to make +// sure that strtoumax works at all. For real tests see +// stdlib/strtoull_test.cpp. + +TEST(LlvmLibcStrToUMaxTest, SimpleCheck) { + const char *ten = "10"; + errno = 0; + ASSERT_EQ(__llvm_libc::strtoumax(ten, nullptr, 10), uintmax_t(10)); + ASSERT_EQ(errno, 0); +}