[libc-commits] [libc] bad3168 - [libc] add atoi, atol, and atoll
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Thu Aug 19 11:02:55 PDT 2021
Author: Michael Jones
Date: 2021-08-19T18:02:51Z
New Revision: bad3168b99aa3d55f5ac6bf330637aafc558229c
URL: https://github.com/llvm/llvm-project/commit/bad3168b99aa3d55f5ac6bf330637aafc558229c
DIFF: https://github.com/llvm/llvm-project/commit/bad3168b99aa3d55f5ac6bf330637aafc558229c.diff
LOG: [libc] add atoi, atol, and atoll
This is based on the work done to add strtoll and the other strto
functions. The atoi functions also were added to stdc and
entrypoints.txt.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D108330
Added:
libc/src/stdlib/atoi.cpp
libc/src/stdlib/atoi.h
libc/src/stdlib/atol.cpp
libc/src/stdlib/atol.h
libc/src/stdlib/atoll.cpp
libc/src/stdlib/atoll.h
libc/test/src/stdlib/atoi_test.cpp
libc/test/src/stdlib/atol_test.cpp
libc/test/src/stdlib/atoll_test.cpp
Modified:
libc/config/linux/x86_64/entrypoints.txt
libc/spec/stdc.td
libc/src/stdlib/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e99fb4e47cac4..4fb4ad4ce9a7d 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -157,6 +157,9 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdlib._Exit
libc.src.stdlib.abort
libc.src.stdlib.abs
+ libc.src.stdlib.atoi
+ libc.src.stdlib.atol
+ libc.src.stdlib.atoll
libc.src.stdlib.labs
libc.src.stdlib.llabs
libc.src.stdlib.strtol
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 6aa68a3e30c19..dadf90e34f7e3 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -476,6 +476,9 @@ def StdC : StandardSpec<"stdc"> {
[
FunctionSpec<"abort", RetValSpec<NoReturn>, [ArgSpec<VoidType>]>,
FunctionSpec<"abs", RetValSpec<IntType>, [ArgSpec<IntType>]>,
+ FunctionSpec<"atoi", RetValSpec<IntType>, [ArgSpec<ConstCharPtr>]>,
+ FunctionSpec<"atol", RetValSpec<LongType>, [ArgSpec<ConstCharPtr>]>,
+ FunctionSpec<"atoll", RetValSpec<LongLongType>, [ArgSpec<ConstCharPtr>]>,
FunctionSpec<"labs", RetValSpec<LongType>, [ArgSpec<LongType>]>,
FunctionSpec<"llabs", RetValSpec<LongLongType>, [ArgSpec<LongLongType>]>,
FunctionSpec<"strtol", RetValSpec<LongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 642202dde1bd9..cd2f2f1f1e7e4 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -31,6 +31,36 @@ add_entrypoint_object(
libc.src.__support.integer_operations
)
+add_entrypoint_object(
+ atoi
+ SRCS
+ atoi.cpp
+ HDRS
+ atoi.h
+ DEPENDS
+ libc.src.__support.str_conv_utils
+)
+
+add_entrypoint_object(
+ atol
+ SRCS
+ atol.cpp
+ HDRS
+ atol.h
+ DEPENDS
+ libc.src.__support.str_conv_utils
+)
+
+add_entrypoint_object(
+ atoll
+ SRCS
+ atoll.cpp
+ HDRS
+ atoll.h
+ DEPENDS
+ libc.src.__support.str_conv_utils
+)
+
add_entrypoint_object(
labs
SRCS
diff --git a/libc/src/stdlib/atoi.cpp b/libc/src/stdlib/atoi.cpp
new file mode 100644
index 0000000000000..f0e57caf743d5
--- /dev/null
+++ b/libc/src/stdlib/atoi.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of atoi --------------------------------------------===//
+//
+// 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/stdlib/atoi.h"
+#include "src/__support/common.h"
+#include "src/__support/str_conv_utils.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, atoi, (const char *str)) {
+ return internal::strtointeger<int>(str, nullptr, 10);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdlib/atoi.h b/libc/src/stdlib/atoi.h
new file mode 100644
index 0000000000000..bb6c978d42f32
--- /dev/null
+++ b/libc/src/stdlib/atoi.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for atoi --------------------------*- 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_STDLIB_ATOI_H
+#define LLVM_LIBC_SRC_STDLIB_ATOI_H
+
+namespace __llvm_libc {
+
+int atoi(const char *str);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_ATOI_H
diff --git a/libc/src/stdlib/atol.cpp b/libc/src/stdlib/atol.cpp
new file mode 100644
index 0000000000000..8f0ed885a9c97
--- /dev/null
+++ b/libc/src/stdlib/atol.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of atol --------------------------------------------===//
+//
+// 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/stdlib/atol.h"
+#include "src/__support/common.h"
+#include "src/__support/str_conv_utils.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(long, atol, (const char *str)) {
+ return internal::strtointeger<long>(str, nullptr, 10);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdlib/atol.h b/libc/src/stdlib/atol.h
new file mode 100644
index 0000000000000..8ba6337aa6eba
--- /dev/null
+++ b/libc/src/stdlib/atol.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for atol --------------------------*- 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_STDLIB_ATOL_H
+#define LLVM_LIBC_SRC_STDLIB_ATOL_H
+
+namespace __llvm_libc {
+
+long atol(const char *str);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_ATOL_H
diff --git a/libc/src/stdlib/atoll.cpp b/libc/src/stdlib/atoll.cpp
new file mode 100644
index 0000000000000..c75e521382190
--- /dev/null
+++ b/libc/src/stdlib/atoll.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of atoll -------------------------------------------===//
+//
+// 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/stdlib/atoll.h"
+#include "src/__support/common.h"
+#include "src/__support/str_conv_utils.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(long long, atoll, (const char *str)) {
+ return internal::strtointeger<long long>(str, nullptr, 10);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdlib/atoll.h b/libc/src/stdlib/atoll.h
new file mode 100644
index 0000000000000..d99184fdd0591
--- /dev/null
+++ b/libc/src/stdlib/atoll.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for atoll -------------------------*- 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_STDLIB_ATOLL_H
+#define LLVM_LIBC_SRC_STDLIB_ATOLL_H
+
+namespace __llvm_libc {
+
+long long atoll(const char *str);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_ATOLL_H
diff --git a/libc/test/src/stdlib/atoi_test.cpp b/libc/test/src/stdlib/atoi_test.cpp
new file mode 100644
index 0000000000000..892f93ac1b28b
--- /dev/null
+++ b/libc/test/src/stdlib/atoi_test.cpp
@@ -0,0 +1,68 @@
+//===-- Unittests for atoi -----------------------------------------------===//
+//
+// 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/stdlib/atoi.h"
+
+#include "utils/UnitTest/Test.h"
+
+#include <limits.h>
+
+TEST(LlvmLibcAToITest, ValidNumbers) {
+ const char *zero = "0";
+ ASSERT_EQ(__llvm_libc::atoi(zero), 0);
+
+ const char *ten = "10";
+ ASSERT_EQ(__llvm_libc::atoi(ten), 10);
+
+ const char *negative_hundred = "-100";
+ ASSERT_EQ(__llvm_libc::atoi(negative_hundred), -100);
+
+ const char *positive_thousand = "+1000";
+ ASSERT_EQ(__llvm_libc::atoi(positive_thousand), 1000);
+
+ const char *spaces_before = " 12345";
+ ASSERT_EQ(__llvm_libc::atoi(spaces_before), 12345);
+
+ const char *tabs_before = "\t\t\t\t67890";
+ ASSERT_EQ(__llvm_libc::atoi(tabs_before), 67890);
+
+ const char *letters_after = "123abc";
+ ASSERT_EQ(__llvm_libc::atoi(letters_after), 123);
+
+ const char *letters_between = "456def789";
+ ASSERT_EQ(__llvm_libc::atoi(letters_between), 456);
+
+ const char *all_together = "\t 110 times 5 = 550";
+ ASSERT_EQ(__llvm_libc::atoi(all_together), 110);
+
+ const char *biggest_int = "2147483647";
+ ASSERT_EQ(__llvm_libc::atoi(biggest_int), INT_MAX);
+
+ const char *smallest_int = "-2147483648";
+ ASSERT_EQ(__llvm_libc::atoi(smallest_int), INT_MIN);
+}
+
+TEST(LlvmLibcAToITest, NonBaseTenWholeNumbers) {
+ const char *hexadecimal = "0x10";
+ ASSERT_EQ(__llvm_libc::atoi(hexadecimal), 0);
+
+ const char *octal = "010";
+ ASSERT_EQ(__llvm_libc::atoi(octal), 10);
+
+ const char *decimal_point = "5.9";
+ ASSERT_EQ(__llvm_libc::atoi(decimal_point), 5);
+}
+
+TEST(LlvmLibcAToITest, NotNumbers) {
+ const char *ten_as_word = "ten";
+ ASSERT_EQ(__llvm_libc::atoi(ten_as_word), 0);
+
+ const char *lots_of_letters =
+ "wtragsdhfgjykutjdyfhgnchgmjhkyurktfgjhlu;po7urtdjyfhgklyk";
+ ASSERT_EQ(__llvm_libc::atoi(lots_of_letters), 0);
+}
diff --git a/libc/test/src/stdlib/atol_test.cpp b/libc/test/src/stdlib/atol_test.cpp
new file mode 100644
index 0000000000000..a2e0444a629fc
--- /dev/null
+++ b/libc/test/src/stdlib/atol_test.cpp
@@ -0,0 +1,62 @@
+//===-- Unittests for atol -----------------------------------------------===//
+//
+// 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/stdlib/atol.h"
+
+#include "utils/UnitTest/Test.h"
+
+#include <limits.h>
+
+TEST(LlvmLibcAToLTest, ValidNumbers) {
+ const char *zero = "0";
+ ASSERT_EQ(__llvm_libc::atol(zero), 0l);
+
+ const char *ten = "10";
+ ASSERT_EQ(__llvm_libc::atol(ten), 10l);
+
+ const char *negative_hundred = "-100";
+ ASSERT_EQ(__llvm_libc::atol(negative_hundred), -100l);
+
+ const char *positive_thousand = "+1000";
+ ASSERT_EQ(__llvm_libc::atol(positive_thousand), 1000l);
+
+ const char *spaces_before = " 12345";
+ ASSERT_EQ(__llvm_libc::atol(spaces_before), 12345l);
+
+ const char *tabs_before = "\t\t\t\t67890";
+ ASSERT_EQ(__llvm_libc::atol(tabs_before), 67890l);
+
+ const char *letters_after = "123abc";
+ ASSERT_EQ(__llvm_libc::atol(letters_after), 123l);
+
+ const char *letters_between = "456def789";
+ ASSERT_EQ(__llvm_libc::atol(letters_between), 456l);
+
+ const char *all_together = "\t 110 times 5 = 550";
+ ASSERT_EQ(__llvm_libc::atol(all_together), 110l);
+}
+
+TEST(LlvmLibcAToLTest, NonBaseTenWholeNumbers) {
+ const char *hexadecimal = "0x10";
+ ASSERT_EQ(__llvm_libc::atol(hexadecimal), 0l);
+
+ const char *octal = "010";
+ ASSERT_EQ(__llvm_libc::atol(hexadecimal), 10l);
+
+ const char *decimal_point = "5.9";
+ ASSERT_EQ(__llvm_libc::atol(decimal_point), 5l);
+}
+
+TEST(LlvmLibcAToLTest, NotNumbers) {
+ const char *ten_as_word = "ten";
+ ASSERT_EQ(__llvm_libc::atol(ten_as_word), 0l);
+
+ const char *lots_of_letters =
+ "wtragsdhfgjykutjdyfhgnchgmjhkyurktfgjhlu;po7urtdjyfhgklyk";
+ ASSERT_EQ(__llvm_libc::atol(lots_of_letters), 0l);
+}
diff --git a/libc/test/src/stdlib/atoll_test.cpp b/libc/test/src/stdlib/atoll_test.cpp
new file mode 100644
index 0000000000000..c716367295cb8
--- /dev/null
+++ b/libc/test/src/stdlib/atoll_test.cpp
@@ -0,0 +1,68 @@
+//===-- Unittests for atoll -----------------------------------------------===//
+//
+// 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/stdlib/atoll.h"
+
+#include "utils/UnitTest/Test.h"
+
+#include <limits.h>
+
+TEST(LlvmLibcAToLLTest, ValidNumbers) {
+ const char *zero = "0";
+ ASSERT_EQ(__llvm_libc::atoll(zero), 0ll);
+
+ const char *ten = "10";
+ ASSERT_EQ(__llvm_libc::atoll(ten), 10ll);
+
+ const char *negative_hundred = "-100";
+ ASSERT_EQ(__llvm_libc::atoll(negative_hundred), -100ll);
+
+ const char *positive_thousand = "+1000";
+ ASSERT_EQ(__llvm_libc::atoll(positive_thousand), 1000ll);
+
+ const char *spaces_before = " 12345";
+ ASSERT_EQ(__llvm_libc::atoll(spaces_before), 12345ll);
+
+ const char *tabs_before = "\t\t\t\t67890";
+ ASSERT_EQ(__llvm_libc::atoll(tabs_before), 67890ll);
+
+ const char *letters_after = "123abc";
+ ASSERT_EQ(__llvm_libc::atoll(letters_after), 123ll);
+
+ const char *letters_between = "456def789";
+ ASSERT_EQ(__llvm_libc::atoll(letters_between), 456ll);
+
+ const char *all_together = "\t 110 times 5 = 550";
+ ASSERT_EQ(__llvm_libc::atoll(all_together), 110ll);
+
+ const char *biggest_long_long = "9223372036854775807";
+ ASSERT_EQ(__llvm_libc::atoll(biggest_int), LLONG_MAX);
+
+ const char *smallest_long_long = "-9223372036854775808";
+ ASSERT_EQ(__llvm_libc::atoll(smallest_int), LLONG_MIN);
+}
+
+TEST(LlvmLibcAToLLTest, NonBaseTenWholeNumbers) {
+ const char *hexadecimal = "0x10";
+ ASSERT_EQ(__llvm_libc::atoll(hexadecimal), 0ll);
+
+ const char *octal = "010";
+ ASSERT_EQ(__llvm_libc::atoll(hexadecimal), 10ll);
+
+ const char *decimal_point = "5.9";
+ ASSERT_EQ(__llvm_libc::atol(decimal_point), 5l);
+}
+
+TEST(LlvmLibcAToLLTest, NotNumbers) {
+ const char *ten_as_word = "ten";
+ ASSERT_EQ(__llvm_libc::atoll(ten_as_word), 0ll);
+
+ const char *lots_of_letters =
+ "wtragsdhfgjykutjdyfhgnchgmjhkyurktfgjhlu;po7urtdjyfhgklyk";
+ ASSERT_EQ(__llvm_libc::atoll(lots_of_letters), 0ll);
+}
More information about the libc-commits
mailing list