diff --git a/libc/test/src/inttypes/CMakeLists.txt b/libc/test/src/inttypes/CMakeLists.txt --- a/libc/test/src/inttypes/CMakeLists.txt +++ b/libc/test/src/inttypes/CMakeLists.txt @@ -8,6 +8,7 @@ strtoimax_test.cpp DEPENDS libc.src.inttypes.strtoimax + libc.test.stdlib.strtol_test_support ) add_libc_unittest( @@ -18,6 +19,7 @@ strtoumax_test.cpp DEPENDS libc.src.inttypes.strtoumax + libc.test.stdlib.strtol_test_support ) add_libc_unittest( diff --git a/libc/test/src/inttypes/strtoimax_test.cpp b/libc/test/src/inttypes/strtoimax_test.cpp --- a/libc/test/src/inttypes/strtoimax_test.cpp +++ b/libc/test/src/inttypes/strtoimax_test.cpp @@ -10,17 +10,6 @@ #include "utils/UnitTest/Test.h" -#include -#include -#include +#include "test/src/stdlib/StrtolTest.h" -// 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); -} +STRTOL_TEST(Strtoimax, __llvm_libc::strtoimax) diff --git a/libc/test/src/inttypes/strtoumax_test.cpp b/libc/test/src/inttypes/strtoumax_test.cpp --- a/libc/test/src/inttypes/strtoumax_test.cpp +++ b/libc/test/src/inttypes/strtoumax_test.cpp @@ -10,18 +10,6 @@ #include "utils/UnitTest/Test.h" -#include -#include -#include +#include "test/src/stdlib/StrtolTest.h" -// 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); -} +STRTOL_TEST(Strtoumax, __llvm_libc::strtoumax) diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -14,6 +14,8 @@ atoi_test_support HDRS AtoiTest.h + DEPENDS + libc.src.__support.CPP.type_traits ) add_libc_unittest( @@ -69,6 +71,17 @@ libc.src.stdlib.strtof ) +add_header_library( + strtol_test_support + HDRS + StrtolTest.h + DEPENDS + libc.src.__support.CPP.limits + libc.src.__support.CPP.type_traits + libc.include.errno + libc.src.errno.errno +) + add_libc_unittest( strtol_test SUITE @@ -77,6 +90,7 @@ strtol_test.cpp DEPENDS libc.src.stdlib.strtol + .strtol_test_support ) add_libc_unittest( @@ -98,6 +112,7 @@ strtoll_test.cpp DEPENDS libc.src.stdlib.strtoll + .strtol_test_support ) add_libc_unittest( @@ -108,6 +123,7 @@ strtoul_test.cpp DEPENDS libc.src.stdlib.strtoul + .strtol_test_support ) add_libc_unittest( @@ -118,6 +134,7 @@ strtoull_test.cpp DEPENDS libc.src.stdlib.strtoull + .strtol_test_support ) add_libc_unittest( diff --git a/libc/test/src/stdlib/StrtolTest.h b/libc/test/src/stdlib/StrtolTest.h new file mode 100644 --- /dev/null +++ b/libc/test/src/stdlib/StrtolTest.h @@ -0,0 +1,410 @@ +//===-- A template class for testing strto* functions -----------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/CPP/limits.h" +#include "src/__support/CPP/type_traits.h" +#include "utils/UnitTest/Test.h" + +#include +#include +#include + +using __llvm_libc::cpp::is_signed_v; + +static inline char int_to_b36_char(int input) { + if (input < 0 || input > 36) + return '0'; + if (input < 10) + return static_cast('0' + input); + return static_cast('A' + input - 10); +} + +template +struct StrtoTest : public __llvm_libc::testing::Test { + using FunctionT = ReturnT (*)(const char *, char **, int); + + static constexpr ReturnT T_MAX = + __llvm_libc::cpp::numeric_limits::max(); + static constexpr ReturnT T_MIN = + __llvm_libc::cpp::numeric_limits::min(); + + void InvalidBase(FunctionT func) { + const char *ten = "10"; + errno = 0; + ASSERT_EQ(func(ten, nullptr, -1), ReturnT(0)); + ASSERT_EQ(errno, EINVAL); + } + + void CleanBaseTenDecode(FunctionT func) { + char *str_end = nullptr; + + // TODO: Look into collapsing these repeated segments. + const char *ten = "10"; + errno = 0; + ASSERT_EQ(func(ten, &str_end, 10), ReturnT(10)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - ten, ptrdiff_t(2)); + + errno = 0; + ASSERT_EQ(func(ten, nullptr, 10), ReturnT(10)); + ASSERT_EQ(errno, 0); + + const char *hundred = "100"; + errno = 0; + ASSERT_EQ(func(hundred, &str_end, 10), ReturnT(100)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - hundred, ptrdiff_t(3)); + + const char *big_number = "1234567890"; + errno = 0; + ASSERT_EQ(func(big_number, &str_end, 10), ReturnT(1234567890)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - big_number, ptrdiff_t(10)); + + // This number is larger than 2^32, meaning that if long is only 32 bits + // wide, strtol will return LONG_MAX. + const char *bigger_number = "12345678900"; + errno = 0; + ASSERT_EQ(func(bigger_number, &str_end, 10), + ((sizeof(ReturnT) < 8) ? T_MAX : ReturnT(12345678900))); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - bigger_number, ptrdiff_t(11)); + + const char *too_big_number = "123456789012345678901"; + errno = 0; + ASSERT_EQ(func(too_big_number, &str_end, 10), T_MAX); + ASSERT_EQ(errno, ERANGE); + EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21)); + + const char *long_number_range_test = + "10000000000000000000000000000000000000000000000000"; + errno = 0; + ASSERT_EQ(func(long_number_range_test, &str_end, 10), T_MAX); + ASSERT_EQ(errno, ERANGE); + EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50)); + + // For most negative numbers, the unsigned functions treat it the same as + // casting a negative variable to an unsigned type. + const char *negative = "-100"; + errno = 0; + ASSERT_EQ(func(negative, &str_end, 10), ReturnT(-100)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - negative, ptrdiff_t(4)); + + const char *big_negative_number = "-1234567890"; + errno = 0; + ASSERT_EQ(func(big_negative_number, &str_end, 10), ReturnT(-1234567890)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - big_negative_number, ptrdiff_t(11)); + + const char *too_big_negative_number = "-123456789012345678901"; + errno = 0; + // If the number is signed, it should return the smallest negative number + // for the current type, but if it's unsigned it should max out and return + // the largest positive number for the current type. From the standard: + // "If the correct value is outside the range of representable values, + // LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is + // returned" + // Note that 0 is not on that list. + ASSERT_EQ(func(too_big_negative_number, &str_end, 10), + (is_signed_v ? T_MIN : T_MAX)); + ASSERT_EQ(errno, ERANGE); + EXPECT_EQ(str_end - too_big_negative_number, ptrdiff_t(22)); + } + + void MessyBaseTenDecode(FunctionT func) { + char *str_end = nullptr; + + const char *spaces_before = " 10"; + errno = 0; + ASSERT_EQ(func(spaces_before, &str_end, 10), ReturnT(10)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7)); + + const char *spaces_after = "10 "; + errno = 0; + ASSERT_EQ(func(spaces_after, &str_end, 10), ReturnT(10)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2)); + + const char *word_before = "word10"; + errno = 0; + ASSERT_EQ(func(word_before, &str_end, 10), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - word_before, ptrdiff_t(0)); + + const char *word_after = "10word"; + errno = 0; + ASSERT_EQ(func(word_after, &str_end, 10), ReturnT(10)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - word_after, ptrdiff_t(2)); + + const char *two_numbers = "10 999"; + errno = 0; + ASSERT_EQ(func(two_numbers, &str_end, 10), ReturnT(10)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2)); + + const char *two_signs = "--10 999"; + errno = 0; + ASSERT_EQ(func(two_signs, &str_end, 10), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - two_signs, ptrdiff_t(0)); + + const char *sign_before = "+2=4"; + errno = 0; + ASSERT_EQ(func(sign_before, &str_end, 10), ReturnT(2)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - sign_before, ptrdiff_t(2)); + + const char *sign_after = "2+2=4"; + errno = 0; + ASSERT_EQ(func(sign_after, &str_end, 10), ReturnT(2)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - sign_after, ptrdiff_t(1)); + + const char *tab_before = "\t10"; + errno = 0; + ASSERT_EQ(func(tab_before, &str_end, 10), ReturnT(10)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - tab_before, ptrdiff_t(3)); + + const char *all_together = "\t -12345and+67890"; + errno = 0; + ASSERT_EQ(func(all_together, &str_end, 10), ReturnT(-12345)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - all_together, ptrdiff_t(9)); + + const char *just_spaces = " "; + errno = 0; + ASSERT_EQ(func(just_spaces, &str_end, 10), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0)); + + const char *just_space_and_sign = " +"; + errno = 0; + ASSERT_EQ(func(just_space_and_sign, &str_end, 10), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0)); + } + + void DecodeInOtherBases(FunctionT func) { + char small_string[4] = {'\0', '\0', '\0', '\0'}; + for (int base = 2; base <= 36; ++base) { + for (int first_digit = 0; first_digit <= 36; ++first_digit) { + small_string[0] = int_to_b36_char(first_digit); + if (first_digit < base) { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), + static_cast(first_digit)); + ASSERT_EQ(errno, 0); + } else { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0)); + ASSERT_EQ(errno, 0); + } + } + } + + for (int base = 2; base <= 36; ++base) { + for (int first_digit = 0; first_digit <= 36; ++first_digit) { + small_string[0] = int_to_b36_char(first_digit); + for (int second_digit = 0; second_digit <= 36; ++second_digit) { + small_string[1] = int_to_b36_char(second_digit); + if (first_digit < base && second_digit < base) { + errno = 0; + ASSERT_EQ( + func(small_string, nullptr, base), + static_cast(second_digit + (first_digit * base))); + ASSERT_EQ(errno, 0); + } else if (first_digit < base) { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), + static_cast(first_digit)); + ASSERT_EQ(errno, 0); + } else { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0)); + ASSERT_EQ(errno, 0); + } + } + } + } + + for (int base = 2; base <= 36; ++base) { + for (int first_digit = 0; first_digit <= 36; ++first_digit) { + small_string[0] = int_to_b36_char(first_digit); + for (int second_digit = 0; second_digit <= 36; ++second_digit) { + small_string[1] = int_to_b36_char(second_digit); + for (int third_digit = 0; third_digit <= 36; ++third_digit) { + small_string[2] = int_to_b36_char(third_digit); + + if (first_digit < base && second_digit < base && + third_digit < base) { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), + static_cast(third_digit + + (second_digit * base) + + (first_digit * base * base))); + ASSERT_EQ(errno, 0); + } else if (first_digit < base && second_digit < base) { + errno = 0; + ASSERT_EQ( + func(small_string, nullptr, base), + static_cast(second_digit + (first_digit * base))); + ASSERT_EQ(errno, 0); + } else if (first_digit < base) { + // if the base is 16 there is a special case for the prefix 0X. + // The number is treated as a one digit hexadecimal. + if (base == 16 && first_digit == 0 && second_digit == 33) { + if (third_digit < base) { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), + static_cast(third_digit)); + ASSERT_EQ(errno, 0); + } else { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0)); + ASSERT_EQ(errno, 0); + } + } else { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), + static_cast(first_digit)); + ASSERT_EQ(errno, 0); + } + } else { + errno = 0; + ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0)); + ASSERT_EQ(errno, 0); + } + } + } + } + } + } + + void CleanBaseSixteenDecode(FunctionT func) { + char *str_end = nullptr; + + const char *no_prefix = "123abc"; + errno = 0; + ASSERT_EQ(func(no_prefix, &str_end, 16), ReturnT(0x123abc)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6)); + + const char *yes_prefix = "0x456def"; + errno = 0; + ASSERT_EQ(func(yes_prefix, &str_end, 16), ReturnT(0x456def)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8)); + + const char *letter_after_prefix = "0xabc123"; + errno = 0; + ASSERT_EQ(func(letter_after_prefix, &str_end, 16), ReturnT(0xabc123)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8)); + } + + void MessyBaseSixteenDecode(FunctionT func) { + char *str_end = nullptr; + + const char *just_prefix = "0x"; + errno = 0; + ASSERT_EQ(func(just_prefix, &str_end, 16), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); + + errno = 0; + ASSERT_EQ(func(just_prefix, &str_end, 0), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); + + const char *prefix_with_x_after = "0xx"; + errno = 0; + ASSERT_EQ(func(prefix_with_x_after, &str_end, 16), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); + + errno = 0; + ASSERT_EQ(func(prefix_with_x_after, &str_end, 0), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); + } + + void AutomaticBaseSelection(FunctionT func) { + char *str_end = nullptr; + + const char *base_ten = "12345"; + errno = 0; + ASSERT_EQ(func(base_ten, &str_end, 0), ReturnT(12345)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - base_ten, ptrdiff_t(5)); + + const char *base_sixteen_no_prefix = "123abc"; + errno = 0; + ASSERT_EQ(func(base_sixteen_no_prefix, &str_end, 0), ReturnT(123)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3)); + + const char *base_sixteen_with_prefix = "0x456def"; + errno = 0; + ASSERT_EQ(func(base_sixteen_with_prefix, &str_end, 0), ReturnT(0x456def)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8)); + + const char *base_eight_with_prefix = "012345"; + errno = 0; + ASSERT_EQ(func(base_eight_with_prefix, &str_end, 0), ReturnT(012345)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6)); + + const char *just_zero = "0"; + errno = 0; + ASSERT_EQ(func(just_zero, &str_end, 0), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - just_zero, ptrdiff_t(1)); + + const char *just_zero_x = "0x"; + errno = 0; + ASSERT_EQ(func(just_zero_x, &str_end, 0), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1)); + + const char *just_zero_eight = "08"; + errno = 0; + ASSERT_EQ(func(just_zero_eight, &str_end, 0), ReturnT(0)); + ASSERT_EQ(errno, 0); + EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1)); + } +}; + +template +StrtoTest(ReturnType (*)(const char *)) -> StrtoTest; + +#define STRTOL_TEST(name, func) \ + using LlvmLibc##name##Test = StrtoTest; \ + TEST_F(LlvmLibc##name##Test, InvalidBase) { InvalidBase(func); } \ + TEST_F(LlvmLibc##name##Test, CleanBaseTenDecode) { \ + CleanBaseTenDecode(func); \ + } \ + TEST_F(LlvmLibc##name##Test, MessyBaseTenDecode) { \ + MessyBaseTenDecode(func); \ + } \ + TEST_F(LlvmLibc##name##Test, DecodeInOtherBases) { \ + DecodeInOtherBases(func); \ + } \ + TEST_F(LlvmLibc##name##Test, CleanBaseSixteenDecode) { \ + CleanBaseSixteenDecode(func); \ + } \ + TEST_F(LlvmLibc##name##Test, MessyBaseSixteenDecode) { \ + MessyBaseSixteenDecode(func); \ + } \ + TEST_F(LlvmLibc##name##Test, AutomaticBaseSelection) { \ + AutomaticBaseSelection(func); \ + } diff --git a/libc/test/src/stdlib/strtol_test.cpp b/libc/test/src/stdlib/strtol_test.cpp --- a/libc/test/src/stdlib/strtol_test.cpp +++ b/libc/test/src/stdlib/strtol_test.cpp @@ -10,346 +10,6 @@ #include "utils/UnitTest/Test.h" -#include -#include -#include +#include "StrtolTest.h" -TEST(LlvmLibcStrToLTest, InvalidBase) { - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(ten, nullptr, -1), 0l); - ASSERT_EQ(errno, EINVAL); -} - -TEST(LlvmLibcStrToLTest, CleanBaseTenDecode) { - char *str_end = nullptr; - - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(ten, &str_end, 10), 10l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - ten, ptrdiff_t(2)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(ten, nullptr, 10), 10l); - ASSERT_EQ(errno, 0); - - const char *hundred = "100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(hundred, &str_end, 10), 100l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - hundred, ptrdiff_t(3)); - - const char *negative = "-100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(negative, &str_end, 10), -100l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - negative, ptrdiff_t(4)); - - const char *big_number = "1234567890"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(big_number, &str_end, 10), 1234567890l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - big_number, ptrdiff_t(10)); - - const char *big_negative_number = "-1234567890"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(big_negative_number, &str_end, 10), - -1234567890l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - big_negative_number, ptrdiff_t(11)); - - const char *too_big_number = "123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(too_big_number, &str_end, 10), LONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21)); - - const char *too_big_negative_number = "-123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(too_big_negative_number, &str_end, 10), - LONG_MIN); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_negative_number, ptrdiff_t(22)); - - const char *long_number_range_test = - "10000000000000000000000000000000000000000000000000"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(long_number_range_test, &str_end, 10), - LONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50)); -} - -TEST(LlvmLibcStrToLTest, MessyBaseTenDecode) { - char *str_end = nullptr; - - const char *spaces_before = " 10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(spaces_before, &str_end, 10), 10l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7)); - - const char *spaces_after = "10 "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(spaces_after, &str_end, 10), 10l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2)); - - const char *word_before = "word10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(word_before, &str_end, 10), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_before, ptrdiff_t(0)); - - const char *word_after = "10word"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(word_after, &str_end, 10), 10l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_after, ptrdiff_t(2)); - - const char *two_numbers = "10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(two_numbers, &str_end, 10), 10l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2)); - - const char *two_signs = "--10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(two_signs, &str_end, 10), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_signs, ptrdiff_t(0)); - - const char *sign_before = "+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(sign_before, &str_end, 10), 2l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_before, ptrdiff_t(2)); - - const char *sign_after = "2+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(sign_after, &str_end, 10), 2l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_after, ptrdiff_t(1)); - - const char *tab_before = "\t10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(tab_before, &str_end, 10), 10l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - tab_before, ptrdiff_t(3)); - - const char *all_together = "\t -12345and+67890"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(all_together, &str_end, 10), -12345l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - all_together, ptrdiff_t(9)); - - const char *just_spaces = " "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(just_spaces, &str_end, 10), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0)); - - const char *just_space_and_sign = " +"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(just_space_and_sign, &str_end, 10), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0)); -} - -static char int_to_b36_char(int input) { - if (input < 0 || input > 36) - return '0'; - if (input < 10) - return static_cast('0' + input); - return static_cast('A' + input - 10); -} - -TEST(LlvmLibcStrToLTest, DecodeInOtherBases) { - char small_string[4] = {'\0', '\0', '\0', '\0'}; - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); - ASSERT_EQ(errno, 0); - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), - static_cast(second_digit + (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); - ASSERT_EQ(errno, 0); - } - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - for (int third_digit = 0; third_digit <= 36; ++third_digit) { - small_string[2] = int_to_b36_char(third_digit); - - if (first_digit < base && second_digit < base && third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), - static_cast(third_digit + - (second_digit * base) + - (first_digit * base * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ( - __llvm_libc::strtol(small_string, nullptr, base), - static_cast(second_digit + (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - // if the base is 16 there is a special case for the prefix 0X. - // The number is treated as a one digit hexadecimal. - if (base == 16 && first_digit == 0 && second_digit == 33) { - if (third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), - static_cast(third_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(small_string, nullptr, base), 0l); - ASSERT_EQ(errno, 0); - } - } - } - } - } -} - -TEST(LlvmLibcStrToLTest, CleanBaseSixteenDecode) { - char *str_end = nullptr; - - const char *no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(no_prefix, &str_end, 16), 0x123abcl); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6)); - - const char *yes_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(yes_prefix, &str_end, 16), 0x456defl); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8)); - - const char *letter_after_prefix = "0xabc123"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(letter_after_prefix, &str_end, 16), 0xabc123l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8)); -} - -TEST(LlvmLibcStrToLTest, MessyBaseSixteenDecode) { - char *str_end = nullptr; - - const char *just_prefix = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(just_prefix, &str_end, 16), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(just_prefix, &str_end, 0), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - const char *prefix_with_x_after = "0xx"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(prefix_with_x_after, &str_end, 16), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(prefix_with_x_after, &str_end, 0), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); -} - -TEST(LlvmLibcStrToLTest, AutomaticBaseSelection) { - char *str_end = nullptr; - - const char *base_ten = "12345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(base_ten, &str_end, 0), 12345l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_ten, ptrdiff_t(5)); - - const char *base_sixteen_no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(base_sixteen_no_prefix, &str_end, 0), 123l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3)); - - const char *base_sixteen_with_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(base_sixteen_with_prefix, &str_end, 0), - 0x456defl); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8)); - - const char *base_eight_with_prefix = "012345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(base_eight_with_prefix, &str_end, 0), 012345l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6)); - - const char *just_zero = "0"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(just_zero, &str_end, 0), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero, ptrdiff_t(1)); - - const char *just_zero_x = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(just_zero_x, &str_end, 0), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1)); - - const char *just_zero_eight = "08"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtol(just_zero_eight, &str_end, 0), 0l); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1)); -} +STRTOL_TEST(Strtol, __llvm_libc::strtol) diff --git a/libc/test/src/stdlib/strtoll_test.cpp b/libc/test/src/stdlib/strtoll_test.cpp --- a/libc/test/src/stdlib/strtoll_test.cpp +++ b/libc/test/src/stdlib/strtoll_test.cpp @@ -10,374 +10,6 @@ #include "utils/UnitTest/Test.h" -#include -#include -#include +#include "StrtolTest.h" -TEST(LlvmLibcStrToLLTest, InvalidBase) { - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(ten, nullptr, -1), 0ll); - ASSERT_EQ(errno, EINVAL); -} - -TEST(LlvmLibcStrToLLTest, CleanBaseTenDecode) { - char *str_end = nullptr; - - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(ten, &str_end, 10), 10ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - ten, ptrdiff_t(2)); - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(ten, nullptr, 10), 10ll); - ASSERT_EQ(errno, 0); - - const char *hundred = "100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(hundred, &str_end, 10), 100ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - hundred, ptrdiff_t(3)); - - const char *negative = "-100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(negative, &str_end, 10), -100ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - negative, ptrdiff_t(4)); - - const char *big_number = "123456789012345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(big_number, &str_end, 10), 123456789012345ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - big_number, ptrdiff_t(15)); - - const char *big_negative_number = "-123456789012345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(big_negative_number, &str_end, 10), - -123456789012345ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - big_negative_number, ptrdiff_t(16)); - - const char *long_long_max_number = "9223372036854775807"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(long_long_max_number, &str_end, 10), - 9223372036854775807ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - long_long_max_number, ptrdiff_t(19)); - - const char *long_long_min_number = "-9223372036854775808"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(long_long_min_number, &str_end, 10), - -9223372036854775807ll - 1ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - long_long_min_number, ptrdiff_t(20)); - - const char *too_big_number = "123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(too_big_number, &str_end, 10), LLONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21)); - - const char *too_big_negative_number = "-123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(too_big_negative_number, &str_end, 10), - LLONG_MIN); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_negative_number, ptrdiff_t(22)); - - const char *long_number_range_test = - "10000000000000000000000000000000000000000000000000"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(long_number_range_test, &str_end, 10), - LLONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50)); - - const char *long_long_max_number_with_numbers_after = - "9223372036854775807123"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(long_long_max_number_with_numbers_after, - &str_end, 10), - LLONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ( - static_cast(str_end - long_long_max_number_with_numbers_after), - 22ll); -} - -TEST(LlvmLibcStrToLLTest, MessyBaseTenDecode) { - char *str_end = nullptr; - - const char *spaces_before = " 10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(spaces_before, &str_end, 10), 10ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7)); - - const char *spaces_after = "10 "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(spaces_after, &str_end, 10), 10ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2)); - - const char *word_before = "word10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(word_before, &str_end, 10), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_before, ptrdiff_t(0)); - - const char *word_after = "10word"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(word_after, &str_end, 10), 10ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_after, ptrdiff_t(2)); - - const char *two_numbers = "10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(two_numbers, &str_end, 10), 10ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2)); - - const char *two_signs = "--10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(two_signs, &str_end, 10), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_signs, ptrdiff_t(0)); - - const char *sign_before = "+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(sign_before, &str_end, 10), 2ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_before, ptrdiff_t(2)); - - const char *sign_after = "2+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(sign_after, &str_end, 10), 2ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_after, ptrdiff_t(1)); - - const char *tab_before = "\t10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(tab_before, &str_end, 10), 10ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - tab_before, ptrdiff_t(3)); - - const char *all_together = "\t -12345and+67890"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(all_together, &str_end, 10), -12345ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - all_together, ptrdiff_t(9)); - - const char *just_spaces = " "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(just_spaces, &str_end, 10), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0)); - - const char *just_space_and_sign = " +"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(just_space_and_sign, &str_end, 10), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0)); -} - -static char int_to_b36_char(int input) { - if (input < 0 || input > 36) - return '0'; - if (input < 10) - return static_cast('0' + input); - return static_cast('A' + input - 10); -} - -TEST(LlvmLibcStrToLLTest, DecodeInOtherBases) { - char small_string[4] = {'\0', '\0', '\0', '\0'}; - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 0ll); - ASSERT_EQ(errno, 0); - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ( - __llvm_libc::strtoll(small_string, nullptr, base), - static_cast(second_digit + (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 0ll); - ASSERT_EQ(errno, 0); - } - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - for (int third_digit = 0; third_digit <= 36; ++third_digit) { - small_string[2] = int_to_b36_char(third_digit); - - if (first_digit < base && second_digit < base && third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), - static_cast(third_digit + - (second_digit * base) + - (first_digit * base * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), - static_cast(second_digit + - (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - // if the base is 16 there is a special case for the prefix 0X. - // The number is treated as a one digit hexadecimal. - if (base == 16 && first_digit == 0 && second_digit == 33) { - if (third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), - static_cast(third_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), - 0ll); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 0ll); - ASSERT_EQ(errno, 0); - } - } - } - } - } -} - -TEST(LlvmLibcStrToLLTest, CleanBaseSixteenDecode) { - char *str_end = nullptr; - - const char *no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(no_prefix, &str_end, 16), 0x123abcll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6)); - - const char *yes_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(yes_prefix, &str_end, 16), 0x456defll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8)); - - const char *letter_after_prefix = "0xabc123"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(letter_after_prefix, &str_end, 16), - 0xabc123ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8)); -} - -TEST(LlvmLibcStrToLLTest, MessyBaseSixteenDecode) { - char *str_end = nullptr; - - const char *just_prefix = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(just_prefix, &str_end, 16), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(just_prefix, &str_end, 0), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - const char *prefix_with_x_after = "0xx"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(prefix_with_x_after, &str_end, 16), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(prefix_with_x_after, &str_end, 0), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); -} - -TEST(LlvmLibcStrToLLTest, AutomaticBaseSelection) { - char *str_end = nullptr; - - const char *base_ten = "12345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(base_ten, &str_end, 0), 12345ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_ten, ptrdiff_t(5)); - - const char *base_sixteen_no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(base_sixteen_no_prefix, &str_end, 0), 123ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3)); - - const char *base_sixteen_with_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(base_sixteen_with_prefix, &str_end, 0), - 0x456defll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8)); - - const char *base_eight_with_prefix = "012345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(base_eight_with_prefix, &str_end, 0), - 012345ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6)); - - const char *just_zero = "0"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(just_zero, &str_end, 0), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero, ptrdiff_t(1)); - - const char *just_zero_x = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(just_zero_x, &str_end, 0), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1)); - - const char *just_zero_eight = "08"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoll(just_zero_eight, &str_end, 0), 0ll); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1)); -} +STRTOL_TEST(Strtoll, __llvm_libc::strtoll) diff --git a/libc/test/src/stdlib/strtoul_test.cpp b/libc/test/src/stdlib/strtoul_test.cpp --- a/libc/test/src/stdlib/strtoul_test.cpp +++ b/libc/test/src/stdlib/strtoul_test.cpp @@ -8,344 +8,8 @@ #include "src/stdlib/strtoul.h" -#include -#include -#include - #include "utils/UnitTest/Test.h" -TEST(LlvmLibcStrToULTest, InvalidBase) { - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(ten, nullptr, -1), 0ul); - ASSERT_EQ(errno, EINVAL); -} - -TEST(LlvmLibcStrToULTest, CleanBaseTenDecode) { - char *str_end = nullptr; - - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(ten, &str_end, 10), 10ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - ten, ptrdiff_t(2)); - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(ten, nullptr, 10), 10ul); - ASSERT_EQ(errno, 0); - - const char *hundred = "100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(hundred, &str_end, 10), 100ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - hundred, ptrdiff_t(3)); - - const char *negative = "-100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(negative, &str_end, 10), -(100ul)); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - negative, ptrdiff_t(4)); - - const char *big_number = "1234567890"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(big_number, &str_end, 10), 1234567890ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - big_number, ptrdiff_t(10)); - - const char *too_big_number = "123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(too_big_number, &str_end, 10), ULONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21)); - - const char *too_big_negative_number = "-123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(too_big_negative_number, &str_end, 10), - ULONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_negative_number, ptrdiff_t(22)); - - const char *long_number_range_test = - "10000000000000000000000000000000000000000000000000"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(long_number_range_test, &str_end, 10), - ULONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50)); -} - -TEST(LlvmLibcStrToULTest, MessyBaseTenDecode) { - char *str_end = nullptr; - - const char *spaces_before = " 10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(spaces_before, &str_end, 10), 10ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7)); - - const char *spaces_after = "10 "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(spaces_after, &str_end, 10), 10ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2)); - - const char *word_before = "word10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(word_before, &str_end, 10), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_before, ptrdiff_t(0)); - - const char *word_after = "10word"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(word_after, &str_end, 10), 10ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_after, ptrdiff_t(2)); - - const char *two_numbers = "10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(two_numbers, &str_end, 10), 10ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2)); - - const char *two_signs = "--10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(two_signs, &str_end, 10), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_signs, ptrdiff_t(0)); - - const char *sign_before = "+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(sign_before, &str_end, 10), 2ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_before, ptrdiff_t(2)); - - const char *sign_after = "2+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(sign_after, &str_end, 10), 2ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_after, ptrdiff_t(1)); - - const char *tab_before = "\t10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(tab_before, &str_end, 10), 10ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - tab_before, ptrdiff_t(3)); - - const char *all_together = "\t -12345and+67890"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(all_together, &str_end, 10), -(12345ul)); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - all_together, ptrdiff_t(9)); - - const char *just_spaces = " "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(just_spaces, &str_end, 10), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0)); - - const char *just_space_and_sign = " +"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(just_space_and_sign, &str_end, 10), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0)); -} - -static char int_to_b36_char(int input) { - if (input < 0 || input > 36) - return '0'; - if (input < 10) - return static_cast('0' + input); - return static_cast('A' + input - 10); -} - -TEST(LlvmLibcStrToULTest, DecodeInOtherBases) { - char small_string[4] = {'\0', '\0', '\0', '\0'}; - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), 0ul); - ASSERT_EQ(errno, 0); - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - static_cast(second_digit + - (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), 0ul); - ASSERT_EQ(errno, 0); - } - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - for (int third_digit = 0; third_digit <= 36; ++third_digit) { - small_string[2] = int_to_b36_char(third_digit); - - if (first_digit < base && second_digit < base && third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - static_cast( - third_digit + (second_digit * base) + - (first_digit * base * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - static_cast(second_digit + - (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - // if the base is 16 there is a special case for the prefix 0X. - // The number is treated as a one digit hexadecimal. - if (base == 16 && first_digit == 0 && second_digit == 33) { - if (third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - static_cast(third_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - 0ul); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(small_string, nullptr, base), 0ul); - ASSERT_EQ(errno, 0); - } - } - } - } - } -} - -TEST(LlvmLibcStrToULTest, CleanBaseSixteenDecode) { - char *str_end = nullptr; - - const char *no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(no_prefix, &str_end, 16), 0x123abcul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6)); - - const char *yes_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(yes_prefix, &str_end, 16), 0x456deful); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8)); - - const char *letter_after_prefix = "0xabc123"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(letter_after_prefix, &str_end, 16), - 0xabc123ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8)); -} - -TEST(LlvmLibcStrToULTest, MessyBaseSixteenDecode) { - char *str_end = nullptr; - - const char *just_prefix = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(just_prefix, &str_end, 16), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(just_prefix, &str_end, 0), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - const char *prefix_with_x_after = "0xx"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(prefix_with_x_after, &str_end, 16), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(prefix_with_x_after, &str_end, 0), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); -} - -TEST(LlvmLibcStrToULTest, AutomaticBaseSelection) { - char *str_end = nullptr; - - const char *base_ten = "12345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(base_ten, &str_end, 0), 12345ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_ten, ptrdiff_t(5)); - - const char *base_sixteen_no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(base_sixteen_no_prefix, &str_end, 0), 123ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3)); - - const char *base_sixteen_with_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(base_sixteen_with_prefix, &str_end, 0), - 0x456deful); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8)); - - const char *base_eight_with_prefix = "012345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(base_eight_with_prefix, &str_end, 0), - 012345ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6)); - - const char *just_zero = "0"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(just_zero, &str_end, 0), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero, ptrdiff_t(1)); - - const char *just_zero_x = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(just_zero_x, &str_end, 0), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1)); +#include "StrtolTest.h" - const char *just_zero_eight = "08"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoul(just_zero_eight, &str_end, 0), 0ul); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1)); -} +STRTOL_TEST(Strtoul, __llvm_libc::strtoul) diff --git a/libc/test/src/stdlib/strtoull_test.cpp b/libc/test/src/stdlib/strtoull_test.cpp --- a/libc/test/src/stdlib/strtoull_test.cpp +++ b/libc/test/src/stdlib/strtoull_test.cpp @@ -8,352 +8,8 @@ #include "src/stdlib/strtoull.h" -#include -#include -#include - #include "utils/UnitTest/Test.h" -TEST(LlvmLibcStrToULLTest, InvalidBase) { - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(ten, nullptr, -1), 0ull); - ASSERT_EQ(errno, EINVAL); -} - -TEST(LlvmLibcStrToULLTest, CleanBaseTenDecode) { - char *str_end = nullptr; - - const char *ten = "10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(ten, &str_end, 10), 10ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - ten, ptrdiff_t(2)); - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(ten, nullptr, 10), 10ull); - ASSERT_EQ(errno, 0); - - const char *hundred = "100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(hundred, &str_end, 10), 100ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - hundred, ptrdiff_t(3)); - - const char *negative = "-100"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(negative, &str_end, 10), -(100ull)); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - negative, ptrdiff_t(4)); - - const char *big_number = "123456789012345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(big_number, &str_end, 10), - 123456789012345ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - big_number, ptrdiff_t(15)); - - const char *unsigned_long_long_max_number = "18446744073709551615"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(unsigned_long_long_max_number, &str_end, 10), - 18446744073709551615ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - unsigned_long_long_max_number, ptrdiff_t(20)); - - const char *too_big_number = "123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(too_big_number, &str_end, 10), ULLONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21)); - - const char *too_big_negative_number = "-123456789012345678901"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(too_big_negative_number, &str_end, 10), - ULLONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - too_big_negative_number, ptrdiff_t(22)); - - const char *long_number_range_test = - "10000000000000000000000000000000000000000000000000"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(long_number_range_test, &str_end, 10), - ULLONG_MAX); - ASSERT_EQ(errno, ERANGE); - EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50)); -} - -TEST(LlvmLibcStrToULLTest, MessyBaseTenDecode) { - char *str_end = nullptr; - - const char *spaces_before = " 10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(spaces_before, &str_end, 10), 10ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7)); - - const char *spaces_after = "10 "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(spaces_after, &str_end, 10), 10ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2)); - - const char *word_before = "word10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(word_before, &str_end, 10), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_before, ptrdiff_t(0)); - - const char *word_after = "10word"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(word_after, &str_end, 10), 10ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - word_after, ptrdiff_t(2)); - - const char *two_numbers = "10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(two_numbers, &str_end, 10), 10ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2)); - - const char *two_signs = "--10 999"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(two_signs, &str_end, 10), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - two_signs, ptrdiff_t(0)); - - const char *sign_before = "+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(sign_before, &str_end, 10), 2ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_before, ptrdiff_t(2)); - - const char *sign_after = "2+2=4"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(sign_after, &str_end, 10), 2ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - sign_after, ptrdiff_t(1)); - - const char *tab_before = "\t10"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(tab_before, &str_end, 10), 10ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - tab_before, ptrdiff_t(3)); - - const char *all_together = "\t -12345and+67890"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(all_together, &str_end, 10), -(12345ull)); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - all_together, ptrdiff_t(9)); - - const char *just_spaces = " "; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(just_spaces, &str_end, 10), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0)); - - const char *just_space_and_sign = " +"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(just_space_and_sign, &str_end, 10), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0)); -} - -static char int_to_b36_char(int input) { - if (input < 0 || input > 36) - return '0'; - if (input < 10) - return static_cast('0' + input); - return static_cast('A' + input - 10); -} - -TEST(LlvmLibcStrToULLTest, DecodeInOtherBases) { - char small_string[4] = {'\0', '\0', '\0', '\0'}; - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); - ASSERT_EQ(errno, 0); - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - static_cast(second_digit + - (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); - ASSERT_EQ(errno, 0); - } - } - } - } - - for (int base = 2; base <= 36; ++base) { - for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = int_to_b36_char(first_digit); - for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = int_to_b36_char(second_digit); - for (int third_digit = 0; third_digit <= 36; ++third_digit) { - small_string[2] = int_to_b36_char(third_digit); - - if (first_digit < base && second_digit < base && third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - static_cast( - third_digit + (second_digit * base) + - (first_digit * base * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base && second_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - static_cast( - second_digit + (first_digit * base))); - ASSERT_EQ(errno, 0); - } else if (first_digit < base) { - // if the base is 16 there is a special case for the prefix 0X. - // The number is treated as a one digit hexadecimal. - if (base == 16 && first_digit == 0 && second_digit == 33) { - if (third_digit < base) { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - static_cast(third_digit)); - ASSERT_EQ(errno, 0); - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - 0ull); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), - static_cast(first_digit)); - ASSERT_EQ(errno, 0); - } - } else { - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); - ASSERT_EQ(errno, 0); - } - } - } - } - } -} - -TEST(LlvmLibcStrToULLTest, CleanBaseSixteenDecode) { - char *str_end = nullptr; - - const char *no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(no_prefix, &str_end, 16), 0x123abcull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6)); - - const char *yes_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(yes_prefix, &str_end, 16), 0x456defull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8)); - - const char *letter_after_prefix = "0xabc123"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(letter_after_prefix, &str_end, 16), - 0xabc123ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8)); -} - -TEST(LlvmLibcStrToULLTest, MessyBaseSixteenDecode) { - char *str_end = nullptr; - - const char *just_prefix = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(just_prefix, &str_end, 16), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(just_prefix, &str_end, 0), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1)); - - const char *prefix_with_x_after = "0xx"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(prefix_with_x_after, &str_end, 16), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); - - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(prefix_with_x_after, &str_end, 0), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1)); -} - -TEST(LlvmLibcStrToULLTest, AutomaticBaseSelection) { - char *str_end = nullptr; - - const char *base_ten = "12345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(base_ten, &str_end, 0), 12345ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_ten, ptrdiff_t(5)); - - const char *base_sixteen_no_prefix = "123abc"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(base_sixteen_no_prefix, &str_end, 0), 123ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3)); - - const char *base_sixteen_with_prefix = "0x456def"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(base_sixteen_with_prefix, &str_end, 0), - 0x456defull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8)); - - const char *base_eight_with_prefix = "012345"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(base_eight_with_prefix, &str_end, 0), - 012345ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6)); - - const char *just_zero = "0"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(just_zero, &str_end, 0), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero, ptrdiff_t(1)); - - const char *just_zero_x = "0x"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(just_zero_x, &str_end, 0), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1)); +#include "StrtolTest.h" - const char *just_zero_eight = "08"; - errno = 0; - ASSERT_EQ(__llvm_libc::strtoull(just_zero_eight, &str_end, 0), 0ull); - ASSERT_EQ(errno, 0); - EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1)); -} +STRTOL_TEST(Strtoull, __llvm_libc::strtoull) diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/stdlib/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/stdlib/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/libc/test/src/stdlib/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/stdlib/BUILD.bazel @@ -58,9 +58,15 @@ ], ) +cc_library( + name = "strtol_test_helper", + hdrs = ["StrtolTest.h"], +) + libc_test( name = "strtol_test", srcs = ["strtol_test.cpp"], + deps = [":strtol_test_helper"], libc_function_deps = [ "//libc:strtol", ], @@ -69,6 +75,7 @@ libc_test( name = "strtoll_test", srcs = ["strtoll_test.cpp"], + deps = [":strtol_test_helper"], libc_function_deps = [ "//libc:strtoll", ], @@ -77,6 +84,7 @@ libc_test( name = "strtoul_test", srcs = ["strtoul_test.cpp"], + deps = [":strtol_test_helper"], libc_function_deps = [ "//libc:strtoul", ], @@ -85,6 +93,7 @@ libc_test( name = "strtoull_test", srcs = ["strtoull_test.cpp"], + deps = [":strtol_test_helper"], libc_function_deps = [ "//libc:strtoull", ],