1*38ef6929SJoseph Huber //===-- Unittests for sscanf ----------------------------------------------===// 2*38ef6929SJoseph Huber // 3*38ef6929SJoseph Huber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*38ef6929SJoseph Huber // See https://llvm.org/LICENSE.txt for license information. 5*38ef6929SJoseph Huber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*38ef6929SJoseph Huber // 7*38ef6929SJoseph Huber //===----------------------------------------------------------------------===// 8*38ef6929SJoseph Huber 9*38ef6929SJoseph Huber #include "src/stdio/vsscanf.h" 10*38ef6929SJoseph Huber 11*38ef6929SJoseph Huber #include "test/UnitTest/Test.h" 12*38ef6929SJoseph Huber 13*38ef6929SJoseph Huber int call_vsscanf(const char *__restrict buffer, const char *__restrict format, 14*38ef6929SJoseph Huber ...) { 15*38ef6929SJoseph Huber va_list vlist; 16*38ef6929SJoseph Huber va_start(vlist, format); 17*38ef6929SJoseph Huber int ret = LIBC_NAMESPACE::vsscanf(buffer, format, vlist); 18*38ef6929SJoseph Huber va_end(vlist); 19*38ef6929SJoseph Huber return ret; 20*38ef6929SJoseph Huber } 21*38ef6929SJoseph Huber 22*38ef6929SJoseph Huber TEST(LlvmLibcVSScanfTest, SimpleStringConv) { 23*38ef6929SJoseph Huber int ret_val; 24*38ef6929SJoseph Huber char buffer[10]; 25*38ef6929SJoseph Huber char buffer2[10]; 26*38ef6929SJoseph Huber ret_val = call_vsscanf("abc123", "abc %s", buffer); 27*38ef6929SJoseph Huber ASSERT_EQ(ret_val, 1); 28*38ef6929SJoseph Huber ASSERT_STREQ(buffer, "123"); 29*38ef6929SJoseph Huber 30*38ef6929SJoseph Huber ret_val = call_vsscanf("abc123", "%3s %3s", buffer, buffer2); 31*38ef6929SJoseph Huber ASSERT_EQ(ret_val, 2); 32*38ef6929SJoseph Huber ASSERT_STREQ(buffer, "abc"); 33*38ef6929SJoseph Huber ASSERT_STREQ(buffer2, "123"); 34*38ef6929SJoseph Huber 35*38ef6929SJoseph Huber ret_val = call_vsscanf("abc 123", "%3s%3s", buffer, buffer2); 36*38ef6929SJoseph Huber ASSERT_EQ(ret_val, 2); 37*38ef6929SJoseph Huber ASSERT_STREQ(buffer, "abc"); 38*38ef6929SJoseph Huber ASSERT_STREQ(buffer2, "123"); 39*38ef6929SJoseph Huber } 40*38ef6929SJoseph Huber 41*38ef6929SJoseph Huber TEST(LlvmLibcVSScanfTest, IntConvSimple) { 42*38ef6929SJoseph Huber int ret_val; 43*38ef6929SJoseph Huber int result = 0; 44*38ef6929SJoseph Huber ret_val = call_vsscanf("123", "%d", &result); 45*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 46*38ef6929SJoseph Huber EXPECT_EQ(result, 123); 47*38ef6929SJoseph Huber 48*38ef6929SJoseph Huber ret_val = call_vsscanf("456", "%i", &result); 49*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 50*38ef6929SJoseph Huber EXPECT_EQ(result, 456); 51*38ef6929SJoseph Huber 52*38ef6929SJoseph Huber ret_val = call_vsscanf("789", "%x", &result); 53*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 54*38ef6929SJoseph Huber EXPECT_EQ(result, 0x789); 55*38ef6929SJoseph Huber 56*38ef6929SJoseph Huber ret_val = call_vsscanf("012", "%o", &result); 57*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 58*38ef6929SJoseph Huber EXPECT_EQ(result, 012); 59*38ef6929SJoseph Huber 60*38ef6929SJoseph Huber ret_val = call_vsscanf("345", "%u", &result); 61*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 62*38ef6929SJoseph Huber EXPECT_EQ(result, 345); 63*38ef6929SJoseph Huber 64*38ef6929SJoseph Huber // 288 characters 65*38ef6929SJoseph Huber ret_val = call_vsscanf("10000000000000000000000000000000" 66*38ef6929SJoseph Huber "00000000000000000000000000000000" 67*38ef6929SJoseph Huber "00000000000000000000000000000000" 68*38ef6929SJoseph Huber "00000000000000000000000000000000" 69*38ef6929SJoseph Huber "00000000000000000000000000000000" 70*38ef6929SJoseph Huber "00000000000000000000000000000000" 71*38ef6929SJoseph Huber "00000000000000000000000000000000" 72*38ef6929SJoseph Huber "00000000000000000000000000000000" 73*38ef6929SJoseph Huber "00000000000000000000000000000000", 74*38ef6929SJoseph Huber "%d", &result); 75*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 76*38ef6929SJoseph Huber EXPECT_EQ(result, int(LIBC_NAMESPACE::cpp::numeric_limits<intmax_t>::max())); 77*38ef6929SJoseph Huber 78*38ef6929SJoseph Huber ret_val = call_vsscanf("Not an integer", "%d", &result); 79*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 0); 80*38ef6929SJoseph Huber } 81*38ef6929SJoseph Huber 82*38ef6929SJoseph Huber TEST(LlvmLibcVSScanfTest, IntConvLengthModifier) { 83*38ef6929SJoseph Huber int ret_val; 84*38ef6929SJoseph Huber uintmax_t max_result = 0; 85*38ef6929SJoseph Huber int int_result = 0; 86*38ef6929SJoseph Huber char char_result = 0; 87*38ef6929SJoseph Huber 88*38ef6929SJoseph Huber ret_val = call_vsscanf("123", "%ju", &max_result); 89*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 90*38ef6929SJoseph Huber EXPECT_EQ(max_result, uintmax_t(123)); 91*38ef6929SJoseph Huber 92*38ef6929SJoseph Huber // Check overflow handling 93*38ef6929SJoseph Huber ret_val = 94*38ef6929SJoseph Huber call_vsscanf("999999999999999999999999999999999999", "%ju", &max_result); 95*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 96*38ef6929SJoseph Huber EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max()); 97*38ef6929SJoseph Huber 98*38ef6929SJoseph Huber // Because this is unsigned, any out of range value should return the maximum, 99*38ef6929SJoseph Huber // even with a negative sign. 100*38ef6929SJoseph Huber ret_val = 101*38ef6929SJoseph Huber call_vsscanf("-999999999999999999999999999999999999", "%ju", &max_result); 102*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 103*38ef6929SJoseph Huber EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max()); 104*38ef6929SJoseph Huber 105*38ef6929SJoseph Huber ret_val = call_vsscanf("-18446744073709551616", "%ju", &max_result); 106*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 107*38ef6929SJoseph Huber EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max()); 108*38ef6929SJoseph Huber 109*38ef6929SJoseph Huber // But any number below the maximum should have the - sign applied. 110*38ef6929SJoseph Huber ret_val = call_vsscanf("-1", "%ju", &max_result); 111*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 112*38ef6929SJoseph Huber EXPECT_EQ(max_result, uintmax_t(-1)); 113*38ef6929SJoseph Huber 114*38ef6929SJoseph Huber ret_val = call_vsscanf("-1", "%u", &int_result); 115*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 116*38ef6929SJoseph Huber EXPECT_EQ(int_result, -1); 117*38ef6929SJoseph Huber 118*38ef6929SJoseph Huber max_result = 0xff00ff00ff00ff00; 119*38ef6929SJoseph Huber char_result = 0x6f; 120*38ef6929SJoseph Huber 121*38ef6929SJoseph Huber // Overflows for sizes larger than the maximum are handled by casting. 122*38ef6929SJoseph Huber ret_val = call_vsscanf("8589967360", "%d", &int_result); 123*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 124*38ef6929SJoseph Huber EXPECT_EQ(int_result, int(8589967360)); // 2^33 + 2^15 125*38ef6929SJoseph Huber 126*38ef6929SJoseph Huber // Check that the adjacent values weren't touched by the overflow. 127*38ef6929SJoseph Huber ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00)); 128*38ef6929SJoseph Huber ASSERT_EQ(char_result, char(0x6f)); 129*38ef6929SJoseph Huber 130*38ef6929SJoseph Huber ret_val = call_vsscanf("-8589967360", "%d", &int_result); 131*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 132*38ef6929SJoseph Huber EXPECT_EQ(int_result, int(-8589967360)); 133*38ef6929SJoseph Huber ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00)); 134*38ef6929SJoseph Huber ASSERT_EQ(char_result, char(0x6f)); 135*38ef6929SJoseph Huber 136*38ef6929SJoseph Huber ret_val = call_vsscanf("25", "%hhd", &char_result); 137*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 138*38ef6929SJoseph Huber EXPECT_EQ(char_result, char(25)); 139*38ef6929SJoseph Huber } 140*38ef6929SJoseph Huber 141*38ef6929SJoseph Huber TEST(LlvmLibcVSScanfTest, IntConvBaseSelection) { 142*38ef6929SJoseph Huber int ret_val; 143*38ef6929SJoseph Huber int result = 0; 144*38ef6929SJoseph Huber ret_val = call_vsscanf("0xabc123", "%i", &result); 145*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 146*38ef6929SJoseph Huber EXPECT_EQ(result, 0xabc123); 147*38ef6929SJoseph Huber 148*38ef6929SJoseph Huber ret_val = call_vsscanf("0456", "%i", &result); 149*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 150*38ef6929SJoseph Huber EXPECT_EQ(result, 0456); 151*38ef6929SJoseph Huber 152*38ef6929SJoseph Huber ret_val = call_vsscanf("0999", "%i", &result); 153*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 154*38ef6929SJoseph Huber EXPECT_EQ(result, 0); 155*38ef6929SJoseph Huber 156*38ef6929SJoseph Huber ret_val = call_vsscanf("123abc456", "%i", &result); 157*38ef6929SJoseph Huber EXPECT_EQ(ret_val, 1); 158*38ef6929SJoseph Huber EXPECT_EQ(result, 123); 159*38ef6929SJoseph Huber } 160