[PATCH] msvcrt: printf: Later width specifiers should override earlier ones
David Gow
david at davidgow.net
Sun Nov 7 21:49:52 CST 2021
From: Andrew Eikum <aeikum at codeweavers.com>
This is a replacement for "msvcrt: The '*' character should be
interpreted as the beginning of the width specification"[1], which matches
the behaviour I see on my machine better.
If a printf format string contains both a '*' (to specify that the field
width should be read from a variable), followed by another explicit
field width, only the latter field width should be used.
For further details, see [2] and [3].
[1]: https://source.winehq.org/patches/data/218904
[2]: https://www.winehq.org/pipermail/wine-devel/2021-November/200039.html
[3]: https://github.com/ValveSoftware/Proton/issues/5258#issuecomment-962423092
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Co-Developed-by: David Gow <david at davidgow.net>
Signed-off-by: David Gow <david at davidgow.net>
---
Note also that this moves the new tests after the setlocale(LC_ALL,
"C"), as I don't think they need to run in a Japanese locale.
---
dlls/msvcrt/printf.h | 8 +++++++-
dlls/msvcrt/tests/printf.c | 20 ++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h
index aeb1290f48f..6d2f02ee85b 100644
--- a/dlls/msvcrt/printf.h
+++ b/dlls/msvcrt/printf.h
@@ -1050,7 +1050,13 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
flags.LeftAlign = TRUE;
flags.FieldLength = -flags.FieldLength;
}
- } else while (*p >= '0' && *p <= '9') {
+
+ /* Ignore this length if there's another specifier. */
+ if (*p >= '0' && *p <= '9')
+ flags.FieldLength = 0;
+ }
+
+ while (*p >= '0' && *p <= '9') {
flags.FieldLength *= 10;
flags.FieldLength += *p++ - '0';
}
diff --git a/dlls/msvcrt/tests/printf.c b/dlls/msvcrt/tests/printf.c
index 06acf4c8450..cc824f571a6 100644
--- a/dlls/msvcrt/tests/printf.c
+++ b/dlls/msvcrt/tests/printf.c
@@ -396,6 +396,26 @@ static void test_sprintf( void )
ok(!strcmp(buffer, "string to copy"), "failed: \"%s\"\n", buffer);
setlocale(LC_ALL, "C");
+
+ r = p_sprintf(buffer, "%0*02d", 1, 0);
+ ok(r==2, "r = %d\n", r);
+ ok(!strcmp(buffer, "00"), "failed: \"%s\"\n", buffer);
+
+ r = p_sprintf(buffer, "%0*02d", 30, 17);
+ ok(r==2, "r = %d\n", r);
+ ok(!strcmp(buffer, "17"), "failed: \"%s\"\n", buffer);
+
+ r = p_sprintf(buffer, "%*1d", 1, 3);
+ ok(r==1, "r = %d\n", r);
+ ok(!strcmp(buffer, "3"), "failed: \"%s\"\n", buffer);
+
+ r = p_sprintf(buffer, "%0*0d", 1, 2);
+ ok(r==1, "r = %d\n", r);
+ ok(!strcmp(buffer, "2"), "failed: \"%s\"\n", buffer);
+
+ r = p_sprintf(buffer, "% *2d", 0, 7);
+ ok(r==2, "r = %d\n", r);
+ ok(!strcmp(buffer, " 7"), "failed: \"%s\"\n", buffer);
}
static void test_swprintf( void )
--
2.32.0
More information about the wine-devel
mailing list