Piotr Caban : msvcrt: Improve multibyte characters support in printf.

Alexandre Julliard julliard at winehq.org
Tue Nov 15 17:56:16 CST 2016


Module: wine
Branch: master
Commit: 1680e984277097b5cbd1c5abf79e2d6411bb6cd2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1680e984277097b5cbd1c5abf79e2d6411bb6cd2

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue Nov 15 13:36:44 2016 -0600

msvcrt: Improve multibyte characters support in printf.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 6c9eeeb..392ead8 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 295c6dd..f9b3fc9 100644
--- a/dlls/msvcrt/tests/printf.c
+++ b/dlls/msvcrt/tests/printf.c
@@ -27,6 +27,7 @@
  
 #include <stdio.h>
 #include <errno.h>
+#include <locale.h>
 
 #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);




More information about the wine-cvs mailing list