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 *too_big_number = "123456789012345678901"; 61 errno = 0; 62 ASSERT_EQ(__llvm_libc::strtoll(too_big_number, &str_end, 10), LLONG_MAX); 63 ASSERT_EQ(errno, ERANGE); 64 EXPECT_EQ(str_end - too_big_number, 19l); 65 66 const char *too_big_negative_number = "-123456789012345678901"; 67 errno = 0; 68 ASSERT_EQ(__llvm_libc::strtoll(too_big_negative_number, &str_end, 10), 69 LLONG_MIN); 70 ASSERT_EQ(errno, ERANGE); 71 EXPECT_EQ(str_end - too_big_negative_number, 20l); 72 } 73 74 TEST(LlvmLibcStrToLLTest, MessyBaseTenDecode) { 75 char *str_end = nullptr; 76 77 const char *spaces_before = " 10"; 78 errno = 0; 79 ASSERT_EQ(__llvm_libc::strtoll(spaces_before, &str_end, 10), 10ll); 80 ASSERT_EQ(errno, 0); 81 EXPECT_EQ(str_end - spaces_before, 7l); 82 83 const char *spaces_after = "10 "; 84 errno = 0; 85 ASSERT_EQ(__llvm_libc::strtoll(spaces_after, &str_end, 10), 10ll); 86 ASSERT_EQ(errno, 0); 87 EXPECT_EQ(str_end - spaces_after, 2l); 88 89 const char *word_before = "word10"; 90 errno = 0; 91 ASSERT_EQ(__llvm_libc::strtoll(word_before, &str_end, 10), 0ll); 92 ASSERT_EQ(errno, 0); 93 EXPECT_EQ(str_end - word_before, 0l); 94 95 const char *word_after = "10word"; 96 errno = 0; 97 ASSERT_EQ(__llvm_libc::strtoll(word_after, &str_end, 10), 10ll); 98 ASSERT_EQ(errno, 0); 99 EXPECT_EQ(str_end - word_after, 2l); 100 101 const char *two_numbers = "10 999"; 102 errno = 0; 103 ASSERT_EQ(__llvm_libc::strtoll(two_numbers, &str_end, 10), 10ll); 104 ASSERT_EQ(errno, 0); 105 EXPECT_EQ(str_end - two_numbers, 2l); 106 107 const char *two_signs = "--10 999"; 108 errno = 0; 109 ASSERT_EQ(__llvm_libc::strtoll(two_signs, &str_end, 10), 0ll); 110 ASSERT_EQ(errno, 0); 111 EXPECT_EQ(str_end - two_signs, 1l); 112 113 const char *sign_before = "+2=4"; 114 errno = 0; 115 ASSERT_EQ(__llvm_libc::strtoll(sign_before, &str_end, 10), 2ll); 116 ASSERT_EQ(errno, 0); 117 EXPECT_EQ(str_end - sign_before, 2l); 118 119 const char *sign_after = "2+2=4"; 120 errno = 0; 121 ASSERT_EQ(__llvm_libc::strtoll(sign_after, &str_end, 10), 2ll); 122 ASSERT_EQ(errno, 0); 123 EXPECT_EQ(str_end - sign_after, 1l); 124 125 const char *tab_before = "\t10"; 126 errno = 0; 127 ASSERT_EQ(__llvm_libc::strtoll(tab_before, &str_end, 10), 10ll); 128 ASSERT_EQ(errno, 0); 129 EXPECT_EQ(str_end - tab_before, 3l); 130 131 const char *all_together = "\t -12345and+67890"; 132 errno = 0; 133 ASSERT_EQ(__llvm_libc::strtoll(all_together, &str_end, 10), -12345ll); 134 ASSERT_EQ(errno, 0); 135 EXPECT_EQ(str_end - all_together, 9l); 136 } 137 138 static char int_to_b36_char(int input) { 139 if (input < 0 || input > 36) 140 return '0'; 141 if (input < 10) 142 return '0' + input; 143 return 'A' + input - 10; 144 } 145 146 TEST(LlvmLibcStrToLLTest, DecodeInOtherBases) { 147 char small_string[4] = {'\0', '\0', '\0', '\0'}; 148 for (int base = 2; base <= 36; ++base) { 149 for (long long first_digit = 0; first_digit <= 36; ++first_digit) { 150 small_string[0] = int_to_b36_char(first_digit); 151 if (first_digit < base) { 152 errno = 0; 153 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 154 first_digit); 155 ASSERT_EQ(errno, 0); 156 } else { 157 errno = 0; 158 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 0ll); 159 ASSERT_EQ(errno, 0); 160 } 161 } 162 } 163 164 for (int base = 2; base <= 36; ++base) { 165 for (long long first_digit = 0; first_digit <= 36; ++first_digit) { 166 small_string[0] = int_to_b36_char(first_digit); 167 for (long long second_digit = 0; second_digit <= 36; ++second_digit) { 168 small_string[1] = int_to_b36_char(second_digit); 169 if (first_digit < base && second_digit < base) { 170 errno = 0; 171 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 172 second_digit + (first_digit * base)); 173 ASSERT_EQ(errno, 0); 174 } else if (first_digit < base) { 175 errno = 0; 176 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 177 first_digit); 178 ASSERT_EQ(errno, 0); 179 } else { 180 errno = 0; 181 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 0ll); 182 ASSERT_EQ(errno, 0); 183 } 184 } 185 } 186 } 187 188 for (int base = 2; base <= 36; ++base) { 189 for (long long first_digit = 0; first_digit <= 36; ++first_digit) { 190 small_string[0] = int_to_b36_char(first_digit); 191 for (long long second_digit = 0; second_digit <= 36; ++second_digit) { 192 small_string[1] = int_to_b36_char(second_digit); 193 for (long long third_digit = 0; third_digit <= 36; ++third_digit) { 194 small_string[2] = int_to_b36_char(third_digit); 195 196 if (first_digit < base && second_digit < base && third_digit < base) { 197 errno = 0; 198 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 199 third_digit + (second_digit * base) + 200 (first_digit * base * base)); 201 ASSERT_EQ(errno, 0); 202 } else if (first_digit < base && second_digit < base) { 203 errno = 0; 204 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 205 second_digit + (first_digit * base)); 206 ASSERT_EQ(errno, 0); 207 } else if (first_digit < base) { 208 // if the base is 16 there is a special case for the prefix 0X. 209 // The number is treated as a one digit hexadecimal. 210 if (base == 16 && first_digit == 0 && second_digit == 33) { 211 if (third_digit < base) { 212 errno = 0; 213 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 214 third_digit); 215 ASSERT_EQ(errno, 0); 216 } else { 217 errno = 0; 218 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 219 0ll); 220 ASSERT_EQ(errno, 0); 221 } 222 } else { 223 errno = 0; 224 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 225 first_digit); 226 ASSERT_EQ(errno, 0); 227 } 228 } else { 229 errno = 0; 230 ASSERT_EQ(__llvm_libc::strtoll(small_string, nullptr, base), 0ll); 231 ASSERT_EQ(errno, 0); 232 } 233 } 234 } 235 } 236 } 237 } 238 239 TEST(LlvmLibcStrToLLTest, CleanBaseSixteenDecode) { 240 char *str_end = nullptr; 241 242 const char *no_prefix = "123abc"; 243 errno = 0; 244 ASSERT_EQ(__llvm_libc::strtoll(no_prefix, &str_end, 16), 0x123abcll); 245 ASSERT_EQ(errno, 0); 246 EXPECT_EQ(str_end - no_prefix, 6l); 247 248 const char *yes_prefix = "0x456def"; 249 errno = 0; 250 ASSERT_EQ(__llvm_libc::strtoll(yes_prefix, &str_end, 16), 0x456defll); 251 ASSERT_EQ(errno, 0); 252 EXPECT_EQ(str_end - yes_prefix, 8l); 253 } 254 255 TEST(LlvmLibcStrToLLTest, AutomaticBaseSelection) { 256 char *str_end = nullptr; 257 258 const char *base_ten = "12345"; 259 errno = 0; 260 ASSERT_EQ(__llvm_libc::strtoll(base_ten, &str_end, 0), 12345ll); 261 ASSERT_EQ(errno, 0); 262 EXPECT_EQ(str_end - base_ten, 5l); 263 264 const char *base_sixteen_no_prefix = "123abc"; 265 errno = 0; 266 ASSERT_EQ(__llvm_libc::strtoll(base_sixteen_no_prefix, &str_end, 0), 123ll); 267 ASSERT_EQ(errno, 0); 268 EXPECT_EQ(str_end - base_sixteen_no_prefix, 3l); 269 270 const char *base_sixteen_with_prefix = "0x456def"; 271 errno = 0; 272 ASSERT_EQ(__llvm_libc::strtoll(base_sixteen_with_prefix, &str_end, 0), 273 0x456defll); 274 ASSERT_EQ(errno, 0); 275 EXPECT_EQ(str_end - base_sixteen_with_prefix, 8l); 276 277 const char *base_eight_with_prefix = "012345"; 278 errno = 0; 279 ASSERT_EQ(__llvm_libc::strtoll(base_eight_with_prefix, &str_end, 0), 280 012345ll); 281 ASSERT_EQ(errno, 0); 282 EXPECT_EQ(str_end - base_eight_with_prefix, 6l); 283 } 284