brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.0 KiB · cadf9e0 Raw
443 lines · c
1//===-- A template class for testing wcsto* functions -----------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "hdr/errno_macros.h"10#include "src/__support/CPP/limits.h"11#include "src/__support/CPP/type_traits.h"12#include "src/__support/macros/properties/architectures.h"13#include "src/__support/wctype_utils.h"14#include "test/UnitTest/ErrnoCheckingTest.h"15#include "test/UnitTest/Test.h"16 17#include <stddef.h>18 19using LIBC_NAMESPACE::cpp::is_signed_v;20 21template <typename ReturnT>22struct WcstoTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest {23  using FunctionT = ReturnT (*)(const wchar_t *, wchar_t **, int);24 25  static constexpr ReturnT T_MAX =26      LIBC_NAMESPACE::cpp::numeric_limits<ReturnT>::max();27  static constexpr ReturnT T_MIN =28      LIBC_NAMESPACE::cpp::numeric_limits<ReturnT>::min();29 30  void InvalidBase(FunctionT func) {31    const wchar_t *ten = L"10";32    ASSERT_EQ(func(ten, nullptr, -1), ReturnT(0));33    ASSERT_ERRNO_EQ(EINVAL);34  }35 36  void CleanBaseTenDecode(FunctionT func) {37    wchar_t *str_end = nullptr;38 39    // TODO: Look into collapsing these repeated segments.40    const wchar_t *ten = L"10";41    ASSERT_EQ(func(ten, &str_end, 10), ReturnT(10));42    ASSERT_ERRNO_SUCCESS();43    EXPECT_EQ(str_end - ten, ptrdiff_t(2));44 45    ASSERT_EQ(func(ten, nullptr, 10), ReturnT(10));46    ASSERT_ERRNO_SUCCESS();47 48    const wchar_t *hundred = L"100";49    ASSERT_EQ(func(hundred, &str_end, 10), ReturnT(100));50    ASSERT_ERRNO_SUCCESS();51    EXPECT_EQ(str_end - hundred, ptrdiff_t(3));52 53    const wchar_t *big_number = L"1234567890";54    ASSERT_EQ(func(big_number, &str_end, 10), ReturnT(1234567890));55    ASSERT_ERRNO_SUCCESS();56    EXPECT_EQ(str_end - big_number, ptrdiff_t(10));57 58    // This number is larger than 2^32, meaning that if long is only 32 bits59    // wide, strtol will return LONG_MAX.60    const wchar_t *bigger_number = L"12345678900";61    if constexpr (sizeof(ReturnT) < 8) {62      ASSERT_EQ(func(bigger_number, &str_end, 10), T_MAX);63      ASSERT_ERRNO_EQ(ERANGE);64    } else {65      ASSERT_EQ(func(bigger_number, &str_end, 10), ReturnT(12345678900));66      ASSERT_ERRNO_SUCCESS();67    }68    EXPECT_EQ(str_end - bigger_number, ptrdiff_t(11));69 70    const wchar_t *too_big_number = L"123456789012345678901";71    ASSERT_EQ(func(too_big_number, &str_end, 10), T_MAX);72    ASSERT_ERRNO_EQ(ERANGE);73    EXPECT_EQ(str_end - too_big_number, ptrdiff_t(21));74 75    const wchar_t *long_number_range_test =76        L"10000000000000000000000000000000000000000000000000";77    ASSERT_EQ(func(long_number_range_test, &str_end, 10), T_MAX);78    ASSERT_ERRNO_EQ(ERANGE);79    EXPECT_EQ(str_end - long_number_range_test, ptrdiff_t(50));80 81    // For most negative numbers, the unsigned functions treat it the same as82    // casting a negative variable to an unsigned type.83    const wchar_t *negative = L"-100";84    ASSERT_EQ(func(negative, &str_end, 10), ReturnT(-100));85    ASSERT_ERRNO_SUCCESS();86    EXPECT_EQ(str_end - negative, ptrdiff_t(4));87 88    const wchar_t *big_negative_number = L"-1234567890";89    ASSERT_EQ(func(big_negative_number, &str_end, 10), ReturnT(-1234567890));90    ASSERT_ERRNO_SUCCESS();91    EXPECT_EQ(str_end - big_negative_number, ptrdiff_t(11));92 93    const wchar_t *too_big_negative_number = L"-123456789012345678901";94    // If the number is signed, it should return the smallest negative number95    // for the current type, but if it's unsigned it should max out and return96    // the largest positive number for the current type. From the standard:97    // "If the correct value is outside the range of representable values,98    // LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is99    // returned"100    // Note that 0 is not on that list.101    ASSERT_EQ(func(too_big_negative_number, &str_end, 10),102              (is_signed_v<ReturnT> ? T_MIN : T_MAX));103    ASSERT_ERRNO_EQ(ERANGE);104    EXPECT_EQ(str_end - too_big_negative_number, ptrdiff_t(22));105  }106 107  void MessyBaseTenDecode(FunctionT func) {108    wchar_t *str_end = nullptr;109 110    const wchar_t *spaces_before = L"     10";111    ASSERT_EQ(func(spaces_before, &str_end, 10), ReturnT(10));112    ASSERT_ERRNO_SUCCESS();113    EXPECT_EQ(str_end - spaces_before, ptrdiff_t(7));114 115    const wchar_t *spaces_after = L"10      ";116    ASSERT_EQ(func(spaces_after, &str_end, 10), ReturnT(10));117    ASSERT_ERRNO_SUCCESS();118    EXPECT_EQ(str_end - spaces_after, ptrdiff_t(2));119 120    const wchar_t *word_before = L"word10";121    ASSERT_EQ(func(word_before, &str_end, 10), ReturnT(0));122    ASSERT_ERRNO_SUCCESS();123    EXPECT_EQ(str_end - word_before, ptrdiff_t(0));124 125    const wchar_t *word_after = L"10word";126    ASSERT_EQ(func(word_after, &str_end, 10), ReturnT(10));127    ASSERT_ERRNO_SUCCESS();128    EXPECT_EQ(str_end - word_after, ptrdiff_t(2));129 130    const wchar_t *two_numbers = L"10 999";131    ASSERT_EQ(func(two_numbers, &str_end, 10), ReturnT(10));132    ASSERT_ERRNO_SUCCESS();133    EXPECT_EQ(str_end - two_numbers, ptrdiff_t(2));134 135    const wchar_t *two_signs = L"--10 999";136    ASSERT_EQ(func(two_signs, &str_end, 10), ReturnT(0));137    ASSERT_ERRNO_SUCCESS();138    EXPECT_EQ(str_end - two_signs, ptrdiff_t(0));139 140    const wchar_t *sign_before = L"+2=4";141    ASSERT_EQ(func(sign_before, &str_end, 10), ReturnT(2));142    ASSERT_ERRNO_SUCCESS();143    EXPECT_EQ(str_end - sign_before, ptrdiff_t(2));144 145    const wchar_t *sign_after = L"2+2=4";146    ASSERT_EQ(func(sign_after, &str_end, 10), ReturnT(2));147    ASSERT_ERRNO_SUCCESS();148    EXPECT_EQ(str_end - sign_after, ptrdiff_t(1));149 150    const wchar_t *tab_before = L"\t10";151    ASSERT_EQ(func(tab_before, &str_end, 10), ReturnT(10));152    ASSERT_ERRNO_SUCCESS();153    EXPECT_EQ(str_end - tab_before, ptrdiff_t(3));154 155    const wchar_t *all_together = L"\t  -12345and+67890";156    ASSERT_EQ(func(all_together, &str_end, 10), ReturnT(-12345));157    ASSERT_ERRNO_SUCCESS();158    EXPECT_EQ(str_end - all_together, ptrdiff_t(9));159 160    const wchar_t *just_spaces = L"  ";161    ASSERT_EQ(func(just_spaces, &str_end, 10), ReturnT(0));162    ASSERT_ERRNO_SUCCESS();163    EXPECT_EQ(str_end - just_spaces, ptrdiff_t(0));164 165    const wchar_t *just_space_and_sign = L" +";166    ASSERT_EQ(func(just_space_and_sign, &str_end, 10), ReturnT(0));167    ASSERT_ERRNO_SUCCESS();168    EXPECT_EQ(str_end - just_space_and_sign, ptrdiff_t(0));169  }170 171  void DecodeInOtherBases(FunctionT func) {172    // This test is excessively slow on the GPU, so we limit the innermost loop.173#if defined(LIBC_TARGET_ARCH_IS_GPU)174    constexpr int limit = 0;175#else176    constexpr int limit = 36;177#endif178    wchar_t small_string[4] = {L'\0', L'\0', L'\0', L'\0'};179    for (int base = 2; base <= 36; ++base) {180      for (int first_digit = 0; first_digit <= 36; ++first_digit) {181        small_string[0] =182            LIBC_NAMESPACE::internal::int_to_b36_wchar(first_digit);183        if (first_digit < base) {184          ASSERT_EQ(func(small_string, nullptr, base),185                    static_cast<ReturnT>(first_digit));186          ASSERT_ERRNO_SUCCESS();187        } else {188          ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));189          ASSERT_ERRNO_SUCCESS();190        }191      }192    }193 194    for (int base = 2; base <= 36; ++base) {195      for (int first_digit = 0; first_digit <= 36; ++first_digit) {196        small_string[0] =197            LIBC_NAMESPACE::internal::int_to_b36_wchar(first_digit);198        for (int second_digit = 0; second_digit <= 36; ++second_digit) {199          small_string[1] =200              LIBC_NAMESPACE::internal::int_to_b36_wchar(second_digit);201          if (first_digit < base && second_digit < base) {202            ASSERT_EQ(203                func(small_string, nullptr, base),204                static_cast<ReturnT>(second_digit + (first_digit * base)));205            ASSERT_ERRNO_SUCCESS();206          } else if (first_digit < base) {207            ASSERT_EQ(func(small_string, nullptr, base),208                      static_cast<ReturnT>(first_digit));209            ASSERT_ERRNO_SUCCESS();210          } else {211            ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));212            ASSERT_ERRNO_SUCCESS();213          }214        }215      }216    }217 218    for (int base = 2; base <= 36; ++base) {219      for (int first_digit = 0; first_digit <= 36; ++first_digit) {220        small_string[0] =221            LIBC_NAMESPACE::internal::int_to_b36_wchar(first_digit);222        for (int second_digit = 0; second_digit <= 36; ++second_digit) {223          small_string[1] =224              LIBC_NAMESPACE::internal::int_to_b36_wchar(second_digit);225          for (int third_digit = 0; third_digit <= limit; ++third_digit) {226            small_string[2] =227                LIBC_NAMESPACE::internal::int_to_b36_wchar(third_digit);228 229            if (first_digit < base && second_digit < base &&230                third_digit < base) {231              ASSERT_EQ(func(small_string, nullptr, base),232                        static_cast<ReturnT>(third_digit +233                                             (second_digit * base) +234                                             (first_digit * base * base)));235              ASSERT_ERRNO_SUCCESS();236            } else if (first_digit < base && second_digit < base) {237              ASSERT_EQ(238                  func(small_string, nullptr, base),239                  static_cast<ReturnT>(second_digit + (first_digit * base)));240              ASSERT_ERRNO_SUCCESS();241            } else if (first_digit < base) {242              // if the base is 16 there is a special case for the prefix 0X.243              // The number is treated as a one digit hexadecimal.244              if (base == 16 && first_digit == 0 && second_digit == 33) {245                if (third_digit < base) {246                  ASSERT_EQ(func(small_string, nullptr, base),247                            static_cast<ReturnT>(third_digit));248                  ASSERT_ERRNO_SUCCESS();249                } else {250                  ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));251                  ASSERT_ERRNO_SUCCESS();252                }253              } else {254                ASSERT_EQ(func(small_string, nullptr, base),255                          static_cast<ReturnT>(first_digit));256                ASSERT_ERRNO_SUCCESS();257              }258            } else {259              ASSERT_EQ(func(small_string, nullptr, base), ReturnT(0));260              ASSERT_ERRNO_SUCCESS();261            }262          }263        }264      }265    }266  }267 268  void CleanBaseSixteenDecode(FunctionT func) {269    wchar_t *str_end = nullptr;270 271    const wchar_t *no_prefix = L"123abc";272    ASSERT_EQ(func(no_prefix, &str_end, 16), ReturnT(0x123abc));273    ASSERT_ERRNO_SUCCESS();274    EXPECT_EQ(str_end - no_prefix, ptrdiff_t(6));275 276    const wchar_t *yes_prefix = L"0x456def";277    ASSERT_EQ(func(yes_prefix, &str_end, 16), ReturnT(0x456def));278    ASSERT_ERRNO_SUCCESS();279    EXPECT_EQ(str_end - yes_prefix, ptrdiff_t(8));280 281    const wchar_t *letter_after_prefix = L"0xabc123";282    ASSERT_EQ(func(letter_after_prefix, &str_end, 16), ReturnT(0xabc123));283    ASSERT_ERRNO_SUCCESS();284    EXPECT_EQ(str_end - letter_after_prefix, ptrdiff_t(8));285 286    // These tests check what happens when the number passed is exactly the max287    // value for the conversion.288 289    // Max size for unsigned 32 bit numbers290 291    const wchar_t *max_32_bit_value = L"0xFFFFFFFF";292    ASSERT_EQ(func(max_32_bit_value, &str_end, 0),293              ((is_signed_v<ReturnT> && sizeof(ReturnT) == 4)294                   ? T_MAX295                   : ReturnT(0xFFFFFFFF)));296    ASSERT_ERRNO_EQ(is_signed_v<ReturnT> && sizeof(ReturnT) == 4 ? ERANGE : 0);297    EXPECT_EQ(str_end - max_32_bit_value, ptrdiff_t(10));298 299    const wchar_t *negative_max_32_bit_value = L"-0xFFFFFFFF";300    ASSERT_EQ(func(negative_max_32_bit_value, &str_end, 0),301              ((is_signed_v<ReturnT> && sizeof(ReturnT) == 4)302                   ? T_MIN303                   : -ReturnT(0xFFFFFFFF)));304    ASSERT_ERRNO_EQ(is_signed_v<ReturnT> && sizeof(ReturnT) == 4 ? ERANGE : 0);305    EXPECT_EQ(str_end - negative_max_32_bit_value, ptrdiff_t(11));306 307    // Max size for signed 32 bit numbers308 309    const wchar_t *max_31_bit_value = L"0x7FFFFFFF";310    ASSERT_EQ(func(max_31_bit_value, &str_end, 0), ReturnT(0x7FFFFFFF));311    ASSERT_ERRNO_SUCCESS();312    EXPECT_EQ(str_end - max_31_bit_value, ptrdiff_t(10));313 314    const wchar_t *negative_max_31_bit_value = L"-0x7FFFFFFF";315    ASSERT_EQ(func(negative_max_31_bit_value, &str_end, 0),316              -ReturnT(0x7FFFFFFF));317    ASSERT_ERRNO_SUCCESS();318    EXPECT_EQ(str_end - negative_max_31_bit_value, ptrdiff_t(11));319 320    // Max size for unsigned 64 bit numbers321 322    const wchar_t *max_64_bit_value = L"0xFFFFFFFFFFFFFFFF";323    ASSERT_EQ(func(max_64_bit_value, &str_end, 0),324              (is_signed_v<ReturnT> || sizeof(ReturnT) < 8325                   ? T_MAX326                   : ReturnT(0xFFFFFFFFFFFFFFFF)));327    ASSERT_ERRNO_EQ((is_signed_v<ReturnT> || sizeof(ReturnT) < 8 ? ERANGE : 0));328    EXPECT_EQ(str_end - max_64_bit_value, ptrdiff_t(18));329 330    // See the end of CleanBase10Decode for an explanation of how this large331    // negative number can end up as T_MAX.332    const wchar_t *negative_max_64_bit_value = L"-0xFFFFFFFFFFFFFFFF";333    ASSERT_EQ(334        func(negative_max_64_bit_value, &str_end, 0),335        (is_signed_v<ReturnT>336             ? T_MIN337             : (sizeof(ReturnT) < 8 ? T_MAX : -ReturnT(0xFFFFFFFFFFFFFFFF))));338    ASSERT_ERRNO_EQ((is_signed_v<ReturnT> || sizeof(ReturnT) < 8 ? ERANGE : 0));339    EXPECT_EQ(str_end - negative_max_64_bit_value, ptrdiff_t(19));340 341    // Max size for signed 64 bit numbers342 343    const wchar_t *max_63_bit_value = L"0x7FFFFFFFFFFFFFFF";344    ASSERT_EQ(func(max_63_bit_value, &str_end, 0),345              (sizeof(ReturnT) < 8 ? T_MAX : ReturnT(0x7FFFFFFFFFFFFFFF)));346    ASSERT_ERRNO_EQ(sizeof(ReturnT) < 8 ? ERANGE : 0);347    EXPECT_EQ(str_end - max_63_bit_value, ptrdiff_t(18));348 349    const wchar_t *negative_max_63_bit_value = L"-0x7FFFFFFFFFFFFFFF";350    ASSERT_EQ(func(negative_max_63_bit_value, &str_end, 0),351              (sizeof(ReturnT) >= 8 ? -ReturnT(0x7FFFFFFFFFFFFFFF)352                                    : (is_signed_v<ReturnT> ? T_MIN : T_MAX)));353    ASSERT_ERRNO_EQ(sizeof(ReturnT) < 8 ? ERANGE : 0);354    EXPECT_EQ(str_end - negative_max_63_bit_value, ptrdiff_t(19));355  }356 357  void MessyBaseSixteenDecode(FunctionT func) {358    wchar_t *str_end = nullptr;359 360    const wchar_t *just_prefix = L"0x";361    ASSERT_EQ(func(just_prefix, &str_end, 16), ReturnT(0));362    ASSERT_ERRNO_SUCCESS();363    EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1));364 365    ASSERT_EQ(func(just_prefix, &str_end, 0), ReturnT(0));366    ASSERT_ERRNO_SUCCESS();367    EXPECT_EQ(str_end - just_prefix, ptrdiff_t(1));368 369    const wchar_t *prefix_with_x_after = L"0xx";370    ASSERT_EQ(func(prefix_with_x_after, &str_end, 16), ReturnT(0));371    ASSERT_ERRNO_SUCCESS();372    EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1));373 374    ASSERT_EQ(func(prefix_with_x_after, &str_end, 0), ReturnT(0));375    ASSERT_ERRNO_SUCCESS();376    EXPECT_EQ(str_end - prefix_with_x_after, ptrdiff_t(1));377  }378 379  void AutomaticBaseSelection(FunctionT func) {380    wchar_t *str_end = nullptr;381 382    const wchar_t *base_ten = L"12345";383    ASSERT_EQ(func(base_ten, &str_end, 0), ReturnT(12345));384    ASSERT_ERRNO_SUCCESS();385    EXPECT_EQ(str_end - base_ten, ptrdiff_t(5));386 387    const wchar_t *base_sixteen_no_prefix = L"123abc";388    ASSERT_EQ(func(base_sixteen_no_prefix, &str_end, 0), ReturnT(123));389    ASSERT_ERRNO_SUCCESS();390    EXPECT_EQ(str_end - base_sixteen_no_prefix, ptrdiff_t(3));391 392    const wchar_t *base_sixteen_with_prefix = L"0x456def";393    ASSERT_EQ(func(base_sixteen_with_prefix, &str_end, 0), ReturnT(0x456def));394    ASSERT_ERRNO_SUCCESS();395    EXPECT_EQ(str_end - base_sixteen_with_prefix, ptrdiff_t(8));396 397    const wchar_t *base_eight_with_prefix = L"012345";398    ASSERT_EQ(func(base_eight_with_prefix, &str_end, 0), ReturnT(012345));399    ASSERT_ERRNO_SUCCESS();400    EXPECT_EQ(str_end - base_eight_with_prefix, ptrdiff_t(6));401 402    const wchar_t *just_zero = L"0";403    ASSERT_EQ(func(just_zero, &str_end, 0), ReturnT(0));404    ASSERT_ERRNO_SUCCESS();405    EXPECT_EQ(str_end - just_zero, ptrdiff_t(1));406 407    const wchar_t *just_zero_x = L"0x";408    ASSERT_EQ(func(just_zero_x, &str_end, 0), ReturnT(0));409    ASSERT_ERRNO_SUCCESS();410    EXPECT_EQ(str_end - just_zero_x, ptrdiff_t(1));411 412    const wchar_t *just_zero_eight = L"08";413    ASSERT_EQ(func(just_zero_eight, &str_end, 0), ReturnT(0));414    ASSERT_ERRNO_SUCCESS();415    EXPECT_EQ(str_end - just_zero_eight, ptrdiff_t(1));416  }417};418 419template <typename ReturnType>420WcstoTest(ReturnType (*)(const wchar_t *)) -> WcstoTest<ReturnType>;421 422#define WCSTOL_TEST(name, func)                                                \423  using LlvmLibc##name##Test = WcstoTest<decltype(func(L"", nullptr, 0))>;     \424  TEST_F(LlvmLibc##name##Test, InvalidBase) { InvalidBase(func); }             \425  TEST_F(LlvmLibc##name##Test, CleanBaseTenDecode) {                           \426    CleanBaseTenDecode(func);                                                  \427  }                                                                            \428  TEST_F(LlvmLibc##name##Test, MessyBaseTenDecode) {                           \429    MessyBaseTenDecode(func);                                                  \430  }                                                                            \431  TEST_F(LlvmLibc##name##Test, DecodeInOtherBases) {                           \432    DecodeInOtherBases(func);                                                  \433  }                                                                            \434  TEST_F(LlvmLibc##name##Test, CleanBaseSixteenDecode) {                       \435    CleanBaseSixteenDecode(func);                                              \436  }                                                                            \437  TEST_F(LlvmLibc##name##Test, MessyBaseSixteenDecode) {                       \438    MessyBaseSixteenDecode(func);                                              \439  }                                                                            \440  TEST_F(LlvmLibc##name##Test, AutomaticBaseSelection) {                       \441    AutomaticBaseSelection(func);                                              \442  }443