| // Copyright 2016 The Fuchsia Authors |
| // Copyright (c) 2008-2014 Travis Geiselbrecht |
| // |
| // Use of this source code is governed by a MIT-style |
| // license that can be found in the LICENSE file or at |
| // https://opensource.org/licenses/MIT |
| |
| #include <lib/unittest/unittest.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include <ktl/string_view.h> |
| |
| #include "tests.h" |
| |
| #include <ktl/enforce.h> |
| |
| #ifndef _KERNEL |
| using ssize_t = ptrdiff_t; |
| #endif |
| |
| // Checks that vsnprintf() gives the expected string as output. |
| static bool test_printf(const char* expected, const char* format, ...) { |
| char buf[100]; |
| va_list args; |
| va_start(args, format); |
| int length = vsnprintf(buf, sizeof(buf), format, args); |
| va_end(args); |
| |
| if (length < 0 || length >= (int)sizeof(buf)) { |
| printf("vsnprintf() returned %d\n", length); |
| return false; |
| } |
| |
| bool success = true; |
| if (buf[length] != '\0') { |
| printf("missing string terminator\n"); |
| success = false; |
| } |
| if (length != (int)strlen(expected) || memcmp(buf, expected, length + 1) != 0) { |
| printf("expected: \"%s\" (length %zu)\n", expected, strlen(expected)); |
| printf("but got: \"%s\" (length %zu) with return value %d)\n", buf, strlen(buf), length); |
| success = false; |
| } |
| return success; |
| } |
| |
| static bool numbers() { |
| BEGIN_TEST; |
| |
| EXPECT_TRUE(test_printf("int8: -12 0 -2", "int8: %hhd %hhd %hhd", -12, 0, 254)); |
| EXPECT_TRUE(test_printf("uint8: 244 0 254", "uint8: %hhu %hhu %hhu", -12, 0, 254)); |
| EXPECT_TRUE(test_printf("int16: -1234 0 1234", "int16: %hd %hd %hd", -1234, 0, 1234)); |
| EXPECT_TRUE(test_printf("uint16:64302 0 1234", "uint16:%hu %hu %hu", -1234, 0, 1234)); |
| EXPECT_TRUE( |
| test_printf("int: -12345678 0 12345678", "int: %d %d %d", -12345678, 0, 12345678)); |
| static_assert(-12345678U == 4282621618, ""); |
| EXPECT_TRUE( |
| test_printf("uint: 4282621618 0 12345678", "uint: %u %u %u", -12345678, 0, 12345678)); |
| EXPECT_TRUE( |
| test_printf("long: -12345678 0 12345678", "long: %ld %ld %ld", -12345678L, 0L, 12345678L)); |
| #ifdef _LP64 |
| static_assert(-12345678UL == 18446744073697205938UL, ""); |
| EXPECT_TRUE(test_printf("ulong: 18446744073697205938 0 12345678", "ulong: %lu %lu %lu", |
| -12345678UL, 0UL, 12345678UL)); |
| #else |
| static_assert(-12345678UL == 4282621618UL, ""); |
| EXPECT_TRUE(test_printf("ulong: 4282621618 0 12345678", "ulong: %lu %lu %lu", -12345678UL, 0UL, |
| 12345678UL)); |
| #endif |
| |
| EXPECT_TRUE(test_printf("longlong: -12345678 0 12345678", "longlong: %lli %lli %lli", -12345678LL, |
| 0LL, 12345678LL)); |
| EXPECT_TRUE(test_printf("ulonglong: 18446744073697205938 0 12345678", "ulonglong: %llu %llu %llu", |
| -12345678LL, 0LL, 12345678LL)); |
| EXPECT_TRUE(test_printf("ssize_t: -12345678 0 12345678", "ssize_t: %zd %zd %zd", |
| (ssize_t)-12345678, (ssize_t)0, (ssize_t)12345678)); |
| #ifdef _LP64 |
| EXPECT_TRUE(test_printf("usize_t: 18446744073697205938 0 12345678", "usize_t: %zu %zu %zu", |
| (size_t)-12345678, (size_t)0, (size_t)12345678)); |
| #else |
| EXPECT_TRUE(test_printf("usize_t: 4282621618 0 12345678", "usize_t: %zu %zu %zu", |
| (size_t)-12345678, (size_t)0, (size_t)12345678)); |
| #endif |
| EXPECT_TRUE(test_printf("intmax_t: -12345678 0 12345678", "intmax_t: %jd %jd %jd", |
| (intmax_t)-12345678, (intmax_t)0, (intmax_t)12345678)); |
| EXPECT_TRUE(test_printf("uintmax_t: 18446744073697205938 0 12345678", "uintmax_t: %ju %ju %ju", |
| (uintmax_t)-12345678, (uintmax_t)0, (uintmax_t)12345678)); |
| EXPECT_TRUE(test_printf("ptrdiff_t: -12345678 0 12345678", "ptrdiff_t: %td %td %td", |
| (ptrdiff_t)-12345678, (ptrdiff_t)0, (ptrdiff_t)12345678)); |
| #ifdef _LP64 |
| EXPECT_TRUE(test_printf("ptrdiff_t (u): 18446744073697205938 0 12345678", |
| "ptrdiff_t (u): %tu %tu %tu", (ptrdiff_t)-12345678, (ptrdiff_t)0, |
| (ptrdiff_t)12345678)); |
| #else |
| EXPECT_TRUE(test_printf("ptrdiff_t (u): 4282621618 0 12345678", "ptrdiff_t (u): %tu %tu %tu", |
| (ptrdiff_t)-12345678, (ptrdiff_t)0, (ptrdiff_t)12345678)); |
| #endif |
| |
| END_TEST; |
| } |
| |
| static bool hex() { |
| BEGIN_TEST; |
| |
| EXPECT_TRUE(test_printf("uint8: f4 0 fe", "uint8: %hhx %hhx %hhx", -12, 0, 254)); |
| EXPECT_TRUE(test_printf("uint16:fb2e 0 4d2", "uint16:%hx %hx %hx", -1234, 0, 1234)); |
| EXPECT_TRUE(test_printf("uint: ff439eb2 0 bc614e", "uint: %x %x %x", -12345678, 0, 12345678)); |
| #ifdef _LP64 |
| EXPECT_TRUE(test_printf("ulong: ffffffffff439eb2 0 bc614e", "ulong: %lx %lx %lx", -12345678UL, |
| 0UL, 12345678UL)); |
| #else |
| EXPECT_TRUE( |
| test_printf("ulong: ff439eb2 0 bc614e", "ulong: %lx %lx %lx", -12345678UL, 0UL, 12345678UL)); |
| #endif |
| EXPECT_TRUE(test_printf("ulong: FF439EB2 0 BC614E", "ulong: %X %X %X", -12345678, 0, 12345678)); |
| EXPECT_TRUE(test_printf("ulonglong: ffffffffff439eb2 0 bc614e", "ulonglong: %llx %llx %llx", |
| -12345678LL, 0LL, 12345678LL)); |
| #ifdef _LP64 |
| EXPECT_TRUE(test_printf("usize_t: ffffffffff439eb2 0 bc614e", "usize_t: %zx %zx %zx", |
| (size_t)-12345678, (size_t)0, (size_t)12345678)); |
| #else |
| EXPECT_TRUE(test_printf("usize_t: ff439eb2 0 bc614e", "usize_t: %zx %zx %zx", (size_t)-12345678, |
| (size_t)0, (size_t)12345678)); |
| #endif |
| |
| END_TEST; |
| } |
| |
| static bool alt_and_sign() { |
| BEGIN_TEST; |
| |
| EXPECT_TRUE(test_printf("uint: 0xabcdef 0XABCDEF", "uint: %#x %#X", 0xabcdef, 0xabcdef)); |
| EXPECT_TRUE(test_printf("int: +12345678 -12345678", "int: %+d %+d", 12345678, -12345678)); |
| EXPECT_TRUE(test_printf("int: 12345678 +12345678", "int: % d %+d", 12345678, 12345678)); |
| |
| // Test if zero-padding works fine with hex's alt (%#x) |
| EXPECT_TRUE(test_printf("uint: 0x02 0X02", "uint: %#04x %#04X", 2, 2)); |
| EXPECT_TRUE(test_printf("uint: 0x0000002 0X0000002", "uint: %#09x %#09X", 2, 2)); |
| EXPECT_TRUE(test_printf("uint: 0x2 0X2", "uint: %#02x %#02X", 2, 2)); |
| |
| END_TEST; |
| } |
| |
| static bool formatting() { |
| BEGIN_TEST; |
| |
| EXPECT_TRUE(test_printf("int: a12345678a", "int: a%8da", 12345678)); |
| EXPECT_TRUE(test_printf("int: a 12345678a", "int: a%9da", 12345678)); |
| EXPECT_TRUE(test_printf("int: a12345678 a", "int: a%-9da", 12345678)); |
| EXPECT_TRUE(test_printf("int: a 12345678a", "int: a%10da", 12345678)); |
| EXPECT_TRUE(test_printf("int: a12345678 a", "int: a%-10da", 12345678)); |
| EXPECT_TRUE(test_printf("int: a012345678a", "int: a%09da", 12345678)); |
| EXPECT_TRUE(test_printf("int: a0012345678a", "int: a%010da", 12345678)); |
| EXPECT_TRUE(test_printf("int: a12345678a", "int: a%6da", 12345678)); |
| |
| EXPECT_TRUE(test_printf("aba", "a%1sa", "b")); |
| EXPECT_TRUE(test_printf("a ba", "a%9sa", "b")); |
| EXPECT_TRUE(test_printf("ab a", "a%-9sa", "b")); |
| EXPECT_TRUE(test_printf("athisisatesta", "a%5sa", "thisisatest")); |
| |
| EXPECT_TRUE(test_printf("-02", "%03d", -2)); |
| EXPECT_TRUE(test_printf("-02", "%0+3d", -2)); |
| EXPECT_TRUE(test_printf("+02", "%0+3d", 2)); |
| EXPECT_TRUE(test_printf(" +2", "%+3d", 2)); |
| EXPECT_TRUE(test_printf("-2000", "% 3d", -2000)); |
| EXPECT_TRUE(test_printf(" 2000", "% 3d", 2000)); |
| EXPECT_TRUE(test_printf("+2000", "%+3d", 2000)); |
| EXPECT_TRUE(test_printf(" test", "%10s", "test")); |
| EXPECT_TRUE(test_printf(" test", "%010s", "test")); |
| EXPECT_TRUE(test_printf("test ", "%-10s", "test")); |
| EXPECT_TRUE(test_printf("test ", "%-010s", "test")); |
| |
| EXPECT_TRUE(test_printf("test", "%V", "test"sv)); |
| EXPECT_TRUE(test_printf("test", "%V", "testlonger"sv.substr(0, 4))); |
| EXPECT_TRUE(test_printf("test", "%.*V", 4, "testlonger"sv)); |
| |
| END_TEST; |
| } |
| |
| static bool printf_field_width_and_precision_test() { |
| BEGIN_TEST; |
| |
| const char input[] = "0123456789"; |
| |
| // Hard-coded width; no precision. |
| EXPECT_TRUE(test_printf("'0123456789'", "'%0s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%1s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%2s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%10s'", input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%11s'", input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%12s'", input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%15s'", input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%20s'", input)); |
| |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-0s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-1s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-2s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-10s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%-11s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%-12s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%-15s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%-20s'", input)); |
| |
| // variable width; no precision. |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", 0, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", 1, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", 2, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", 10, input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%*s'", 11, input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%*s'", 12, input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%*s'", 15, input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%*s'", 20, input)); |
| |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", -1, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", -2, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", -5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*s'", -10, input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%*s'", -11, input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%*s'", -12, input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%*s'", -15, input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%*s'", -20, input)); |
| |
| // No width; hard-coded precision. |
| EXPECT_TRUE(test_printf("", "%.", input)); |
| EXPECT_TRUE(test_printf("", "%.s", input)); |
| EXPECT_TRUE(test_printf("''", "'%.0s'", input)); |
| EXPECT_TRUE(test_printf("'0'", "'%.1s'", input)); |
| EXPECT_TRUE(test_printf("'01'", "'%.2s'", input)); |
| EXPECT_TRUE(test_printf("'012'", "'%.3s'", input)); |
| EXPECT_TRUE(test_printf("'0123'", "'%.4s'", input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%.5s'", input)); |
| EXPECT_TRUE(test_printf("'012345'", "'%.6s'", input)); |
| EXPECT_TRUE(test_printf("'0123456'", "'%.7s'", input)); |
| EXPECT_TRUE(test_printf("'01234567'", "'%.8s'", input)); |
| EXPECT_TRUE(test_printf("'012345678'", "'%.9s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%.10s'", input)); |
| |
| // No width; variable precision. |
| EXPECT_TRUE(test_printf("'0'", "'%.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("'01'", "'%.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("'012'", "'%.*s'", 3, input)); |
| EXPECT_TRUE(test_printf("'0123'", "'%.*s'", 4, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'012345'", "'%.*s'", 6, input)); |
| EXPECT_TRUE(test_printf("'0123456'", "'%.*s'", 7, input)); |
| EXPECT_TRUE(test_printf("'01234567'", "'%.*s'", 8, input)); |
| EXPECT_TRUE(test_printf("'012345678'", "'%.*s'", 9, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%.*s'", 10, input)); |
| |
| // Hard-coded width; hard-coded precision. |
| EXPECT_TRUE(test_printf("''", "'%0.0s'", input)); |
| EXPECT_TRUE(test_printf("'0'", "'%0.1s'", input)); |
| EXPECT_TRUE(test_printf("'01'", "'%0.2s'", input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%0.5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%0.10s'", input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%5.0s'", input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%5.1s'", input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%5.2s'", input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%5.5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%5.10s'", input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%10.0s'", input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%10.1s'", input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%10.2s'", input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%10.5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%10.10s'", input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%15.0s'", input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%15.1s'", input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%15.2s'", input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%15.5s'", input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%15.10s'", input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%-5.0s'", input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%-5.1s'", input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%-5.2s'", input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%-5.5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-5.10s'", input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%-10.0s'", input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%-10.1s'", input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%-10.2s'", input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%-10.5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-10.10s'", input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%-15.0s'", input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%-15.1s'", input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%-15.2s'", input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%-15.5s'", input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%-15.10s'", input)); |
| |
| // Variable width; hard-coded precision. |
| EXPECT_TRUE(test_printf("''", "'%*.0s'", 0, input)); |
| EXPECT_TRUE(test_printf("'0'", "'%*.1s'", 0, input)); |
| EXPECT_TRUE(test_printf("'01'", "'%*.2s'", 0, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%*.5s'", 0, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.10s'", 0, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.0s'", 5, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%*.1s'", 5, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%*.2s'", 5, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%*.5s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.10s'", 5, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.0s'", 10, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%*.1s'", 10, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%*.2s'", 10, input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%*.5s'", 10, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.10s'", 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.0s'", 15, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%*.1s'", 15, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%*.2s'", 15, input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%*.5s'", 15, input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%*.10s'", 15, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.0s'", -5, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%*.1s'", -5, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%*.2s'", -5, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%*.5s'", -5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.10s'", -5, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.0s'", -10, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%*.1s'", -10, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%*.2s'", -10, input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%*.5s'", -10, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.10s'", -10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.0s'", -15, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%*.1s'", -15, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%*.2s'", -15, input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%*.5s'", -15, input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%*.10s'", -15, input)); |
| |
| // Hard-coded width; variable precision. |
| EXPECT_TRUE(test_printf("''", "'%0.*s'", 0, input)); |
| EXPECT_TRUE(test_printf("'0'", "'%0.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("'01'", "'%0.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%0.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%0.*s'", 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%5.*s'", 0, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%5.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%5.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%5.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%5.*s'", 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%10.*s'", 0, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%10.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%10.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%10.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%10.*s'", 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%15.*s'", 0, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%15.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%15.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%15.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%15.*s'", 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%-5.*s'", 0, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%-5.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%-5.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%-5.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-5.*s'", 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%-10.*s'", 0, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%-10.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%-10.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%-10.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%-10.*s'", 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%-15.*s'", 0, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%-15.*s'", 1, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%-15.*s'", 2, input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%-15.*s'", 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%-15.*s'", 10, input)); |
| |
| // Variable width; variable precision. |
| EXPECT_TRUE(test_printf("''", "'%*.*s'", 0, 0, input)); |
| EXPECT_TRUE(test_printf("'0'", "'%*.*s'", 0, 1, input)); |
| EXPECT_TRUE(test_printf("'01'", "'%*.*s'", 0, 2, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%*.*s'", 0, 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.*s'", 0, 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.*s'", 5, 0, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%*.*s'", 5, 1, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%*.*s'", 5, 2, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%*.*s'", 5, 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.*s'", 5, 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.*s'", 10, 0, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%*.*s'", 10, 1, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%*.*s'", 10, 2, input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%*.*s'", 10, 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.*s'", 10, 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.*s'", 15, 0, input)); |
| EXPECT_TRUE(test_printf("' 0'", "'%*.*s'", 15, 1, input)); |
| EXPECT_TRUE(test_printf("' 01'", "'%*.*s'", 15, 2, input)); |
| EXPECT_TRUE(test_printf("' 01234'", "'%*.*s'", 15, 5, input)); |
| EXPECT_TRUE(test_printf("' 0123456789'", "'%*.*s'", 15, 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.*s'", -5, 0, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%*.*s'", -5, 1, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%*.*s'", -5, 2, input)); |
| EXPECT_TRUE(test_printf("'01234'", "'%*.*s'", -5, 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.*s'", -5, 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.*s'", -10, 0, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%*.*s'", -10, 1, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%*.*s'", -10, 2, input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%*.*s'", -10, 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789'", "'%*.*s'", -10, 10, input)); |
| |
| EXPECT_TRUE(test_printf("' '", "'%*.*s'", -15, 0, input)); |
| EXPECT_TRUE(test_printf("'0 '", "'%*.*s'", -15, 1, input)); |
| EXPECT_TRUE(test_printf("'01 '", "'%*.*s'", -15, 2, input)); |
| EXPECT_TRUE(test_printf("'01234 '", "'%*.*s'", -15, 5, input)); |
| EXPECT_TRUE(test_printf("'0123456789 '", "'%*.*s'", -15, 10, input)); |
| |
| END_TEST; |
| } |
| |
| // Test snprintf() when the output is larger than the given buffer. |
| static bool snprintf_truncation_test() { |
| BEGIN_TEST; |
| |
| char buf[32]; |
| |
| memset(buf, 'x', sizeof(buf)); |
| static const char str[26] = "0123456789abcdef012345678"; |
| int shorter_length = 15; |
| int result = snprintf(buf, shorter_length, "%s", str); |
| |
| // Check that snprintf() returns the length of the string that it would |
| // have written if the buffer was big enough. |
| EXPECT_EQ(result, (int)strlen(str)); |
| |
| // Check that snprintf() wrote a truncated, terminated string. |
| EXPECT_EQ(memcmp(buf, str, shorter_length - 1), 0); |
| EXPECT_EQ(buf[shorter_length - 1], '\0'); |
| |
| // Check that snprintf() did not overrun the buffer it was given. |
| for (uint32_t i = shorter_length; i < sizeof(buf); ++i) |
| EXPECT_EQ(buf[i], 'x'); |
| |
| END_TEST; |
| } |
| |
| UNITTEST_START_TESTCASE(printf_tests) |
| UNITTEST("numbers", numbers) |
| UNITTEST("hex", hex) |
| UNITTEST("alt_and_sign", alt_and_sign) |
| UNITTEST("formatting", formatting) |
| UNITTEST("printf_field_width_and_precision_tests", printf_field_width_and_precision_test) |
| UNITTEST("snprintf_truncation_test", snprintf_truncation_test) |
| UNITTEST_END_TESTCASE(printf_tests, "printf_tests", "printf_tests") |