kernel32: MultiByteToWideChar: MB_USEGLYPHCHARS & incorrect GetLastError() codes fix

Andrew O. Shadoura bugzilla at tut.by
Wed May 9 22:19:20 CDT 2007


Hello All!

This patch implements MB_USEGLYPHCHARS flag in MultiByteToWideChar function
and fixes incorrect error codes (in case of CP_SYMBOL charset non-zero dwFlags
should give ERROR_INVALID_FLAGS, not ERROR_INVALID_PARAMETER, almost the same
with CP_UTF8, but "dwFlags must be set to either 0 or MB_ERR_INVALID_CHARS"
according to MSDN: http://msdn2.microsoft.com/en-us/library/ms776413.aspx
Test cases present.
Fixed some glyphs, added 0x7f glyph, removed tabs from sources.
==================== here clipboard begins ====================
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 6e96eea..8ace411 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -1764,7 +1764,6 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
 {
     const union cptable *table;
     int ret;
-    static int once;
 
     if (!src || (!dst && dstlen))
     {
@@ -1774,18 +1773,12 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
 
     if (srclen < 0) srclen = strlen(src) + 1;
 
-    if (!once && (flags & MB_USEGLYPHCHARS))
-    {
-        once = 1;
-        FIXME("MB_USEGLYPHCHARS not supported\n");
-    }
-
     switch(page)
     {
     case CP_SYMBOL:
-        if( flags)
+        if(flags)
         {
-            SetLastError( ERROR_INVALID_PARAMETER );
+            SetLastError( ERROR_INVALID_FLAGS );
             return 0;
         }
         ret = wine_cpsymbol_mbstowcs( src, srclen, dst, dstlen );
@@ -1802,6 +1795,11 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
         }
         /* fall through */
     case CP_UTF8:
+	if (flags & (~MB_ERR_INVALID_CHARS))
+        {
+            SetLastError( ERROR_INVALID_FLAGS );
+            return 0;
+        }
         ret = wine_utf8_mbstowcs( flags, src, srclen, dst, dstlen );
         break;
     default:
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 08f4982..748471f 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -2255,6 +2255,42 @@ static void test_GetCPInfo(void)
     ok(cpinfo.MaxCharSize == 4, "expected 5, got 0x%x\n", cpinfo.MaxCharSize);
 }
 
+static void test_MultiByteToWideChar(void)
+{
+    int i, ret;
+    static char src[32];
+    static WCHAR dst[32];
+    static const WCHAR glyphed_dst[32] = {
+        0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
+        0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
+        0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
+        0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC
+    };
+    for (i=0;i<32;i++) src[i]=i;
+    memset(&dst, 0, sizeof(dst));
+    SetLastError(0xdeadbeef);
+    ret = MultiByteToWideChar(CP_UTF8,MB_USEGLYPHCHARS,src,32,dst,32);
+    ok(!ret, "MultiByteToWideChar should return ERROR_INVALID_FLAGS(%d) when used CP_UTF8 and MB_USEGLYPHCHARS but returned %d\n", ERROR_INVALID_FLAGS, GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = MultiByteToWideChar(CP_SYMBOL,MB_USEGLYPHCHARS,src,32,dst,32);
+    ok(!ret, "MultiByteToWideChar should return ERROR_INVALID_FLAGS(%d) when used CP_SYMBOL and non-null dwFlags but returned %d\n", ERROR_INVALID_FLAGS, GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = MultiByteToWideChar(CP_OEMCP,MB_USEGLYPHCHARS,src,32,dst,32);
+    ok(ret, "MultiByteToWideChar returned %d\n", GetLastError());
+    ret=memcmp(dst, glyphed_dst, 32*sizeof(WCHAR));
+    ok(!ret, "MultiByteToWideChar didn't return string of glyphs (0x00..0x1F): %d\n",ret);
+    if (ret) {
+        trace("originaldst: %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x\n",
+           dst[0],dst[1],dst[2],dst[3],dst[4],dst[5],dst[6],dst[7],dst[8],dst[9],dst[10],dst[11],dst[12],dst[13],dst[14],dst[15],dst[16],
+           dst[17],dst[18],dst[19],dst[20],dst[21],dst[22],dst[23],dst[24],dst[25],dst[26],dst[27],dst[28],dst[29],dst[30],dst[31]);
+        trace("glyphed_dst: %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x\n",
+           glyphed_dst[0],glyphed_dst[1],glyphed_dst[2],glyphed_dst[3],glyphed_dst[4],glyphed_dst[5],glyphed_dst[6],glyphed_dst[7],glyphed_dst[8],glyphed_dst[9],glyphed_dst[10],glyphed_dst[11],glyphed_dst[12],glyphed_dst[13],glyphed_dst[14],glyphed_dst[15],glyphed_dst[16],
+           glyphed_dst[17],glyphed_dst[18],glyphed_dst[19],glyphed_dst[20],glyphed_dst[21],glyphed_dst[22],glyphed_dst[23],glyphed_dst[24],glyphed_dst[25],glyphed_dst[26],glyphed_dst[27],glyphed_dst[28],glyphed_dst[29],glyphed_dst[30],glyphed_dst[31]);
+    }
+}
+
 START_TEST(locale)
 {
   InitFunctionPointers();
@@ -2278,6 +2314,7 @@ START_TEST(locale)
   test_SetLocaleInfoA();
   test_EnumUILanguageA();
   test_GetCPInfo();
+  test_MultiByteToWideChar();
   /* this requires collation table patch to make it MS compatible */
   if (0) test_sorting();
 }
diff --git a/libs/wine/mbtowc.c b/libs/wine/mbtowc.c
index c0e5791..74dabed 100644
--- a/libs/wine/mbtowc.c
+++ b/libs/wine/mbtowc.c
@@ -22,6 +22,25 @@
 
 #include "wine/unicode.h"
 
+/* 0x00..0x1f chars glyph map */
+static const WCHAR glyph_xlat[32] = {
+    0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
+    0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
+    0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
+    0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC
+};
+
+/* adds glyphs to the string */
+void add_glyphs( WCHAR *str, unsigned int length )
+{
+    unsigned int i;
+    for (i=0; i<length; i++) {
+        if (str[i]<0x20) str[i]=glyph_xlat[str[i]];
+        if (str[i]==0x7f) str[i]=0x2302;
+    }
+}
+
+
 /* get the decomposition of a Unicode char */
 static int get_decomposition( WCHAR src, WCHAR *dst, unsigned int dstlen )
 {
@@ -253,6 +272,7 @@ int wine_cp_mbstowcs( const union cptable *table, int flags,
                       WCHAR *dst, int dstlen )
 {
     const unsigned char *src = (const unsigned char*) s;
+    int res;
 
     if (table->info.char_size == 1)
     {
@@ -263,9 +283,12 @@ int wine_cp_mbstowcs( const union cptable *table, int flags,
         if (!(flags & MB_COMPOSITE))
         {
             if (!dstlen) return srclen;
-            return mbstowcs_sbcs( &table->sbcs, src, srclen, dst, dstlen );
+	    res = mbstowcs_sbcs( &table->sbcs, src, srclen, dst, dstlen );
         }
-        return mbstowcs_sbcs_decompose( &table->sbcs, src, srclen, dst, dstlen );
+	else
+    	    res = mbstowcs_sbcs_decompose( &table->sbcs, src, srclen, dst, dstlen );
+	if (flags & MB_USEGLYPHCHARS) add_glyphs( dst, dstlen );
+	return res;
     }
     else /* mbcs */
     {
@@ -274,9 +297,11 @@ int wine_cp_mbstowcs( const union cptable *table, int flags,
             if (check_invalid_chars_dbcs( &table->dbcs, src, srclen )) return -2;
         }
         if (!(flags & MB_COMPOSITE))
-            return mbstowcs_dbcs( &table->dbcs, src, srclen, dst, dstlen );
+            res = mbstowcs_dbcs( &table->dbcs, src, srclen, dst, dstlen );
         else
-            return mbstowcs_dbcs_decompose( &table->dbcs, src, srclen, dst, dstlen );
+            res = mbstowcs_dbcs_decompose( &table->dbcs, src, srclen, dst, dstlen );
+	if (flags & MB_USEGLYPHCHARS) add_glyphs( dst, dstlen );
+	return res;
     }
 }
 

===================== here clipboard ends =====================

 -- WBR, Andrew O. Shadoura

--- PolySoft Station
 * Origin: Knowledge itself is a power (2:4500/1.25)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: locales-etc.patch
Type: text/x-diff
Size: 6987 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20070510/292cc734/locales-etc-0001.bin


More information about the wine-patches mailing list