1 //===-- Unittests for sprintf ---------------------------------------------===//
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/stdio/sprintf.h"
10 
11 #include "utils/UnitTest/Test.h"
12 
13 TEST(LlvmLibcSPrintfTest, SimpleNoConv) {
14   char buff[64];
15   int written;
16 
17   written = __llvm_libc::sprintf(buff, "A simple string with no conversions.");
18   EXPECT_EQ(written, 36);
19   ASSERT_STREQ(buff, "A simple string with no conversions.");
20 }
21 
22 TEST(LlvmLibcSPrintfTest, PercentConv) {
23   char buff[64];
24   int written;
25 
26   written = __llvm_libc::sprintf(buff, "%%");
27   EXPECT_EQ(written, 1);
28   ASSERT_STREQ(buff, "%");
29 
30   written = __llvm_libc::sprintf(buff, "abc %% def");
31   EXPECT_EQ(written, 9);
32   ASSERT_STREQ(buff, "abc % def");
33 
34   written = __llvm_libc::sprintf(buff, "%%%%%%");
35   EXPECT_EQ(written, 3);
36   ASSERT_STREQ(buff, "%%%");
37 }
38 
39 TEST(LlvmLibcSPrintfTest, CharConv) {
40   char buff[64];
41   int written;
42 
43   written = __llvm_libc::sprintf(buff, "%c", 'a');
44   EXPECT_EQ(written, 1);
45   ASSERT_STREQ(buff, "a");
46 
47   written = __llvm_libc::sprintf(buff, "%3c %-3c", '1', '2');
48   EXPECT_EQ(written, 7);
49   ASSERT_STREQ(buff, "  1 2  ");
50 
51   written = __llvm_libc::sprintf(buff, "%*c", 2, '3');
52   EXPECT_EQ(written, 2);
53   ASSERT_STREQ(buff, " 3");
54 }
55 
56 TEST(LlvmLibcSPrintfTest, StringConv) {
57   char buff[64];
58   int written;
59 
60   written = __llvm_libc::sprintf(buff, "%s", "abcDEF123");
61   EXPECT_EQ(written, 9);
62   ASSERT_STREQ(buff, "abcDEF123");
63 
64   written = __llvm_libc::sprintf(buff, "%10s %-10s", "centered", "title");
65   EXPECT_EQ(written, 21);
66   ASSERT_STREQ(buff, "  centered title     ");
67 
68   written = __llvm_libc::sprintf(buff, "%-5.4s%-4.4s", "words can describe",
69                                  "soups most delicious");
70   EXPECT_EQ(written, 9);
71   ASSERT_STREQ(buff, "word soup");
72 
73   written = __llvm_libc::sprintf(buff, "%*s %.*s %*.*s", 10, "beginning", 2,
74                                  "isn't", 12, 10, "important. Ever.");
75   EXPECT_EQ(written, 26);
76   ASSERT_STREQ(buff, " beginning is   important.");
77 }
78 
79 TEST(LlvmLibcSPrintfTest, IntConv) {
80   char buff[64];
81   int written;
82 
83   // Basic Tests.
84 
85   written = __llvm_libc::sprintf(buff, "%d", 123);
86   EXPECT_EQ(written, 3);
87   ASSERT_STREQ(buff, "123");
88 
89   written = __llvm_libc::sprintf(buff, "%i", -456);
90   EXPECT_EQ(written, 4);
91   ASSERT_STREQ(buff, "-456");
92 
93   // Length Modifier Tests.
94 
95   written = __llvm_libc::sprintf(buff, "%hhu", 257); // 0x10001
96   EXPECT_EQ(written, 1);
97   ASSERT_STREQ(buff, "1");
98 
99   written = __llvm_libc::sprintf(buff, "%llu", 18446744073709551615ull);
100   EXPECT_EQ(written, 20);
101   ASSERT_STREQ(buff, "18446744073709551615"); // ull max
102 
103   written = __llvm_libc::sprintf(buff, "%tu", ~ptrdiff_t(0));
104   if (sizeof(ptrdiff_t) == 8) {
105     EXPECT_EQ(written, 20);
106     ASSERT_STREQ(buff, "18446744073709551615");
107   } else if (sizeof(ptrdiff_t) == 4) {
108     EXPECT_EQ(written, 10);
109     ASSERT_STREQ(buff, "4294967296");
110   }
111 
112   written = __llvm_libc::sprintf(buff, "%lld", -9223372036854775807ll - 1ll);
113   EXPECT_EQ(written, 20);
114   ASSERT_STREQ(buff, "-9223372036854775808"); // ll min
115 
116   // Min Width Tests.
117 
118   written = __llvm_libc::sprintf(buff, "%4d", 789);
119   EXPECT_EQ(written, 4);
120   ASSERT_STREQ(buff, " 789");
121 
122   written = __llvm_libc::sprintf(buff, "%2d", 987);
123   EXPECT_EQ(written, 3);
124   ASSERT_STREQ(buff, "987");
125 
126   // Precision Tests.
127 
128   written = __llvm_libc::sprintf(buff, "%d", 0);
129   EXPECT_EQ(written, 1);
130   ASSERT_STREQ(buff, "0");
131 
132   written = __llvm_libc::sprintf(buff, "%.0d", 0);
133   EXPECT_EQ(written, 0);
134   ASSERT_STREQ(buff, "");
135 
136   written = __llvm_libc::sprintf(buff, "%.5d", 654);
137   EXPECT_EQ(written, 5);
138   ASSERT_STREQ(buff, "00654");
139 
140   written = __llvm_libc::sprintf(buff, "%.5d", -321);
141   EXPECT_EQ(written, 6);
142   ASSERT_STREQ(buff, "-00321");
143 
144   written = __llvm_libc::sprintf(buff, "%.2d", 135);
145   EXPECT_EQ(written, 3);
146   ASSERT_STREQ(buff, "135");
147 
148   // Flag Tests.
149 
150   written = __llvm_libc::sprintf(buff, "%.5d", -321);
151   EXPECT_EQ(written, 6);
152   ASSERT_STREQ(buff, "-00321");
153 
154   written = __llvm_libc::sprintf(buff, "%-5d", 246);
155   EXPECT_EQ(written, 5);
156   ASSERT_STREQ(buff, "246  ");
157 
158   written = __llvm_libc::sprintf(buff, "%-5d", -147);
159   EXPECT_EQ(written, 5);
160   ASSERT_STREQ(buff, "-147 ");
161 
162   written = __llvm_libc::sprintf(buff, "%+d", 258);
163   EXPECT_EQ(written, 4);
164   ASSERT_STREQ(buff, "+258");
165 
166   written = __llvm_libc::sprintf(buff, "% d", 369);
167   EXPECT_EQ(written, 4);
168   ASSERT_STREQ(buff, " 369");
169 
170   written = __llvm_libc::sprintf(buff, "%05d", 470);
171   EXPECT_EQ(written, 5);
172   ASSERT_STREQ(buff, "00470");
173 
174   written = __llvm_libc::sprintf(buff, "%05d", -581);
175   EXPECT_EQ(written, 5);
176   ASSERT_STREQ(buff, "-0581");
177 
178   // Combined Tests.
179 
180   written = __llvm_libc::sprintf(buff, "%+ u", 692);
181   EXPECT_EQ(written, 3);
182   ASSERT_STREQ(buff, "692");
183 
184   written = __llvm_libc::sprintf(buff, "%+ -05d", 703);
185   EXPECT_EQ(written, 5);
186   ASSERT_STREQ(buff, "+703 ");
187 
188   written = __llvm_libc::sprintf(buff, "%7.5d", 814);
189   EXPECT_EQ(written, 7);
190   ASSERT_STREQ(buff, "  00814");
191 
192   written = __llvm_libc::sprintf(buff, "%7.5d", -925);
193   EXPECT_EQ(written, 7);
194   ASSERT_STREQ(buff, " -00925");
195 
196   written = __llvm_libc::sprintf(buff, "%7.5d", 159);
197   EXPECT_EQ(written, 7);
198   ASSERT_STREQ(buff, "  00159");
199 
200   written = __llvm_libc::sprintf(buff, "% -7.5d", 260);
201   EXPECT_EQ(written, 7);
202   ASSERT_STREQ(buff, " 00260 ");
203 
204   written = __llvm_libc::sprintf(buff, "%5.4d", 10000);
205   EXPECT_EQ(written, 5);
206   ASSERT_STREQ(buff, "10000");
207 
208   // Multiple Conversion Tests.
209 
210   written = __llvm_libc::sprintf(buff, "%10d %-10d", 456, -789);
211   EXPECT_EQ(written, 21);
212   ASSERT_STREQ(buff, "       456 -789      ");
213 
214   written = __llvm_libc::sprintf(buff, "%-5.4d%+.4u", 75, 25);
215   EXPECT_EQ(written, 9);
216   ASSERT_STREQ(buff, "0075 0025");
217 
218   written = __llvm_libc::sprintf(buff, "% 05hhi %+-0.5llu %-+ 06.3zd",
219                                  256 + 127, 68719476736ll, size_t(2));
220   EXPECT_EQ(written, 24);
221   ASSERT_STREQ(buff, " 0127 68719476736 +002  ");
222 }
223 
224 #ifndef LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE
225 TEST(LlvmLibcSPrintfTest, IndexModeParsing) {
226   char buff[64];
227   int written;
228 
229   written = __llvm_libc::sprintf(buff, "%1$s", "abcDEF123");
230   EXPECT_EQ(written, 9);
231   ASSERT_STREQ(buff, "abcDEF123");
232 
233   written = __llvm_libc::sprintf(buff, "%1$s %%", "abcDEF123");
234   EXPECT_EQ(written, 11);
235   ASSERT_STREQ(buff, "abcDEF123 %");
236 
237   written =
238       __llvm_libc::sprintf(buff, "%3$s %1$s %2$s", "is", "hard", "ordering");
239   EXPECT_EQ(written, 16);
240   ASSERT_STREQ(buff, "ordering is hard");
241 
242   written = __llvm_libc::sprintf(
243       buff, "%10$s %9$s %8$c %7$s %6$s, %6$s %5$s %4$-*1$s %3$.*11$s %2$s. %%",
244       6, "pain", "alphabetical", "such", "is", "this", "do", 'u', "would",
245       "why", 1);
246   EXPECT_EQ(written, 45);
247   ASSERT_STREQ(buff, "why would u do this, this is such   a pain. %");
248 }
249 #endif // LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE
250