From 1680e984277097b5cbd1c5abf79e2d6411bb6cd2 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 15 Nov 2016 13:36:44 -0600 Subject: [PATCH] msvcrt: Improve multibyte characters support in printf. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcrt/printf.h | 12 +++++++----- dlls/msvcrt/tests/printf.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/dlls/msvcrt/printf.h b/dlls/msvcrt/printf.h index 6c9eeeb708d..392ead8312b 100644 --- a/dlls/msvcrt/printf.h +++ b/dlls/msvcrt/printf.h @@ -122,13 +122,18 @@ static inline int FUNC_NAME(pf_output_wstr)(FUNC_NAME(puts_clbk) pf_puts, void * return pf_puts(puts_ctx, len, str); #else LPSTR out; - int len_a = WideCharToMultiByte(locinfo->lc_codepage, 0, str, len, NULL, 0, NULL, NULL); + BOOL def_char; + int len_a = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS, + str, len, NULL, 0, NULL, &def_char); + if(def_char) + return 0; out = HeapAlloc(GetProcessHeap(), 0, len_a); if(!out) return -1; - WideCharToMultiByte(locinfo->lc_codepage, 0, str, len, out, len_a, NULL, NULL); + WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS, + str, len, out, len_a, NULL, NULL); len = pf_puts(puts_ctx, len_a, out); HeapFree(GetProcessHeap(), 0, out); return len; @@ -495,9 +500,6 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API } else if(flags.Format == 'c' || flags.Format == 'C') { int ch = pf_args(args_ctx, pos, VT_INT, valist).get_int; - if((ch&0xff) != ch) - FIXME("multibyte characters printing not supported\n"); - i = FUNC_NAME(pf_handle_string)(pf_puts, puts_ctx, &ch, 1, &flags, locinfo, legacy_wide); } else if(flags.Format == 'p') { flags.Format = 'X'; diff --git a/dlls/msvcrt/tests/printf.c b/dlls/msvcrt/tests/printf.c index 295c6dd3020..f9b3fc9ff0b 100644 --- a/dlls/msvcrt/tests/printf.c +++ b/dlls/msvcrt/tests/printf.c @@ -27,6 +27,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -768,6 +769,39 @@ static void test_sprintf( void ) r = sprintf(buffer, format, INFINITY); ok(r==10, "r = %d\n", r); ok(!strcmp(buffer, "0000001.#J"), "failed: \"%s\"\n", buffer); + + format = "%c"; + r = sprintf(buffer, format, 'a'); + ok(r==1, "r = %d\n", r); + ok(!strcmp(buffer, "a"), "failed: \"%s\"\n", buffer); + r = sprintf(buffer, format, 0xa082); + ok(r==1, "r = %d\n", r); + ok(!strcmp(buffer, "\x82"), "failed: \"%s\"\n", buffer); + + format = "%C"; + r = sprintf(buffer, format, 'a'); + ok(r==1, "r = %d\n", r); + ok(!strcmp(buffer, "a"), "failed: \"%s\"\n", buffer); + r = sprintf(buffer, format, 0x3042); + ok(r==0, "r = %d\n", r); + ok(!strcmp(buffer, ""), "failed: \"%s\"\n", buffer); + + if(!setlocale(LC_ALL, "Japanese_Japan.932")) { + win_skip("Japanese_Japan.932 locale not available\n"); + return; + } + + format = "%c"; + r = sprintf(buffer, format, 0xa082); + ok(r==1, "r = %d\n", r); + ok(!strcmp(buffer, "\x82"), "failed: \"%s\"\n", buffer); + + format = "%C"; + r = sprintf(buffer, format, 0x3042); + ok(r==2, "r = %d\n", r); + ok(!strcmp(buffer, "\x82\xa0"), "failed: \"%s\"\n", buffer); + + setlocale(LC_ALL, "C"); } static void test_swprintf( void ) @@ -911,7 +945,7 @@ static void test_fcvt(void) { char *str; int dec=100, sign=100; - + /* Numbers less than 1.0 with different precisions */ str = _fcvt(0.0001, 1, &dec, &sign ); ok( 0 == strcmp(str,""), "bad return '%s'\n", str); -- 2.11.4.GIT