Despite what msdn states, I and I32 are supported width modifiers.
V2: - better code structure - added support and tests for I32
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/msvcrt/scanf.h | 10 ++++++++-- dlls/msvcrt/tests/scanf.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h index 3ab2efef13d..02284379854 100644 --- a/dlls/msvcrt/scanf.h +++ b/dlls/msvcrt/scanf.h @@ -279,13 +279,19 @@ _FUNCTION_ { *(format + 2) == '4') { I64_prefix = 1; format += 2; + break; } - break; + else if (*(format + 1) == '3' && + *(format + 2) == '2') { + format += 2; + break; + } + /* fall through */ #if _MSVCR_VER == 0 || _MSVCR_VER >= 140 case 'z': +#endif if (sizeof(void *) == sizeof(LONGLONG)) I64_prefix = 1; break; -#endif default: prefix_finished = 1; } diff --git a/dlls/msvcrt/tests/scanf.c b/dlls/msvcrt/tests/scanf.c index e175342796b..6541f5fd5cb 100644 --- a/dlls/msvcrt/tests/scanf.c +++ b/dlls/msvcrt/tests/scanf.c @@ -74,6 +74,7 @@ static void test_sscanf( void ) int hour=21,min=59,sec=20; int number,number_so_far; HMODULE hmod = GetModuleHandleA("msvcrt.dll"); + DWORD_PTR result_ptr;
p_sprintf = (void *)GetProcAddress( hmod, "sprintf" ); p_sscanf = (void *)GetProcAddress( hmod, "sscanf" ); @@ -264,6 +265,51 @@ static void test_sscanf( void ) if(ret == 14) ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer);
+ strcpy(buffer,"12345678901234"); + ret = p_sscanf(buffer, "%I64d", &result64); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ret = p_sprintf(buffer1, "%I64d", result64); + ok(ret==14 || broken(ret==10), "sprintf returned %d\n", ret); + if(ret == 14) + ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer); + + result = 0; + strcpy(buffer,"0x123456789"); + ret = p_sscanf(buffer, "%I32x", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0x23456789, "got %x, expected 0x23456789\n", result); + + result_ptr = 0; + strcpy(buffer,"0x87654321"); + ret = p_sscanf(buffer, "%Ix", &result_ptr); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + if (sizeof(void*) == sizeof(LONGLONG)) + { + ret = p_sprintf(buffer1, "%#Ix", result_ptr); + ok(ret==9, "sprintf returned %d\n", ret); + if(ret == 9) + ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer); + } + else + { + ok(result_ptr == 0x87654321, "got %x, expected 0x23456789\n", result); + } + result_ptr = 0; + strcpy(buffer,"0x123456789"); + ret = p_sscanf(buffer, "%Ix", &result_ptr); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + if (sizeof(void*) == sizeof(LONGLONG)) + { + ret = p_sprintf(buffer1, "%#Ix", result_ptr); + ok(ret==11, "sprintf returned %d\n", ret); + if(ret == 11) + ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer); + } + else + { + ok(result_ptr == 0x23456789, "got %x, expected 0x23456789\n", result); + } + /* Check %i according to bug 1878 */ strcpy(buffer,"123"); ret = p_sscanf(buffer, "%i", &result);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100455
Your paranoid android.
=== w864 (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w1064v1507 (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w1064v1809 (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w1064 (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w1064_2qxl (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w1064_tsign (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w10pro64 (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w10pro64_ar (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w10pro64_he (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w10pro64_ja (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== w10pro64_zh_CN (64 bit report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
=== debiant2 (64 bit WoW report) ===
msvcrt: scanf.c:289: Test failed: sprintf returned 10
Hi Eric,
On 10/19/21 5:51 PM, Eric Pouech wrote:
- strcpy(buffer,"12345678901234");
- ret = p_sscanf(buffer, "%I64d", &result64);
- ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
- ret = p_sprintf(buffer1, "%I64d", result64);
- ok(ret==14 || broken(ret==10), "sprintf returned %d\n", ret);
- if(ret == 14)
ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer);
Why are you testing printf output instead of checking result64 value? How about moving the tests to ucrtbase so you don't have to handle "broken" case (otherwise it's probably better to skip the test on old msvcrt)?
Thanks, Piotr
Hi Piotr
Le mardi 19 octobre 2021, Piotr Caban piotr.caban@gmail.com a écrit :
Hi Eric,
Why are you testing printf output instead of checking result64 value?
I was just following the style used in the previous scanf tests...
How about moving the tests to ucrtbase so you don't have to handle "broken"
case (otherwise it's probably better to skip the test on old msvcrt)?
Would moving to ucrtbase only test for latest versions (>= 140) ?
It seems to me that all of I I32 I64 should be supported at the same time and they could be present since 90 (at least)
Thx
Thanks,
Piotr
On 10/19/21 8:26 PM, Eric Pouech wrote:
How about moving the tests to ucrtbase so you don't have to handle "broken" case (otherwise it's probably better to skip the test on old msvcrt)?
Would moving to ucrtbase only test for latest versions (>= 140) ? > It seems to me that all of I I32 I64 should be supported at the same time and they could be present since 90 (at least)
Yes, moving to ucrtbase will test only _MSVCR_VER==140 case. But msvcrt tests are only testing msvcrt.dll (_MSVCR_VER==0 case).
I was thinking about moving the tests only (not guarding the implementation with _MSVCR_VER check). I think the tests are cleaner if you don't have to worry about broken case.
Thanks, Piotr
Le 20/10/2021 à 11:57, Piotr Caban a écrit :
On 10/19/21 8:26 PM, Eric Pouech wrote:
How about moving the tests to ucrtbase so you don't have to handle "broken" case (otherwise it's probably better to skip the test on old msvcrt)?
Would moving to ucrtbase only test for latest versions (>= 140) ? > It seems to me that all of I I32 I64 should be supported at the same time and they could be present since 90 (at least)
Yes, moving to ucrtbase will test only _MSVCR_VER==140 case. But msvcrt tests are only testing msvcrt.dll (_MSVCR_VER==0 case).
I was thinking about moving the tests only (not guarding the implementation with _MSVCR_VER check). I think the tests are cleaner if you don't have to worry about broken case.
ok, I'll resend with putting the tests in ucrtbase
A+