Module: wine Branch: master Commit: 3b6b28bce5f2f05ba21d6ca5399517c22300aeeb URL: https://source.winehq.org/git/wine.git/?a=commit;h=3b6b28bce5f2f05ba21d6ca53...
Author: Ambrož Bizjak abizjak.pro@gmail.com Date: Fri Nov 1 19:40:04 2019 +0100
ucrtbase: Implement t and j printf length modifiers.
Signed-off-by: Ambroz Bizjak abizjak.pro@gmail.com Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/printf.h | 6 +++++- dlls/ucrtbase/tests/printf.c | 42 +++++++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h index 346fb5ac5d..975977087d 100644 --- a/dlls/msvcrt/printf.h +++ b/dlls/msvcrt/printf.h @@ -516,10 +516,14 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API } else if(*p == 'w') flags.WideString = *p++; #if _MSVCR_VER >= 140 - else if(*p == 'z') + else if(*p == 'z' || *p == 't') flags.IntegerNative = *p++; else if(*p == 'T') flags.NaturalString = *p++; + else if(*p == 'j') { + flags.IntegerDouble++; + p++; + } #endif else if((*p == 'F' || *p == 'N') && legacy_msvcrt_compat) p++; /* ignore */ diff --git a/dlls/ucrtbase/tests/printf.c b/dlls/ucrtbase/tests/printf.c index 769121ebd9..2af29322bf 100644 --- a/dlls/ucrtbase/tests/printf.c +++ b/dlls/ucrtbase/tests/printf.c @@ -24,6 +24,7 @@ #include <stdio.h> #include <errno.h> #include <math.h> +#include <inttypes.h>
#include "windef.h" #include "winbase.h" @@ -637,24 +638,35 @@ static void test_printf_legacy_three_digit_exp(void)
static void test_printf_c99(void) { - char buf[20]; + char buf[30];
/* The msvcrt compatibility flag doesn't affect whether 'z' is interpreted * as size_t size for integers. */ - if (sizeof(void*) == 8) { - vsprintf_wrapper(0, buf, sizeof(buf), "%zx %d", - (size_t) 0x12345678123456, 1); - ok(!strcmp(buf, "12345678123456 1"), "buf = %s\n", buf); - vsprintf_wrapper(UCRTBASE_PRINTF_LEGACY_MSVCRT_COMPATIBILITY, - buf, sizeof(buf), "%zx %d", (size_t) 0x12345678123456, 1); - ok(!strcmp(buf, "12345678123456 1"), "buf = %s\n", buf); - } else { - vsprintf_wrapper(0, buf, sizeof(buf), "%zx %d", - (size_t) 0x123456, 1); - ok(!strcmp(buf, "123456 1"), "buf = %s\n", buf); - vsprintf_wrapper(UCRTBASE_PRINTF_LEGACY_MSVCRT_COMPATIBILITY, - buf, sizeof(buf), "%zx %d", (size_t) 0x123456, 1); - ok(!strcmp(buf, "123456 1"), "buf = %s\n", buf); + for (int i = 0; i < 2; i++) { + unsigned __int64 options = (i == 0) ? 0 : + UCRTBASE_PRINTF_LEGACY_MSVCRT_COMPATIBILITY; + + /* z modifier accepts size_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%zx %d", SIZE_MAX, 1); + if (sizeof(size_t) == 8) + ok(!strcmp(buf, "ffffffffffffffff 1"), "buf = %s\n", buf); + else + ok(!strcmp(buf, "ffffffff 1"), "buf = %s\n", buf); + + /* j modifier with signed format accepts intmax_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%jd %d", INTMAX_MIN, 1); + ok(!strcmp(buf, "-9223372036854775808 1"), "buf = %s\n", buf); + + /* j modifier with unsigned format accepts uintmax_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%ju %d", UINTMAX_MAX, 1); + ok(!strcmp(buf, "18446744073709551615 1"), "buf = %s\n", buf); + + /* t modifier accepts ptrdiff_t argument */ + vsprintf_wrapper(options, buf, sizeof(buf), "%td %d", PTRDIFF_MIN, 1); + if (sizeof(ptrdiff_t) == 8) + ok(!strcmp(buf, "-9223372036854775808 1"), "buf = %s\n", buf); + else + ok(!strcmp(buf, "-2147483648 1"), "buf = %s\n", buf); } }