1 //===-- Unittests for strtoull --------------------------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/stdlib/strtoull.h" 10 11 #include "utils/UnitTest/Test.h" 12 13 #include <errno.h> 14 #include <limits.h> 15 16 TEST(LlvmLibcStrToULLTest, InvalidBase) { 17 const char *ten = "10"; 18 errno = 0; 19 ASSERT_EQ(__llvm_libc::strtoull(ten, nullptr, -1), 0ull); 20 ASSERT_EQ(errno, EINVAL); 21 } 22 23 TEST(LlvmLibcStrToULLTest, CleanBaseTenDecode) { 24 char *str_end = nullptr; 25 26 const char *ten = "10"; 27 errno = 0; 28 ASSERT_EQ(__llvm_libc::strtoull(ten, &str_end, 10), 10ull); 29 ASSERT_EQ(errno, 0); 30 EXPECT_EQ(str_end - ten, 2l); 31 errno = 0; 32 ASSERT_EQ(__llvm_libc::strtoull(ten, nullptr, 10), 10ull); 33 ASSERT_EQ(errno, 0); 34 35 const char *hundred = "100"; 36 errno = 0; 37 ASSERT_EQ(__llvm_libc::strtoull(hundred, &str_end, 10), 100ull); 38 ASSERT_EQ(errno, 0); 39 EXPECT_EQ(str_end - hundred, 3l); 40 41 const char *negative = "-100"; 42 errno = 0; 43 ASSERT_EQ(__llvm_libc::strtoull(negative, &str_end, 10), -(100ull)); 44 ASSERT_EQ(errno, 0); 45 EXPECT_EQ(str_end - negative, 4l); 46 47 const char *big_number = "123456789012345"; 48 errno = 0; 49 ASSERT_EQ(__llvm_libc::strtoull(big_number, &str_end, 10), 50 123456789012345ull); 51 ASSERT_EQ(errno, 0); 52 EXPECT_EQ(str_end - big_number, 15l); 53 54 const char *unsigned_long_long_max_number = "18446744073709551615"; 55 errno = 0; 56 ASSERT_EQ(__llvm_libc::strtoull(unsigned_long_long_max_number, &str_end, 10), 57 18446744073709551615ull); 58 ASSERT_EQ(errno, 0); 59 EXPECT_EQ(str_end - unsigned_long_long_max_number, 20l); 60 61 const char *too_big_number = "123456789012345678901"; 62 errno = 0; 63 ASSERT_EQ(__llvm_libc::strtoull(too_big_number, &str_end, 10), ULLONG_MAX); 64 ASSERT_EQ(errno, ERANGE); 65 EXPECT_EQ(str_end - too_big_number, 21l); 66 67 const char *too_big_negative_number = "-123456789012345678901"; 68 errno = 0; 69 ASSERT_EQ(__llvm_libc::strtoull(too_big_negative_number, &str_end, 10), 70 ULLONG_MAX); 71 ASSERT_EQ(errno, ERANGE); 72 EXPECT_EQ(str_end - too_big_negative_number, 22l); 73 74 const char *long_number_range_test = 75 "10000000000000000000000000000000000000000000000000"; 76 errno = 0; 77 ASSERT_EQ(__llvm_libc::strtoull(long_number_range_test, &str_end, 10), 78 ULLONG_MAX); 79 ASSERT_EQ(errno, ERANGE); 80 EXPECT_EQ(str_end - long_number_range_test, 50l); 81 } 82 83 TEST(LlvmLibcStrToULLTest, MessyBaseTenDecode) { 84 char *str_end = nullptr; 85 86 const char *spaces_before = " 10"; 87 errno = 0; 88 ASSERT_EQ(__llvm_libc::strtoull(spaces_before, &str_end, 10), 10ull); 89 ASSERT_EQ(errno, 0); 90 EXPECT_EQ(str_end - spaces_before, 7l); 91 92 const char *spaces_after = "10 "; 93 errno = 0; 94 ASSERT_EQ(__llvm_libc::strtoull(spaces_after, &str_end, 10), 10ull); 95 ASSERT_EQ(errno, 0); 96 EXPECT_EQ(str_end - spaces_after, 2l); 97 98 const char *word_before = "word10"; 99 errno = 0; 100 ASSERT_EQ(__llvm_libc::strtoull(word_before, &str_end, 10), 0ull); 101 ASSERT_EQ(errno, 0); 102 EXPECT_EQ(str_end - word_before, 0l); 103 104 const char *word_after = "10word"; 105 errno = 0; 106 ASSERT_EQ(__llvm_libc::strtoull(word_after, &str_end, 10), 10ull); 107 ASSERT_EQ(errno, 0); 108 EXPECT_EQ(str_end - word_after, 2l); 109 110 const char *two_numbers = "10 999"; 111 errno = 0; 112 ASSERT_EQ(__llvm_libc::strtoull(two_numbers, &str_end, 10), 10ull); 113 ASSERT_EQ(errno, 0); 114 EXPECT_EQ(str_end - two_numbers, 2l); 115 116 const char *two_signs = "--10 999"; 117 errno = 0; 118 ASSERT_EQ(__llvm_libc::strtoull(two_signs, &str_end, 10), 0ull); 119 ASSERT_EQ(errno, 0); 120 EXPECT_EQ(str_end - two_signs, 1l); 121 122 const char *sign_before = "+2=4"; 123 errno = 0; 124 ASSERT_EQ(__llvm_libc::strtoull(sign_before, &str_end, 10), 2ull); 125 ASSERT_EQ(errno, 0); 126 EXPECT_EQ(str_end - sign_before, 2l); 127 128 const char *sign_after = "2+2=4"; 129 errno = 0; 130 ASSERT_EQ(__llvm_libc::strtoull(sign_after, &str_end, 10), 2ull); 131 ASSERT_EQ(errno, 0); 132 EXPECT_EQ(str_end - sign_after, 1l); 133 134 const char *tab_before = "\t10"; 135 errno = 0; 136 ASSERT_EQ(__llvm_libc::strtoull(tab_before, &str_end, 10), 10ull); 137 ASSERT_EQ(errno, 0); 138 EXPECT_EQ(str_end - tab_before, 3l); 139 140 const char *all_together = "\t -12345and+67890"; 141 errno = 0; 142 ASSERT_EQ(__llvm_libc::strtoull(all_together, &str_end, 10), -(12345ull)); 143 ASSERT_EQ(errno, 0); 144 EXPECT_EQ(str_end - all_together, 9l); 145 } 146 147 static char int_to_b36_char(int input) { 148 if (input < 0 || input > 36) 149 return '0'; 150 if (input < 10) 151 return '0' + input; 152 return 'A' + input - 10; 153 } 154 155 TEST(LlvmLibcStrToULLTest, DecodeInOtherBases) { 156 char small_string[4] = {'\0', '\0', '\0', '\0'}; 157 for (unsigned int base = 2; base <= 36; ++base) { 158 for (unsigned long long first_digit = 0; first_digit <= 36; ++first_digit) { 159 small_string[0] = int_to_b36_char(first_digit); 160 if (first_digit < base) { 161 errno = 0; 162 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 163 first_digit); 164 ASSERT_EQ(errno, 0); 165 } else { 166 errno = 0; 167 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); 168 ASSERT_EQ(errno, 0); 169 } 170 } 171 } 172 173 for (unsigned int base = 2; base <= 36; ++base) { 174 for (unsigned long long first_digit = 0; first_digit <= 36; ++first_digit) { 175 small_string[0] = int_to_b36_char(first_digit); 176 for (unsigned long long second_digit = 0; second_digit <= 36; 177 ++second_digit) { 178 small_string[1] = int_to_b36_char(second_digit); 179 if (first_digit < base && second_digit < base) { 180 errno = 0; 181 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 182 second_digit + (first_digit * base)); 183 ASSERT_EQ(errno, 0); 184 } else if (first_digit < base) { 185 errno = 0; 186 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 187 first_digit); 188 ASSERT_EQ(errno, 0); 189 } else { 190 errno = 0; 191 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); 192 ASSERT_EQ(errno, 0); 193 } 194 } 195 } 196 } 197 198 for (unsigned int base = 2; base <= 36; ++base) { 199 for (unsigned long long first_digit = 0; first_digit <= 36; ++first_digit) { 200 small_string[0] = int_to_b36_char(first_digit); 201 for (unsigned long long second_digit = 0; second_digit <= 36; 202 ++second_digit) { 203 small_string[1] = int_to_b36_char(second_digit); 204 for (unsigned long long third_digit = 0; third_digit <= 36; 205 ++third_digit) { 206 small_string[2] = int_to_b36_char(third_digit); 207 208 if (first_digit < base && second_digit < base && third_digit < base) { 209 errno = 0; 210 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 211 third_digit + (second_digit * base) + 212 (first_digit * base * base)); 213 ASSERT_EQ(errno, 0); 214 } else if (first_digit < base && second_digit < base) { 215 errno = 0; 216 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 217 second_digit + (first_digit * base)); 218 ASSERT_EQ(errno, 0); 219 } else if (first_digit < base) { 220 // if the base is 16 there is a special case for the prefix 0X. 221 // The number is treated as a one digit hexadecimal. 222 if (base == 16 && first_digit == 0 && second_digit == 33) { 223 if (third_digit < base) { 224 errno = 0; 225 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 226 third_digit); 227 ASSERT_EQ(errno, 0); 228 } else { 229 errno = 0; 230 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 231 0ull); 232 ASSERT_EQ(errno, 0); 233 } 234 } else { 235 errno = 0; 236 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 237 first_digit); 238 ASSERT_EQ(errno, 0); 239 } 240 } else { 241 errno = 0; 242 ASSERT_EQ(__llvm_libc::strtoull(small_string, nullptr, base), 0ull); 243 ASSERT_EQ(errno, 0); 244 } 245 } 246 } 247 } 248 } 249 } 250 251 TEST(LlvmLibcStrToULLTest, CleanBaseSixteenDecode) { 252 char *str_end = nullptr; 253 254 const char *no_prefix = "123abc"; 255 errno = 0; 256 ASSERT_EQ(__llvm_libc::strtoull(no_prefix, &str_end, 16), 0x123abcull); 257 ASSERT_EQ(errno, 0); 258 EXPECT_EQ(str_end - no_prefix, 6l); 259 260 const char *yes_prefix = "0x456def"; 261 errno = 0; 262 ASSERT_EQ(__llvm_libc::strtoull(yes_prefix, &str_end, 16), 0x456defull); 263 ASSERT_EQ(errno, 0); 264 EXPECT_EQ(str_end - yes_prefix, 8l); 265 } 266 267 TEST(LlvmLibcStrToULLTest, AutomaticBaseSelection) { 268 char *str_end = nullptr; 269 270 const char *base_ten = "12345"; 271 errno = 0; 272 ASSERT_EQ(__llvm_libc::strtoull(base_ten, &str_end, 0), 12345ull); 273 ASSERT_EQ(errno, 0); 274 EXPECT_EQ(str_end - base_ten, 5l); 275 276 const char *base_sixteen_no_prefix = "123abc"; 277 errno = 0; 278 ASSERT_EQ(__llvm_libc::strtoull(base_sixteen_no_prefix, &str_end, 0), 123ull); 279 ASSERT_EQ(errno, 0); 280 EXPECT_EQ(str_end - base_sixteen_no_prefix, 3l); 281 282 const char *base_sixteen_with_prefix = "0x456def"; 283 errno = 0; 284 ASSERT_EQ(__llvm_libc::strtoull(base_sixteen_with_prefix, &str_end, 0), 285 0x456defull); 286 ASSERT_EQ(errno, 0); 287 EXPECT_EQ(str_end - base_sixteen_with_prefix, 8l); 288 289 const char *base_eight_with_prefix = "012345"; 290 errno = 0; 291 ASSERT_EQ(__llvm_libc::strtoull(base_eight_with_prefix, &str_end, 0), 292 012345ull); 293 ASSERT_EQ(errno, 0); 294 EXPECT_EQ(str_end - base_eight_with_prefix, 6l); 295 } 296