AK: Implement printf's "period without precision value" correctly

This commit is contained in:
Tim Schumacher 2023-10-03 17:34:28 +02:00 committed by Andreas Kling
parent 0068e91aad
commit 87bcaa6151
Notes: sideshowbarker 2024-07-18 02:13:10 +09:00
2 changed files with 31 additions and 6 deletions

View file

@ -503,6 +503,8 @@ ALWAYS_INLINE int printf_internal(PutChFunc putch, IdentityType<CharType>* 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<CharType>* 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<CharType>* buffe
}
if (*p == '*') {
if (state.dot) {
state.has_precision = true;
state.zero_pad = true;
state.precision = NextArgument<int>()(ap);
} else {

View file

@ -275,7 +275,22 @@ TEST_CASE(inttypes_macros)
EXPECT(test_single<uint16_t>({ 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<double>({ LITERAL("xxx\0"), "|%.f|", 0, 3, LITERAL("|0|\0") }));
EXPECT(test_single<double>({ LITERAL("xxx\0"), "|%.f|", 1.23456789, 3, LITERAL("|1|\0") }));
EXPECT(test_single<double>({ LITERAL("xxx\0"), "|%.0f|", 0, 3, LITERAL("|0|\0") }));
EXPECT(test_single<double>({ LITERAL("xxx\0"), "|%.0f|", 1.23456789, 3, LITERAL("|1|\0") }));
// The default value for the precision is 6.
EXPECT(test_single<double>({ LITERAL("xxxxxxxxxx\0"), "|%f|", 0, 10, LITERAL("|0.000000|\0") }));
EXPECT(test_single<double>({ LITERAL("xxxxxxxxxx\0"), "|%f|", 1.23456789, 10, LITERAL("|1.234567|\0") }));
EXPECT(test_single<double>({ LITERAL("xxxxxxxxxx\0"), "|%.6f|", 0, 10, LITERAL("|0.000000|\0") }));
EXPECT(test_single<double>({ 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<double>({ LITERAL("xxxxxxx"), "|%4f|", -v.f, 6, LITERAL("|-inf|\0") }));
}
TEST_CASE(string_precision)
{
// Print the entire string by default.
EXPECT(test_single<char const*>({ LITERAL("xxxxxx\0"), "|%s|", "WHF!", 6, LITERAL("|WHF!|\0") }));
// Precision limits the number of characters that are printed.
EXPECT(test_single<char const*>({ LITERAL("xxxx\0"), "|%.2s|", "WHF!", 4, LITERAL("|WH|\0") }));
EXPECT(test_single<char const*>({ LITERAL("xxxxxx\0"), "|%.7s|", "WHF!", 6, LITERAL("|WHF!|\0") }));
// An empty precision value implies a precision of 0.
EXPECT(test_single<char const*>({ LITERAL("xx\0"), "|%.s|", "WHF!", 2, LITERAL("||\0") }));
}
TEST_CASE(truncation)
{
EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxxx"), "|%d|", INT_MAX, 12, LITERAL("|2147483647|\0") }));