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); // 0x101 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 TEST(LlvmLibcSPrintfTest, OctConv) { 366 char buff[64]; 367 int written; 368 369 // Basic Tests. 370 371 written = __llvm_libc::sprintf(buff, "%o", 01234); 372 EXPECT_EQ(written, 4); 373 ASSERT_STREQ(buff, "1234"); 374 375 written = __llvm_libc::sprintf(buff, "%o", 04567); 376 EXPECT_EQ(written, 4); 377 ASSERT_STREQ(buff, "4567"); 378 379 // Length Modifier Tests. 380 381 written = __llvm_libc::sprintf(buff, "%hho", 0401); 382 EXPECT_EQ(written, 1); 383 ASSERT_STREQ(buff, "1"); 384 385 written = __llvm_libc::sprintf(buff, "%llo", 01777777777777777777777ull); 386 EXPECT_EQ(written, 22); 387 ASSERT_STREQ(buff, "1777777777777777777777"); // ull max 388 389 written = __llvm_libc::sprintf(buff, "%to", ~ptrdiff_t(0)); 390 if (sizeof(ptrdiff_t) == 8) { 391 EXPECT_EQ(written, 22); 392 ASSERT_STREQ(buff, "1777777777777777777777"); 393 } else if (sizeof(ptrdiff_t) == 4) { 394 EXPECT_EQ(written, 11); 395 ASSERT_STREQ(buff, "37777777777"); 396 } 397 398 // Min Width Tests. 399 400 written = __llvm_libc::sprintf(buff, "%4o", 0701); 401 EXPECT_EQ(written, 4); 402 ASSERT_STREQ(buff, " 701"); 403 404 written = __llvm_libc::sprintf(buff, "%2o", 0107); 405 EXPECT_EQ(written, 3); 406 ASSERT_STREQ(buff, "107"); 407 408 // Precision Tests. 409 410 written = __llvm_libc::sprintf(buff, "%o", 0); 411 EXPECT_EQ(written, 1); 412 ASSERT_STREQ(buff, "0"); 413 414 written = __llvm_libc::sprintf(buff, "%.0o", 0); 415 EXPECT_EQ(written, 0); 416 ASSERT_STREQ(buff, ""); 417 418 written = __llvm_libc::sprintf(buff, "%.5o", 0153); 419 EXPECT_EQ(written, 5); 420 ASSERT_STREQ(buff, "00153"); 421 422 written = __llvm_libc::sprintf(buff, "%.2o", 0135); 423 EXPECT_EQ(written, 3); 424 ASSERT_STREQ(buff, "135"); 425 426 // Flag Tests. 427 428 written = __llvm_libc::sprintf(buff, "%-5o", 0246); 429 EXPECT_EQ(written, 5); 430 ASSERT_STREQ(buff, "246 "); 431 432 written = __llvm_libc::sprintf(buff, "%#o", 0234); 433 EXPECT_EQ(written, 4); 434 ASSERT_STREQ(buff, "0234"); 435 436 written = __llvm_libc::sprintf(buff, "%05o", 0470); 437 EXPECT_EQ(written, 5); 438 ASSERT_STREQ(buff, "00470"); 439 440 written = __llvm_libc::sprintf(buff, "%0#6o", 0753); 441 EXPECT_EQ(written, 6); 442 ASSERT_STREQ(buff, "000753"); 443 444 written = __llvm_libc::sprintf(buff, "%-#6o", 0642); 445 EXPECT_EQ(written, 6); 446 ASSERT_STREQ(buff, "0642 "); 447 448 // Combined Tests. 449 450 written = __llvm_libc::sprintf(buff, "%#-07o", 0703); 451 EXPECT_EQ(written, 7); 452 ASSERT_STREQ(buff, "0703 "); 453 454 written = __llvm_libc::sprintf(buff, "%7.5o", 0314); 455 EXPECT_EQ(written, 7); 456 ASSERT_STREQ(buff, " 00314"); 457 458 written = __llvm_libc::sprintf(buff, "%#9.5o", 0234); 459 EXPECT_EQ(written, 9); 460 ASSERT_STREQ(buff, " 00234"); 461 462 written = __llvm_libc::sprintf(buff, "%-7.5o", 0260); 463 EXPECT_EQ(written, 7); 464 ASSERT_STREQ(buff, "00260 "); 465 466 written = __llvm_libc::sprintf(buff, "%5.4o", 010000); 467 EXPECT_EQ(written, 5); 468 ASSERT_STREQ(buff, "10000"); 469 470 // Multiple Conversion Tests. 471 472 written = __llvm_libc::sprintf(buff, "%10o %-#10o", 0456, 0123); 473 EXPECT_EQ(written, 21); 474 ASSERT_STREQ(buff, " 456 0123 "); 475 476 written = __llvm_libc::sprintf(buff, "%-5.4o%#.4o", 075, 025); 477 EXPECT_EQ(written, 9); 478 ASSERT_STREQ(buff, "0075 0025"); 479 480 written = __llvm_libc::sprintf(buff, "%04hho %#.5llo %-6.3zo", 256 + 077, 481 01000000000000ll, size_t(2)); 482 EXPECT_EQ(written, 26); 483 ASSERT_STREQ(buff, "0077 01000000000000 002 "); 484 } 485 486 #ifndef LLVM_LIBC_PRINTF_DISABLE_WRITE_INT 487 TEST(LlvmLibcSPrintfTest, WriteIntConv) { 488 char buff[64]; 489 int written; 490 int test_val = -1; 491 492 test_val = -1; 493 written = __llvm_libc::sprintf(buff, "12345%n67890", &test_val); 494 EXPECT_EQ(written, 10); 495 EXPECT_EQ(test_val, 5); 496 ASSERT_STREQ(buff, "1234567890"); 497 498 test_val = -1; 499 written = __llvm_libc::sprintf(buff, "%n", &test_val); 500 EXPECT_EQ(written, 0); 501 EXPECT_EQ(test_val, 0); 502 ASSERT_STREQ(buff, ""); 503 504 test_val = 0x100; 505 written = __llvm_libc::sprintf(buff, "ABC%hhnDEF", &test_val); 506 EXPECT_EQ(written, 6); 507 EXPECT_EQ(test_val, 0x103); 508 ASSERT_STREQ(buff, "ABCDEF"); 509 510 test_val = -1; 511 written = __llvm_libc::sprintf(buff, "%s%n", "87654321", &test_val); 512 EXPECT_EQ(written, 8); 513 EXPECT_EQ(test_val, 8); 514 ASSERT_STREQ(buff, "87654321"); 515 516 written = __llvm_libc::sprintf(buff, "abc123%n", nullptr); 517 EXPECT_LT(written, 0); 518 } 519 #endif // LLVM_LIBC_PRINTF_DISABLE_WRITE_INT 520 521 #ifndef LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE 522 TEST(LlvmLibcSPrintfTest, IndexModeParsing) { 523 char buff[64]; 524 int written; 525 526 written = __llvm_libc::sprintf(buff, "%1$s", "abcDEF123"); 527 EXPECT_EQ(written, 9); 528 ASSERT_STREQ(buff, "abcDEF123"); 529 530 written = __llvm_libc::sprintf(buff, "%1$s %%", "abcDEF123"); 531 EXPECT_EQ(written, 11); 532 ASSERT_STREQ(buff, "abcDEF123 %"); 533 534 written = 535 __llvm_libc::sprintf(buff, "%3$s %1$s %2$s", "is", "hard", "ordering"); 536 EXPECT_EQ(written, 16); 537 ASSERT_STREQ(buff, "ordering is hard"); 538 539 written = __llvm_libc::sprintf( 540 buff, "%10$s %9$s %8$c %7$s %6$s, %6$s %5$s %4$-*1$s %3$.*11$s %2$s. %%", 541 6, "pain", "alphabetical", "such", "is", "this", "do", 'u', "would", 542 "why", 1); 543 EXPECT_EQ(written, 45); 544 ASSERT_STREQ(buff, "why would u do this, this is such a pain. %"); 545 } 546 #endif // LLVM_LIBC_PRINTF_DISABLE_INDEX_MODE 547