Bug 524314 - g_convert() on Win32 implicitly converts full width
authorTor Lillqvist <tml@novell.com>
Wed, 2 Apr 2008 02:43:45 +0000 (02:43 +0000)
committerTor Lillqvist <tml@src.gnome.org>
Wed, 2 Apr 2008 02:43:45 +0000 (02:43 +0000)
2008-04-02  Tor Lillqvist  <tml@novell.com>

Bug 524314 - g_convert() on Win32 implicitly converts full width
alphanumerics into half width

* glib/win_iconv.c: Update from Yukihiro Nakadaira. Use
WC_NO_BEST_FIT_CHARS flag for WideCharToMultiByte() unless the
//translit flag was suffixed to the codeset name.

* glib/gconvert.c: Include win_iconv.c earlier so that its
definition of WINVER before it includes <windows.h> is used.

svn path=/trunk/; revision=6808

ChangeLog
glib/gconvert.c
glib/win_iconv.c

index 3c9f91e..d9d230b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-04-02  Tor Lillqvist  <tml@novell.com>
+
+       Bug 524314 - g_convert() on Win32 implicitly converts full width
+       alphanumerics into half width
+       
+       * glib/win_iconv.c: Update from Yukihiro Nakadaira. Use
+       WC_NO_BEST_FIT_CHARS flag for WideCharToMultiByte() unless the
+       //translit flag was suffixed to the codeset name.
+
+       * glib/gconvert.c: Include win_iconv.c earlier so that its
+       definition of WINVER before it includes <windows.h> is used.
+
 2008-03-31  Tor Lillqvist  <tml@novell.com>
 
        * glib/gmain.c (g_poll): Improve fix for #525192 below: Use
index e6fd8bd..8ba4801 100644 (file)
 #include "gthreadprivate.h"
 #include "gunicode.h"
 
+#ifdef G_OS_WIN32
+#include "win_iconv.c"
+#endif
+
 #ifdef G_PLATFORM_WIN32
 #define STRICT
 #include <windows.h>
 
 #include "galias.h"
 
-#ifdef G_OS_WIN32
-#include "win_iconv.c"
-#endif
-
 GQuark 
 g_convert_error_quark (void)
 {
index 7ed272b..2770878 100644 (file)
  * be used for encoding validation purpose.\r
  */\r
 \r
+/* for WC_NO_BEST_FIT_CHARS */\r
+#ifndef WINVER\r
+# define WINVER 0x0500\r
+#endif\r
+\r
+#define STRICT\r
 #include <windows.h>\r
 #include <errno.h>\r
 #include <string.h>\r
 \r
 #define MB_CHAR_MAX 16\r
 \r
-#define UNICODE_MODE_BOM_DONE 1\r
-#define UNICODE_MODE_SWAPPED 2\r
+#define UNICODE_MODE_BOM_DONE   1\r
+#define UNICODE_MODE_SWAPPED    2\r
 \r
-#define UNICODE_FLAG_USE_BOM_ENDIAN 1\r
+#define FLAG_USE_BOM_ENDIAN     1\r
+#define FLAG_TRANSLIT           2 /* //TRANSLIT */\r
+#define FLAG_IGNORE             4 /* //IGNORE (not implemented) */\r
 \r
 #define return_error(code)  \\r
     do {                    \\r
@@ -873,6 +881,7 @@ make_csconv(const char *_name)
     CPINFOEX cpinfoex;\r
     csconv_t cv;\r
     int use_compat = TRUE;\r
+    int flag = 0;\r
     char name[128];\r
     char *p;\r
 \r
@@ -883,11 +892,15 @@ make_csconv(const char *_name)
     {\r
         if (_stricmp(p + 2, "nocompat") == 0)\r
             use_compat = FALSE;\r
+        else if (_stricmp(p + 2, "translit") == 0)\r
+            flag |= FLAG_TRANSLIT;\r
+        else if (_stricmp(p + 2, "ignore") == 0)\r
+            flag |= FLAG_IGNORE;\r
         *p = 0;\r
     }\r
 \r
     cv.mode = 0;\r
-    cv.flags = 0;\r
+    cv.flags = flag;\r
     cv.mblen = NULL;\r
     cv.flush = NULL;\r
     cv.compat = NULL;\r
@@ -899,14 +912,14 @@ make_csconv(const char *_name)
         if (_stricmp(name, "UTF-16") == 0 ||\r
            _stricmp(name, "UTF16") == 0 ||\r
            _stricmp(name, "UCS-2") == 0)\r
-            cv.flags |= UNICODE_FLAG_USE_BOM_ENDIAN;\r
+            cv.flags |= FLAG_USE_BOM_ENDIAN;\r
     }\r
     else if (cv.codepage == 12000 || cv.codepage == 12001)\r
     {\r
         cv.mbtowc = utf32_mbtowc;\r
         cv.wctomb = utf32_wctomb;\r
         if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0)\r
-            cv.flags |= UNICODE_FLAG_USE_BOM_ENDIAN;\r
+            cv.flags |= FLAG_USE_BOM_ENDIAN;\r
     }\r
     else if (cv.codepage == 65001)\r
     {\r
@@ -1061,7 +1074,7 @@ static void
 check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize)\r
 {\r
     /* If we have a BOM, trust it, despite what the caller said */\r
-    if (wbuf[0] == 0xFFFE && (cd->from.flags & UNICODE_FLAG_USE_BOM_ENDIAN))\r
+    if (wbuf[0] == 0xFFFE && (cd->from.flags & FLAG_USE_BOM_ENDIAN))\r
     {\r
         /* swap endian: 1200 <-> 1201 or 12000 <-> 12001 */\r
         cd->from.codepage ^= 1;\r
@@ -1345,13 +1358,22 @@ static int
 kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)\r
 {\r
     BOOL usedDefaultChar = 0;\r
+    BOOL *p = NULL;\r
+    int flags = 0;\r
     int len;\r
 \r
     if (bufsize == 0)\r
         return_error(E2BIG);\r
-    len = WideCharToMultiByte(cv->codepage, 0,\r
-            (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL,\r
-            must_use_null_useddefaultchar(cv->codepage) ? NULL : &usedDefaultChar);\r
+    if (!must_use_null_useddefaultchar(cv->codepage))\r
+    {\r
+        p = &usedDefaultChar;\r
+#ifdef WC_NO_BEST_FIT_CHARS\r
+        if (!(cv->flags & FLAG_TRANSLIT))\r
+            flags |= WC_NO_BEST_FIT_CHARS;\r
+#endif\r
+    }\r
+    len = WideCharToMultiByte(cv->codepage, flags,\r
+            (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p);\r
     if (len == 0)\r
     {\r
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\r