xref: /llvm-project/libc/test/src/stdio/vasprintf_test.cpp (revision a5e67fba8abb35211aebb945d9d07ac988b80cf5)
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