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