[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
This commit is contained in:
Michael Jones 2021-08-18 17:24:14 +00:00
parent 475f831b17
commit bad3168b99
12 changed files with 345 additions and 0 deletions

View File

@ -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

View File

@ -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>]>,

View File

@ -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

19
libc/src/stdlib/atoi.cpp Normal file
View File

@ -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

18
libc/src/stdlib/atoi.h Normal file
View File

@ -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

19
libc/src/stdlib/atol.cpp Normal file
View File

@ -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

18
libc/src/stdlib/atol.h Normal file
View File

@ -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

19
libc/src/stdlib/atoll.cpp Normal file
View File

@ -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

18
libc/src/stdlib/atoll.h Normal file
View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}