[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