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 TEST(LlvmLibcSPrintfTest, HexConv) {
225   char buff[64];
226   int written;
227 
228   // Basic Tests.
229 
230   written = __llvm_libc::sprintf(buff, "%x", 0x123a);
231   EXPECT_EQ(written, 4);
232   ASSERT_STREQ(buff, "123a");
233 
234   written = __llvm_libc::sprintf(buff, "%X", 0x456b);
235   EXPECT_EQ(written, 4);
236   ASSERT_STREQ(buff, "456B");
237 
238   // Length Modifier Tests.
239 
240   written = __llvm_libc::sprintf(buff, "%hhx", 0x10001);
241   EXPECT_EQ(written, 1);
242   ASSERT_STREQ(buff, "1");
243 
244   written = __llvm_libc::sprintf(buff, "%llx", 0xffffffffffffffffull);
245   EXPECT_EQ(written, 16);
246   ASSERT_STREQ(buff, "ffffffffffffffff"); // ull max
247 
248   written = __llvm_libc::sprintf(buff, "%tX", ~ptrdiff_t(0));
249   if (sizeof(ptrdiff_t) == 8) {
250     EXPECT_EQ(written, 16);
251     ASSERT_STREQ(buff, "FFFFFFFFFFFFFFFF");
252   } else if (sizeof(ptrdiff_t) == 4) {
253     EXPECT_EQ(written, 8);
254     ASSERT_STREQ(buff, "FFFFFFFF");
255   }
256 
257   // Min Width Tests.
258 
259   written = __llvm_libc::sprintf(buff, "%4x", 0x789);
260   EXPECT_EQ(written, 4);
261   ASSERT_STREQ(buff, " 789");
262 
263   written = __llvm_libc::sprintf(buff, "%2X", 0x987);
264   EXPECT_EQ(written, 3);
265   ASSERT_STREQ(buff, "987");
266 
267   // Precision Tests.
268 
269   written = __llvm_libc::sprintf(buff, "%x", 0);
270   EXPECT_EQ(written, 1);
271   ASSERT_STREQ(buff, "0");
272 
273   written = __llvm_libc::sprintf(buff, "%.0x", 0);
274   EXPECT_EQ(written, 0);
275   ASSERT_STREQ(buff, "");
276 
277   written = __llvm_libc::sprintf(buff, "%.5x", 0x1F3);
278   EXPECT_EQ(written, 5);
279   ASSERT_STREQ(buff, "001f3");
280 
281   written = __llvm_libc::sprintf(buff, "%.2x", 0x135);
282   EXPECT_EQ(written, 3);
283   ASSERT_STREQ(buff, "135");
284 
285   // Flag Tests.
286 
287   written = __llvm_libc::sprintf(buff, "%-5x", 0x246);
288   EXPECT_EQ(written, 5);
289   ASSERT_STREQ(buff, "246  ");
290 
291   written = __llvm_libc::sprintf(buff, "%#x", 0xd3f);
292   EXPECT_EQ(written, 5);
293   ASSERT_STREQ(buff, "0xd3f");
294 
295   written = __llvm_libc::sprintf(buff, "%#X", 0xE40);
296   EXPECT_EQ(written, 5);
297   ASSERT_STREQ(buff, "0XE40");
298 
299   written = __llvm_libc::sprintf(buff, "%05x", 0x470);
300   EXPECT_EQ(written, 5);
301   ASSERT_STREQ(buff, "00470");
302 
303   written = __llvm_libc::sprintf(buff, "%0#6x", 0x8c3);
304   EXPECT_EQ(written, 6);
305   ASSERT_STREQ(buff, "0x08c3");
306 
307   written = __llvm_libc::sprintf(buff, "%-#6x", 0x5f0);
308   EXPECT_EQ(written, 6);
309   ASSERT_STREQ(buff, "0x5f0 ");
310 
311   // Combined Tests.
312 
313   written = __llvm_libc::sprintf(buff, "%#-07x", 0x703);
314   EXPECT_EQ(written, 7);
315   ASSERT_STREQ(buff, "0x703  ");
316 
317   written = __llvm_libc::sprintf(buff, "%7.5x", 0x814);
318   EXPECT_EQ(written, 7);
319   ASSERT_STREQ(buff, "  00814");
320 
321   written = __llvm_libc::sprintf(buff, "%#9.5X", 0x9d4);
322   EXPECT_EQ(written, 9);
323   ASSERT_STREQ(buff, "  0X009D4");
324 
325   written = __llvm_libc::sprintf(buff, "%-7.5x", 0x260);
326   EXPECT_EQ(written, 7);
327   ASSERT_STREQ(buff, "00260  ");
328 
329   written = __llvm_libc::sprintf(buff, "%5.4x", 0x10000);
330   EXPECT_EQ(written, 5);
331   ASSERT_STREQ(buff, "10000");
332 
333   // Multiple Conversion Tests.
334 
335   written = __llvm_libc::sprintf(buff, "%10X %-#10x", 0x45b, 0x789);
336   EXPECT_EQ(written, 21);
337   ASSERT_STREQ(buff, "       45B 0x789     ");
338 
339   written = __llvm_libc::sprintf(buff, "%-5.4x%#.4x", 0x75, 0x25);
340   EXPECT_EQ(written, 11);
341   ASSERT_STREQ(buff, "0075 0x0025");
342 
343   written = __llvm_libc::sprintf(buff, "%04hhX %#.5llx %-6.3zX", 256 + 0x7f,
344                                  0x1000000000ll, size_t(2));
345   EXPECT_EQ(written, 24);
346   ASSERT_STREQ(buff, "007F 0x1000000000 002   ");
347 }
348 
349 #ifndef LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE
350 TEST(LlvmLibcSPrintfTest, IndexModeParsing) {
351   char buff[64];
352   int written;
353 
354   written = __llvm_libc::sprintf(buff, "%1$s", "abcDEF123");
355   EXPECT_EQ(written, 9);
356   ASSERT_STREQ(buff, "abcDEF123");
357 
358   written = __llvm_libc::sprintf(buff, "%1$s %%", "abcDEF123");
359   EXPECT_EQ(written, 11);
360   ASSERT_STREQ(buff, "abcDEF123 %");
361 
362   written =
363       __llvm_libc::sprintf(buff, "%3$s %1$s %2$s", "is", "hard", "ordering");
364   EXPECT_EQ(written, 16);
365   ASSERT_STREQ(buff, "ordering is hard");
366 
367   written = __llvm_libc::sprintf(
368       buff, "%10$s %9$s %8$c %7$s %6$s, %6$s %5$s %4$-*1$s %3$.*11$s %2$s. %%",
369       6, "pain", "alphabetical", "such", "is", "this", "do", 'u', "would",
370       "why", 1);
371   EXPECT_EQ(written, 45);
372   ASSERT_STREQ(buff, "why would u do this, this is such   a pain. %");
373 }
374 #endif // LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE
375