1*a5e67fbaSTsz Chan //===-- Unittests for vasprintf--------------------------------------------===// 2*a5e67fbaSTsz Chan // 3*a5e67fbaSTsz Chan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*a5e67fbaSTsz Chan // See https://llvm.org/LICENSE.txt for license information. 5*a5e67fbaSTsz Chan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*a5e67fbaSTsz Chan // 7*a5e67fbaSTsz Chan //===----------------------------------------------------------------------===// 8*a5e67fbaSTsz Chan 9*a5e67fbaSTsz Chan #include "src/stdio/sprintf.h" 10*a5e67fbaSTsz Chan #include "src/stdio/vasprintf.h" 11*a5e67fbaSTsz Chan #include "src/string/memset.h" 12*a5e67fbaSTsz Chan #include "test/UnitTest/Test.h" 13*a5e67fbaSTsz Chan 14*a5e67fbaSTsz Chan int call_vasprintf(char **__restrict buffer, const char *__restrict format, 15*a5e67fbaSTsz Chan ...) { 16*a5e67fbaSTsz Chan va_list vlist; 17*a5e67fbaSTsz Chan va_start(vlist, format); 18*a5e67fbaSTsz Chan int ret = LIBC_NAMESPACE::vasprintf(buffer, format, vlist); 19*a5e67fbaSTsz Chan va_end(vlist); 20*a5e67fbaSTsz Chan return ret; 21*a5e67fbaSTsz Chan } 22*a5e67fbaSTsz Chan 23*a5e67fbaSTsz Chan TEST(LlvmLibcVASPrintfTest, SimpleNoConv) { 24*a5e67fbaSTsz Chan char *buff = nullptr; 25*a5e67fbaSTsz Chan int written; 26*a5e67fbaSTsz Chan written = call_vasprintf(&buff, "A simple string with no conversions."); 27*a5e67fbaSTsz Chan EXPECT_EQ(written, 36); 28*a5e67fbaSTsz Chan ASSERT_STREQ(buff, "A simple string with no conversions."); 29*a5e67fbaSTsz Chan free(buff); 30*a5e67fbaSTsz Chan } 31*a5e67fbaSTsz Chan 32*a5e67fbaSTsz Chan TEST(LlvmLibcVASPrintfTest, PercentConv) { 33*a5e67fbaSTsz Chan char *buff = nullptr; 34*a5e67fbaSTsz Chan int written; 35*a5e67fbaSTsz Chan 36*a5e67fbaSTsz Chan written = call_vasprintf(&buff, "%%"); 37*a5e67fbaSTsz Chan EXPECT_EQ(written, 1); 38*a5e67fbaSTsz Chan ASSERT_STREQ(buff, "%"); 39*a5e67fbaSTsz Chan free(buff); 40*a5e67fbaSTsz Chan 41*a5e67fbaSTsz Chan written = call_vasprintf(&buff, "abc %% def"); 42*a5e67fbaSTsz Chan EXPECT_EQ(written, 9); 43*a5e67fbaSTsz Chan ASSERT_STREQ(buff, "abc % def"); 44*a5e67fbaSTsz Chan free(buff); 45*a5e67fbaSTsz Chan 46*a5e67fbaSTsz Chan written = call_vasprintf(&buff, "%%%%%%"); 47*a5e67fbaSTsz Chan EXPECT_EQ(written, 3); 48*a5e67fbaSTsz Chan ASSERT_STREQ(buff, "%%%"); 49*a5e67fbaSTsz Chan free(buff); 50*a5e67fbaSTsz Chan } 51*a5e67fbaSTsz Chan 52*a5e67fbaSTsz Chan TEST(LlvmLibcVASPrintfTest, CharConv) { 53*a5e67fbaSTsz Chan char *buff = nullptr; 54*a5e67fbaSTsz Chan int written; 55*a5e67fbaSTsz Chan 56*a5e67fbaSTsz Chan written = call_vasprintf(&buff, "%c", 'a'); 57*a5e67fbaSTsz Chan EXPECT_EQ(written, 1); 58*a5e67fbaSTsz Chan ASSERT_STREQ(buff, "a"); 59*a5e67fbaSTsz Chan free(buff); 60*a5e67fbaSTsz Chan 61*a5e67fbaSTsz Chan written = call_vasprintf(&buff, "%3c %-3c", '1', '2'); 62*a5e67fbaSTsz Chan EXPECT_EQ(written, 7); 63*a5e67fbaSTsz Chan ASSERT_STREQ(buff, " 1 2 "); 64*a5e67fbaSTsz Chan free(buff); 65*a5e67fbaSTsz Chan 66*a5e67fbaSTsz Chan written = call_vasprintf(&buff, "%*c", 2, '3'); 67*a5e67fbaSTsz Chan EXPECT_EQ(written, 2); 68*a5e67fbaSTsz Chan ASSERT_STREQ(buff, " 3"); 69*a5e67fbaSTsz Chan free(buff); 70*a5e67fbaSTsz Chan } 71*a5e67fbaSTsz Chan 72*a5e67fbaSTsz Chan TEST(LlvmLibcVASPrintfTest, LargeStringNoConv) { 73*a5e67fbaSTsz Chan char *buff = nullptr; 74*a5e67fbaSTsz Chan char long_str[1001]; 75*a5e67fbaSTsz Chan LIBC_NAMESPACE::memset(long_str, 'a', 1000); 76*a5e67fbaSTsz Chan long_str[1000] = '\0'; 77*a5e67fbaSTsz Chan int written; 78*a5e67fbaSTsz Chan written = call_vasprintf(&buff, long_str); 79*a5e67fbaSTsz Chan EXPECT_EQ(written, 1000); 80*a5e67fbaSTsz Chan ASSERT_STREQ(buff, long_str); 81*a5e67fbaSTsz Chan free(buff); 82*a5e67fbaSTsz Chan } 83*a5e67fbaSTsz Chan 84*a5e67fbaSTsz Chan TEST(LlvmLibcVASPrintfTest, ManyReAlloc) { 85*a5e67fbaSTsz Chan char *buff = nullptr; 86*a5e67fbaSTsz Chan const int expected_num_chars = 600; 87*a5e67fbaSTsz Chan int written = call_vasprintf(&buff, "%200s%200s%200s", "", "", ""); 88*a5e67fbaSTsz Chan EXPECT_EQ(written, expected_num_chars); 89*a5e67fbaSTsz Chan 90*a5e67fbaSTsz Chan bool isPadding = true; 91*a5e67fbaSTsz Chan for (int i = 0; i < expected_num_chars; i++) { 92*a5e67fbaSTsz Chan if (buff[i] != ' ') { 93*a5e67fbaSTsz Chan isPadding = false; 94*a5e67fbaSTsz Chan break; 95*a5e67fbaSTsz Chan } 96*a5e67fbaSTsz Chan } 97*a5e67fbaSTsz Chan EXPECT_TRUE(isPadding); 98*a5e67fbaSTsz Chan free(buff); 99*a5e67fbaSTsz Chan } 100