diff --git a/AK/PrintfImplementation.h b/AK/PrintfImplementation.h index 7953ab074b0..ffaa6108576 100644 --- a/AK/PrintfImplementation.h +++ b/AK/PrintfImplementation.h @@ -503,6 +503,8 @@ ALWAYS_INLINE int printf_internal(PutChFunc putch, IdentityType* buffe ++p; if (*p == '.') { state.dot = true; + state.has_precision = true; + state.precision = 0; if (*(p + 1)) goto one_more; } @@ -528,10 +530,6 @@ ALWAYS_INLINE int printf_internal(PutChFunc putch, IdentityType* buffe if (*(p + 1)) goto one_more; } else { - if (!state.has_precision) { - state.has_precision = true; - state.precision = 0; - } state.precision *= 10; state.precision += *p - '0'; if (*(p + 1)) @@ -540,7 +538,6 @@ ALWAYS_INLINE int printf_internal(PutChFunc putch, IdentityType* buffe } if (*p == '*') { if (state.dot) { - state.has_precision = true; state.zero_pad = true; state.precision = NextArgument()(ap); } else { diff --git a/Tests/LibC/TestSnprintf.cpp b/Tests/LibC/TestSnprintf.cpp index 5f2bf015515..17c3b62acbd 100644 --- a/Tests/LibC/TestSnprintf.cpp +++ b/Tests/LibC/TestSnprintf.cpp @@ -275,7 +275,22 @@ TEST_CASE(inttypes_macros) EXPECT(test_single({ LITERAL("xxxxxxx"), "|%" PRIX16 "|", 0xC0DE, 6, LITERAL("|C0DE|\0") })); } -TEST_CASE(float_values) +TEST_CASE(float_value_precision) +{ + // An empty precision value implies a precision of 0. + EXPECT(test_single({ LITERAL("xxx\0"), "|%.f|", 0, 3, LITERAL("|0|\0") })); + EXPECT(test_single({ LITERAL("xxx\0"), "|%.f|", 1.23456789, 3, LITERAL("|1|\0") })); + EXPECT(test_single({ LITERAL("xxx\0"), "|%.0f|", 0, 3, LITERAL("|0|\0") })); + EXPECT(test_single({ LITERAL("xxx\0"), "|%.0f|", 1.23456789, 3, LITERAL("|1|\0") })); + + // The default value for the precision is 6. + EXPECT(test_single({ LITERAL("xxxxxxxxxx\0"), "|%f|", 0, 10, LITERAL("|0.000000|\0") })); + EXPECT(test_single({ LITERAL("xxxxxxxxxx\0"), "|%f|", 1.23456789, 10, LITERAL("|1.234567|\0") })); + EXPECT(test_single({ LITERAL("xxxxxxxxxx\0"), "|%.6f|", 0, 10, LITERAL("|0.000000|\0") })); + EXPECT(test_single({ LITERAL("xxxxxxxxxx\0"), "|%.6f|", 1.23456789, 10, LITERAL("|1.234567|\0") })); +} + +TEST_CASE(float_value_special) { union { float f; @@ -291,6 +306,19 @@ TEST_CASE(float_values) EXPECT(test_single({ LITERAL("xxxxxxx"), "|%4f|", -v.f, 6, LITERAL("|-inf|\0") })); } +TEST_CASE(string_precision) +{ + // Print the entire string by default. + EXPECT(test_single({ LITERAL("xxxxxx\0"), "|%s|", "WHF!", 6, LITERAL("|WHF!|\0") })); + + // Precision limits the number of characters that are printed. + EXPECT(test_single({ LITERAL("xxxx\0"), "|%.2s|", "WHF!", 4, LITERAL("|WH|\0") })); + EXPECT(test_single({ LITERAL("xxxxxx\0"), "|%.7s|", "WHF!", 6, LITERAL("|WHF!|\0") })); + + // An empty precision value implies a precision of 0. + EXPECT(test_single({ LITERAL("xx\0"), "|%.s|", "WHF!", 2, LITERAL("||\0") })); +} + TEST_CASE(truncation) { EXPECT(test_single({ LITERAL("xxxxxxxxxxxxx"), "|%d|", INT_MAX, 12, LITERAL("|2147483647|\0") }));