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