From: Paul Gofman pgofman@codeweavers.com
--- dlls/shlwapi/tests/string.c | 107 ++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index 8379a523733..998931e85a8 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -1689,6 +1689,112 @@ static void test_StrCatChainW(void) ok(buf[5] == 'e', "Expected buf[5] = 'e', got %x\n", buf[5]); }
+static void test_printf_format(void) +{ + const struct + { + const char *spec; + unsigned int arg_size; + const char *expected; + const WCHAR *expectedw; + ULONG64 arg; + const void *argw; + } + tests[] = + { + { "%qu", 0, "qu", NULL, 10 }, + { "%lu", sizeof(ULONG), "10", NULL, 10 }, + { "%#lx", sizeof(ULONG), "0xa", NULL, 10 }, + { "%hu", sizeof(ULONG), "10", NULL, 10 }, + { "%s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, + { "%S", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%ls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%lS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%hs", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, + { "%hS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, + { "%ws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%c", sizeof(SHORT), "\xc8", L"\x95c8", 0x95c8 }, + { "%lc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%C", sizeof(SHORT), "\x3f", L"\xc8", 0x95c8 }, + { "%lC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%hc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, + { "%I64u", sizeof(ULONG64), "10", NULL, 10 }, + { "%I64s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, + { "%q%u", sizeof(ULONG), "q10", NULL, 10 }, + }; + WCHAR ws[256], expectedw[256], specw[256]; + unsigned int i, j; + char expected[256], spec[256], s[256]; + int len; + + if (!is_locale_english()) + { + /* The test is not designed for testing locale but some of the test expected results depend on locale. */ + skip("An English locale is required for the printf tests.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + strcpy(spec, tests[i].spec); + winetest_push_context("%s", spec); + strcat(spec,"|%s"); + *s = 0; + *ws = 0; + j = 0; + do + specw[j] = spec[j]; + while (specw[j++]); + switch (tests[i].arg_size) + { + case 0: + wnsprintfA(s, ARRAY_SIZE(s), spec, "end"); + if (tests[i].argw) + len = wnsprintfW(ws, ARRAY_SIZE(ws), specw, L"end"); + else + len = wnsprintfW(ws, ARRAY_SIZE(ws), specw, L"end"); + break; + case 1: + case 2: + case 4: + wnsprintfA(s, ARRAY_SIZE(s), spec, (ULONG)tests[i].arg, "end"); + if (tests[i].argw) + len = wnsprintfW(ws, ARRAY_SIZE(ws), specw, tests[i].argw, L"end"); + else + len = wnsprintfW(ws, ARRAY_SIZE(ws), specw, (ULONG)tests[i].arg, L"end"); + break; + case 8: + wnsprintfA(s, ARRAY_SIZE(s), spec, (ULONG64)tests[i].arg, "end"); + if (tests[i].argw) + len = wnsprintfW(ws, ARRAY_SIZE(ws), specw, tests[i].argw, L"end"); + else + len = wnsprintfW(ws, ARRAY_SIZE(ws), specw, (ULONG64)tests[i].arg, L"end"); + break; + default: + len = 0; + ok(0, "unknown length %u.\n", tests[i].arg_size); + break; + } + strcpy(expected, tests[i].expected); + strcat(expected, "|end"); + ok(len == strlen(expected), "got len %d, expected %Id.\n", len, strlen(expected)); + ok(!strcmp(s, expected), "got %s, expected %s.\n", debugstr_a(s), debugstr_a(expected)); + if (tests[i].expectedw) + { + wcscpy(expectedw, tests[i].expectedw); + wcscat(expectedw, L"|end"); + } + else + { + for (j = 0; j < len; ++j) + expectedw[j] = expected[j]; + } + expectedw[len] = 0; + ok(!wcscmp(ws, expectedw), "got %s, expected %s.\n", debugstr_w(ws), debugstr_w(expectedw)); + winetest_pop_context(); + } +} + START_TEST(string) { HMODULE hShlwapi; @@ -1777,6 +1883,7 @@ START_TEST(string) test_StrStrNW(); test_StrStrNIW(); test_StrCatChainW(); + test_printf_format();
CoUninitialize(); }
From: Paul Gofman pgofman@codeweavers.com
--- dlls/shlwapi/tests/string.c | 11 +++++++++++ dlls/shlwapi/wsprintf.c | 38 +++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index 998931e85a8..c58409ce102 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -1703,9 +1703,13 @@ static void test_printf_format(void) tests[] = { { "%qu", 0, "qu", NULL, 10 }, + { "%ll", 0, "", NULL, 10 }, { "%lu", sizeof(ULONG), "10", NULL, 10 }, { "%#lx", sizeof(ULONG), "0xa", NULL, 10 }, { "%hu", sizeof(ULONG), "10", NULL, 10 }, + { "%hhu", sizeof(ULONG), "10", NULL, 10 }, + { "%hwu", sizeof(ULONG), "10", NULL, 10 }, + { "%whu", sizeof(ULONG), "10", NULL, 10 }, { "%s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, { "%S", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, { "%ls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, @@ -1713,12 +1717,19 @@ static void test_printf_format(void) { "%hs", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, { "%hS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, { "%ws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%hhs", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, + { "%hhS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, + { "%wwws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, { "%c", sizeof(SHORT), "\xc8", L"\x95c8", 0x95c8 }, { "%lc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, { "%C", sizeof(SHORT), "\x3f", L"\xc8", 0x95c8 }, { "%lC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, { "%hc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, + { "%hhc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, + { "%hhhc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, { "%I64u", sizeof(ULONG64), "10", NULL, 10 }, + { "%llI64u", sizeof(ULONG64), "10", NULL, 10 }, + { "%I64llu", sizeof(ULONG64), "10", NULL, 10 }, { "%I64s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, { "%q%u", sizeof(ULONG), "q10", NULL, 10 }, }; diff --git a/dlls/shlwapi/wsprintf.c b/dlls/shlwapi/wsprintf.c index fbd2a7e75bf..ed385081821 100644 --- a/dlls/shlwapi/wsprintf.c +++ b/dlls/shlwapi/wsprintf.c @@ -110,14 +110,19 @@ static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res ) p++; } } - if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; } - else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; } - else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; } - else if (*p == 'I') + while (*p && strchr("lhwI", *p)) { - if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } - else if (p[1] == '3' && p[2] == '2') p += 3; - else { res->flags |= WPRINTF_INTPTR; p++; } + switch (*p) + { + case 'l': res->flags |= WPRINTF_LONG; ++p; break; + case 'I': + if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } + else if (p[1] == '3' && p[2] == '2') p += 3; + else { res->flags |= WPRINTF_INTPTR; p++; } + break; + case 'h': res->flags |= WPRINTF_SHORT; ++p; break; + case 'w': res->flags |= WPRINTF_WIDE; ++p; break; + } } switch(*p) { @@ -192,14 +197,19 @@ static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res ) p++; } } - if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; } - else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; } - else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; } - else if (*p == 'I') + while (*p && strchr("lhwI", *p)) { - if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } - else if (p[1] == '3' && p[2] == '2') p += 3; - else { res->flags |= WPRINTF_INTPTR; p++; } + switch (*p) + { + case 'l': res->flags |= WPRINTF_LONG; ++p; break; + case 'I': + if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } + else if (p[1] == '3' && p[2] == '2') p += 3; + else { res->flags |= WPRINTF_INTPTR; p++; } + break; + case 'h': res->flags |= WPRINTF_SHORT; ++p; break; + case 'w': res->flags |= WPRINTF_WIDE; ++p; break; + } } switch(*p) {
From: Paul Gofman pgofman@codeweavers.com
--- dlls/shlwapi/tests/string.c | 26 ++++++++++++++++++++++++++ dlls/shlwapi/wsprintf.c | 18 +++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index c58409ce102..1800b0a5771 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -1717,16 +1717,42 @@ static void test_printf_format(void) { "%hs", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, { "%hS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, { "%ws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%wS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, { "%hhs", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, { "%hhS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, + { "%wws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%wwS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, { "%wwws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%wwwS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%hws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%hwS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%whs", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%whS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%hwls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%hwlls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%hwlS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%hwllS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%lhws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%llhws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%lhwS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%llhwS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, { "%c", sizeof(SHORT), "\xc8", L"\x95c8", 0x95c8 }, { "%lc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%lllc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%lllllc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, { "%C", sizeof(SHORT), "\x3f", L"\xc8", 0x95c8 }, { "%lC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%lllC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%lllllC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, { "%hc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, { "%hhc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, { "%hhhc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, + { "%wc", sizeof(BYTE), "\x3f", L"\x95c8", 0x95c8 }, + { "%wC", sizeof(BYTE), "\x3f", L"\x95c8", 0x95c8 }, + { "%hwc", sizeof(BYTE), "\x3f", L"\xc8", 0x95c8 }, + { "%whc", sizeof(BYTE), "\x3f", L"\xc8", 0x95c8 }, + { "%hwC", sizeof(BYTE), "\x3f", L"\xc8", 0x95c8 }, + { "%whC", sizeof(BYTE), "\x3f", L"\xc8", 0x95c8 }, { "%I64u", sizeof(ULONG64), "10", NULL, 10 }, { "%llI64u", sizeof(ULONG64), "10", NULL, 10 }, { "%I64llu", sizeof(ULONG64), "10", NULL, 10 }, diff --git a/dlls/shlwapi/wsprintf.c b/dlls/shlwapi/wsprintf.c index ed385081821..eb64b5e3845 100644 --- a/dlls/shlwapi/wsprintf.c +++ b/dlls/shlwapi/wsprintf.c @@ -114,7 +114,7 @@ static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res ) { switch (*p) { - case 'l': res->flags |= WPRINTF_LONG; ++p; break; + case 'l': res->flags |= WPRINTF_LONG | WPRINTF_WIDE; ++p; break; case 'I': if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } else if (p[1] == '3' && p[2] == '2') p += 3; @@ -127,20 +127,20 @@ static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res ) switch(*p) { case 'c': - res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR; + res->type = (res->flags & WPRINTF_WIDE) ? WPR_WCHAR : WPR_CHAR; break; case 'C': - res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR; + res->type = (res->flags & (WPRINTF_SHORT | WPRINTF_WIDE)) == WPRINTF_SHORT ? WPR_CHAR : WPR_WCHAR; break; case 'd': case 'i': res->type = WPR_SIGNED; break; case 's': - res->type = (res->flags & (WPRINTF_LONG |WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING; + res->type = (res->flags & WPRINTF_WIDE) ? WPR_WSTRING : WPR_STRING; break; case 'S': - res->type = (res->flags & (WPRINTF_SHORT|WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING; + res->type = (res->flags & (WPRINTF_SHORT | WPRINTF_WIDE)) == WPRINTF_SHORT ? WPR_STRING : WPR_WSTRING; break; case 'u': res->type = WPR_UNSIGNED; @@ -201,7 +201,7 @@ static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res ) { switch (*p) { - case 'l': res->flags |= WPRINTF_LONG; ++p; break; + case 'l': res->flags |= WPRINTF_LONG | WPRINTF_WIDE; ++p; break; case 'I': if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } else if (p[1] == '3' && p[2] == '2') p += 3; @@ -217,17 +217,17 @@ static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res ) res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR; break; case 'C': - res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR; + res->type = (res->flags & (WPRINTF_SHORT | WPRINTF_WIDE)) == WPRINTF_WIDE ? WPR_WCHAR : WPR_CHAR; break; case 'd': case 'i': res->type = WPR_SIGNED; break; case 's': - res->type = ((res->flags & WPRINTF_SHORT) && !(res->flags & WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING; + res->type = (res->flags & WPRINTF_SHORT) ? WPR_STRING : WPR_WSTRING; break; case 'S': - res->type = (res->flags & (WPRINTF_LONG|WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING; + res->type = (res->flags & (WPRINTF_SHORT | WPRINTF_WIDE)) == WPRINTF_WIDE ? WPR_WSTRING : WPR_STRING; break; case 'u': res->type = WPR_UNSIGNED;
From: Paul Gofman pgofman@codeweavers.com
--- dlls/shlwapi/tests/string.c | 15 +++++++++++++++ dlls/shlwapi/wsprintf.c | 20 ++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index 1800b0a5771..467a952d58b 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -1705,15 +1705,26 @@ static void test_printf_format(void) { "%qu", 0, "qu", NULL, 10 }, { "%ll", 0, "", NULL, 10 }, { "%lu", sizeof(ULONG), "10", NULL, 10 }, + { "%llu", sizeof(ULONG64), "10", NULL, 10 }, + { "%lllllllu", sizeof(ULONG64), "10", NULL, 10 }, { "%#lx", sizeof(ULONG), "0xa", NULL, 10 }, + { "%#llx", sizeof(ULONG64), "0x1000000000", NULL, 0x1000000000 }, + { "%#lllx", sizeof(ULONG64), "0x1000000000", NULL, 0x1000000000 }, { "%hu", sizeof(ULONG), "10", NULL, 10 }, { "%hhu", sizeof(ULONG), "10", NULL, 10 }, { "%hwu", sizeof(ULONG), "10", NULL, 10 }, { "%whu", sizeof(ULONG), "10", NULL, 10 }, + { "%04lhlwllx", sizeof(ULONG64), "1000000010", NULL, 0x1000000010 }, { "%s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, { "%S", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, { "%ls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, { "%lS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%lls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, + { "%llS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, + { "%llls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%lllS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, + { "%lllls", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, + { "%llllS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, { "%hs", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, { "%hS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str" }, { "%ws", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str" }, @@ -1738,11 +1749,15 @@ static void test_printf_format(void) { "%llhwS", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, { "%c", sizeof(SHORT), "\xc8", L"\x95c8", 0x95c8 }, { "%lc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%llc", sizeof(SHORT), "\xc8", L"\x95c8", 0x95c8 }, { "%lllc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%llllc", sizeof(SHORT), "\xc8", L"\x95c8", 0x95c8 }, { "%lllllc", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, { "%C", sizeof(SHORT), "\x3f", L"\xc8", 0x95c8 }, { "%lC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%llC", sizeof(SHORT), "\x3f", L"\xc8", 0x95c8 }, { "%lllC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, + { "%llllC", sizeof(SHORT), "\x3f", L"\xc8", 0x95c8 }, { "%lllllC", sizeof(SHORT), "\x3f", L"\x95c8", 0x95c8 }, { "%hc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, { "%hhc", sizeof(BYTE), "\xc8", L"\xc8", 0x95c8 }, diff --git a/dlls/shlwapi/wsprintf.c b/dlls/shlwapi/wsprintf.c index eb64b5e3845..771c130be70 100644 --- a/dlls/shlwapi/wsprintf.c +++ b/dlls/shlwapi/wsprintf.c @@ -114,7 +114,15 @@ static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res ) { switch (*p) { - case 'l': res->flags |= WPRINTF_LONG | WPRINTF_WIDE; ++p; break; + case 'l': + ++p; + if (*p == 'l') + { + res->flags |= WPRINTF_I64; + ++p; + } + else res->flags |= WPRINTF_LONG | WPRINTF_WIDE; + break; case 'I': if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } else if (p[1] == '3' && p[2] == '2') p += 3; @@ -201,7 +209,15 @@ static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res ) { switch (*p) { - case 'l': res->flags |= WPRINTF_LONG | WPRINTF_WIDE; ++p; break; + case 'l': + ++p; + if (*p == 'l') + { + res->flags |= WPRINTF_I64; + ++p; + } + else res->flags |= WPRINTF_LONG | WPRINTF_WIDE; + break; case 'I': if (p[1] == '6' && p[2] == '4') { res->flags |= WPRINTF_I64; p += 3; } else if (p[1] == '3' && p[2] == '2') p += 3;
From: Paul Gofman pgofman@codeweavers.com
--- dlls/shlwapi/tests/string.c | 5 +++++ dlls/shlwapi/wsprintf.c | 4 ++++ 2 files changed, 9 insertions(+)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index 467a952d58b..db018fa864b 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -1773,6 +1773,11 @@ static void test_printf_format(void) { "%I64llu", sizeof(ULONG64), "10", NULL, 10 }, { "%I64s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, { "%q%u", sizeof(ULONG), "q10", NULL, 10 }, + { "%u% ", sizeof(ULONG), "10", NULL, 10 }, + { "% ll u", 0, " u", NULL, 10 }, + { "% llu", sizeof(ULONG64), "10", NULL, 10 }, + { "%# llx", sizeof(ULONG64), "0xa", NULL, 10 }, + { "% #llx", sizeof(ULONG64), "0xa", NULL, 10 }, }; WCHAR ws[256], expectedw[256], specw[256]; unsigned int i, j; diff --git a/dlls/shlwapi/wsprintf.c b/dlls/shlwapi/wsprintf.c index 771c130be70..b4113d2d563 100644 --- a/dlls/shlwapi/wsprintf.c +++ b/dlls/shlwapi/wsprintf.c @@ -90,11 +90,13 @@ static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res ) { LPCSTR p = format;
+ while (*p == ' ') ++p; res->flags = 0; res->width = 0; res->precision = 0; if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; } if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; } + while (*p == ' ') ++p; if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; } while ((*p >= '0') && (*p <= '9')) /* width field */ { @@ -185,11 +187,13 @@ static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res ) { LPCWSTR p = format;
+ while (*p == ' ') ++p; res->flags = 0; res->width = 0; res->precision = 0; if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; } if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; } + while (*p == ' ') ++p; if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; } while ((*p >= '0') && (*p <= '9')) /* width field */ {
From: Paul Gofman pgofman@codeweavers.com
--- dlls/shlwapi/tests/string.c | 2 ++ dlls/shlwapi/wsprintf.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index db018fa864b..6bb1ac384a1 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -1714,6 +1714,8 @@ static void test_printf_format(void) { "%hhu", sizeof(ULONG), "10", NULL, 10 }, { "%hwu", sizeof(ULONG), "10", NULL, 10 }, { "%whu", sizeof(ULONG), "10", NULL, 10 }, + { "%##lhllwlx", sizeof(ULONG64), "0x1000000010", NULL, 0x1000000010 }, + { "%##lhlwlx", sizeof(ULONG), "0x10", NULL, 0x1000000010 }, { "%04lhlwllx", sizeof(ULONG64), "1000000010", NULL, 0x1000000010 }, { "%s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, { "%S", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)L"str", "str" }, diff --git a/dlls/shlwapi/wsprintf.c b/dlls/shlwapi/wsprintf.c index b4113d2d563..abf217e9474 100644 --- a/dlls/shlwapi/wsprintf.c +++ b/dlls/shlwapi/wsprintf.c @@ -95,7 +95,7 @@ static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res ) res->width = 0; res->precision = 0; if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; } - if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; } + while (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; } while (*p == ' ') ++p; if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; } while ((*p >= '0') && (*p <= '9')) /* width field */ @@ -192,7 +192,7 @@ static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res ) res->width = 0; res->precision = 0; if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; } - if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; } + while (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; } while (*p == ' ') ++p; if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; } while ((*p >= '0') && (*p <= '9')) /* width field */
From: Paul Gofman pgofman@codeweavers.com
--- dlls/shlwapi/tests/string.c | 2 ++ dlls/shlwapi/wsprintf.c | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index 6bb1ac384a1..d0b445f4d87 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -1775,7 +1775,9 @@ static void test_printf_format(void) { "%I64llu", sizeof(ULONG64), "10", NULL, 10 }, { "%I64s", sizeof(ULONG_PTR), "str", NULL, (ULONG_PTR)"str", L"str" }, { "%q%u", sizeof(ULONG), "q10", NULL, 10 }, + { "%lhw%u", 0, "%u", NULL, 10 }, { "%u% ", sizeof(ULONG), "10", NULL, 10 }, + { "%u% %u", sizeof(ULONG), "10%u", NULL, 10 }, { "% ll u", 0, " u", NULL, 10 }, { "% llu", sizeof(ULONG64), "10", NULL, 10 }, { "%# llx", sizeof(ULONG64), "0xa", NULL, 10 }, diff --git a/dlls/shlwapi/wsprintf.c b/dlls/shlwapi/wsprintf.c index abf217e9474..daff024d9c3 100644 --- a/dlls/shlwapi/wsprintf.c +++ b/dlls/shlwapi/wsprintf.c @@ -483,6 +483,7 @@ INT WINAPI wvnsprintfA( LPSTR buffer, INT maxlen, LPCSTR spec, va_list args ) p += len - sign; break; case WPR_UNKNOWN: + if (*spec) *p++ = *spec++; continue; } if (format.flags & WPRINTF_LEFTALIGN) @@ -603,6 +604,7 @@ INT WINAPI wvnsprintfW( LPWSTR buffer, INT maxlen, LPCWSTR spec, va_list args ) for (i = sign; i < len; i++) *p++ = (BYTE)number[i]; break; case WPR_UNKNOWN: + if (*spec) *p++ = *spec++; continue; } if (format.flags & WPRINTF_LEFTALIGN)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=148938
Your paranoid android.
=== w10pro64_en_AE_u8 (32 bit report) ===
shlwapi: string.c:1842: Test failed: %lc: got "\xe9\x97\x88|end", expected "?|end". string.c:1842: Test failed: %lllc: got "\xe9\x97\x88|end", expected "?|end". string.c:1842: Test failed: %lllllc: got "\xe9\x97\x88|end", expected "?|end". string.c:1842: Test failed: %C: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %C: got L"\fffd|end", expected L"\00c8|end". string.c:1842: Test failed: %lC: got "\xe9\x97\x88|end", expected "?|end". string.c:1842: Test failed: %llC: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %llC: got L"\fffd|end", expected L"\00c8|end". string.c:1842: Test failed: %lllC: got "\xe9\x97\x88|end", expected "?|end". string.c:1842: Test failed: %llllC: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %llllC: got L"\fffd|end", expected L"\00c8|end". string.c:1842: Test failed: %lllllC: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %hc: got L"\fffd|end", expected L"\00c8|end". string.c:1854: Test failed: %hhc: got L"\fffd|end", expected L"\00c8|end". string.c:1854: Test failed: %hhhc: got L"\fffd|end", expected L"\00c8|end". string.c:1842: Test failed: %wc: got "\xe9\x97\x88|end", expected "?|end". string.c:1842: Test failed: %wC: got "\xe9\x97\x88|end", expected "?|end". string.c:1842: Test failed: %hwc: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %hwc: got L"\fffd|end", expected L"\00c8|end". string.c:1842: Test failed: %whc: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %whc: got L"\fffd|end", expected L"\00c8|end". string.c:1842: Test failed: %hwC: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %hwC: got L"\fffd|end", expected L"\00c8|end". string.c:1842: Test failed: %whC: got "\xe9\x97\x88|end", expected "?|end". string.c:1854: Test failed: %whC: got L"\fffd|end", expected L"\00c8|end".
Fixes XDefiant crashing on start.
In fact, it only needs 'll' handling (for %016llx part of format string), but one thing pulls another: e. g., trying to make some tests to understand how this 'll' is supposed to work with 'c' or 'S' reveals that there are more differences etc.