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