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 TEST(LlvmLibcSPrintfTest, PointerConv) { 350 char buff[64]; 351 int written; 352 353 written = __llvm_libc::sprintf(buff, "%p", nullptr); 354 EXPECT_EQ(written, 9); 355 ASSERT_STREQ(buff, "(nullptr)"); 356 357 written = __llvm_libc::sprintf(buff, "%p", 0x1a2b3c4d); 358 EXPECT_EQ(written, 10); 359 ASSERT_STREQ(buff, "0x1a2b3c4d"); 360 361 written = __llvm_libc::sprintf(buff, "%p", buff); 362 EXPECT_GT(written, 0); 363 } 364 365 #ifndef LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE 366 TEST(LlvmLibcSPrintfTest, IndexModeParsing) { 367 char buff[64]; 368 int written; 369 370 written = __llvm_libc::sprintf(buff, "%1$s", "abcDEF123"); 371 EXPECT_EQ(written, 9); 372 ASSERT_STREQ(buff, "abcDEF123"); 373 374 written = __llvm_libc::sprintf(buff, "%1$s %%", "abcDEF123"); 375 EXPECT_EQ(written, 11); 376 ASSERT_STREQ(buff, "abcDEF123 %"); 377 378 written = 379 __llvm_libc::sprintf(buff, "%3$s %1$s %2$s", "is", "hard", "ordering"); 380 EXPECT_EQ(written, 16); 381 ASSERT_STREQ(buff, "ordering is hard"); 382 383 written = __llvm_libc::sprintf( 384 buff, "%10$s %9$s %8$c %7$s %6$s, %6$s %5$s %4$-*1$s %3$.*11$s %2$s. %%", 385 6, "pain", "alphabetical", "such", "is", "this", "do", 'u', "would", 386 "why", 1); 387 EXPECT_EQ(written, 45); 388 ASSERT_STREQ(buff, "why would u do this, this is such a pain. %"); 389 } 390 #endif // LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE 391