]> sourceware.org Git - newlib-cygwin.git/commitdiff
* wincap.h (wincaps::has_always_all_codepages): New element.
authorCorinna Vinschen <corinna@vinschen.de>
Mon, 20 Jul 2009 15:44:55 +0000 (15:44 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Mon, 20 Jul 2009 15:44:55 +0000 (15:44 +0000)
* wincap.cc: Implement above element throughout.
* wchar.h (__sjis_mbtowc): Declare.
(__eucjp_mbtowc): Ditto.
(__gbk_mbtowc): Ditto.
(__kr_mbtowc): Ditto.
(__big5_mbtowc): Ditto.
* syscalls.cc (internal_setlocale): Convert to char * function.
Return parameter by default.  Return NULL if request to use a
charset can't be satisfied due to missing codepage support in the
underlying OS.  Fix comment.
(setlocale): Store original locale.  Restore to original locale if
internal_setlocale returns NULL.

winsup/cygwin/ChangeLog
winsup/cygwin/syscalls.cc
winsup/cygwin/wchar.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index 9e78d09dd2f20a4601cfb2e7ffd3d19403e00d83..ebe1f72755fa34fcd38b315737c29f2a2b046a1a 100644 (file)
@@ -1,3 +1,19 @@
+2009-07-20  Corinna Vinschen  <corinna@vinschen.de>
+
+       * wincap.h (wincaps::has_always_all_codepages): New element.
+       * wincap.cc: Implement above element throughout.
+       * wchar.h (__sjis_mbtowc): Declare.
+       (__eucjp_mbtowc): Ditto.
+       (__gbk_mbtowc): Ditto.
+       (__kr_mbtowc): Ditto.
+       (__big5_mbtowc): Ditto.
+       * syscalls.cc (internal_setlocale): Convert to char * function.
+       Return parameter by default.  Return NULL if request to use a
+       charset can't be satisfied due to missing codepage support in the
+       underlying OS.  Fix comment.
+       (setlocale): Store original locale.  Restore to original locale if
+       internal_setlocale returns NULL.
+
 2009-07-20  Corinna Vinschen  <corinna@vinschen.de>
 
        * fork.cc (fork): Create local tmp_pathbuf.  Explain why.
index 6f2de057a9770bd0318902e1aac938be53457988..64d9001e3379c7f79dc10e897ca64839279f9ae9 100644 (file)
@@ -24,6 +24,7 @@ details. */
 #define pwrite __FOO_pwrite
 
 #include "winsup.h"
+#include "winnls.h"
 #include "miscfuncs.h"
 #include <sys/stat.h>
 #include <sys/vfs.h> /* needed for statfs */
@@ -36,6 +37,7 @@ details. */
 #include <sys/uio.h>
 #include <ctype.h>
 #include <locale.h>
+#include <wchar.h>
 #include <unistd.h>
 #include <sys/wait.h>
 #include <rpc.h>
@@ -4031,32 +4033,61 @@ unlinkat (int dirfd, const char *pathname, int flags)
   return (flags & AT_REMOVEDIR) ? rmdir (path) : unlink (path);
 }
 
-static void
-internal_setlocale ()
+static char *
+internal_setlocale (char *ret)
 {
-  if (*cygheap->locale.charset == 'A')
+  if (*__locale_charset () == 'A')
     {
       cygheap->locale.mbtowc = __utf8_mbtowc;
       cygheap->locale.wctomb = __utf8_wctomb;
     }
   else
     {
+      if (!wincap.has_always_all_codepages ())
+       {
+         /* Prior to Windows Vista, many codepages are not installed by
+            default, or can be deinstalled.  The following codepages require
+            that the respective conversion tables are installed into the OS.
+            So we check if they are installed and if not, setlocale should
+            fail. */
+         CPINFO cpi;
+         UINT cp = 0;
+         if (__mbtowc == __sjis_mbtowc)
+           cp = 932;
+         else if (__mbtowc == __eucjp_mbtowc)
+           cp = 20932;
+         else if (__mbtowc == __gbk_mbtowc)
+           cp = 963;
+         else if (__mbtowc == __kr_mbtowc)
+           cp = 949;
+         else if (__mbtowc == __big5_mbtowc)
+           cp = 950;
+         if (cp && !GetCPInfo (cp, &cpi)
+             && GetLastError () == ERROR_INVALID_PARAMETER)
+           return NULL;
+       }
       cygheap->locale.mbtowc = __mbtowc;
       cygheap->locale.wctomb = __wctomb;
     }
   strcpy (cygheap->locale.charset, __locale_charset ());
   /* Each setlocale potentially changes the multibyte representation
-     of the CWD.  Therefore we have to rest the CWD's posix path and
+     of the CWD.  Therefore we have to reset the CWD's posix path and
      reevaluate the next time it's used. */
   /* FIXME: Other buffered paths might be affected as well. */
   cygheap->cwd.reset_posix ();
+  return ret;
 }
 
 extern "C" char *
 setlocale (int category, const char *locale)
 {
+  char old[(LC_MESSAGES + 1) * (ENCODING_LEN + 1/*"/"*/ + 1)];
+  if (locale && (category == LC_ALL || category == LC_CTYPE)
+      && !wincap.has_always_all_codepages ())
+    stpcpy (old, _setlocale_r (_REENT, category, NULL));
   char *ret = _setlocale_r (_REENT, category, locale);
-  if (ret && locale && (category == LC_ALL || category == LC_CTYPE))
-    internal_setlocale ();
+  if (ret && locale && (category == LC_ALL || category == LC_CTYPE)
+      && !(ret = internal_setlocale (ret)))
+    _setlocale_r (_REENT, category, old);
   return ret;
 }
index fc8eb3858a18d1091077f8453ea36685d64eaa15..f989b7d113ed480a716bde45c21c4df32794b3e3 100644 (file)
@@ -28,6 +28,11 @@ extern mbtowc_f __ascii_mbtowc;
 extern mbtowc_f __utf8_mbtowc;
 extern mbtowc_f __iso_mbtowc;
 extern mbtowc_f __cp_mbtowc;
+extern mbtowc_f __sjis_mbtowc;
+extern mbtowc_f __eucjp_mbtowc;
+extern mbtowc_f __gbk_mbtowc;
+extern mbtowc_f __kr_mbtowc;
+extern mbtowc_f __big5_mbtowc;
 
 typedef int wctomb_f (struct _reent *, char *, wchar_t, const char *,
                      mbstate_t *);
index 774925ec79bdca6fdb613c2e0cc96088d7c10ff8..84e530d3f1f08419e7275fb5429633cefd3de51c 100644 (file)
@@ -56,6 +56,7 @@ wincaps wincap_unknown __attribute__((section (".cygwin_dll_common"), shared)) =
   has_broken_udf:false,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -94,6 +95,7 @@ wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:false,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -132,6 +134,7 @@ wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
   has_broken_udf:false,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -170,6 +173,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:true,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -208,6 +212,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
   has_broken_udf:true,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -246,6 +251,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:true,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -284,6 +290,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:true,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -322,6 +329,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:true,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -360,6 +368,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:true,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:false,
 };
 
 wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -398,6 +407,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:false,
   has_console_handle_problem:false,
   has_broken_alloc_console:false,
+  has_always_all_codepages:true,
 };
 
 wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -436,6 +446,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_broken_udf:false,
   has_console_handle_problem:true,
   has_broken_alloc_console:true,
+  has_always_all_codepages:true,
 };
 
 wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
index ed6eaa9c9d3981f79eb169bde487c731c6dee261..74955ff632ba6eb808bd8272efb06224549939c3 100644 (file)
@@ -48,6 +48,7 @@ struct wincaps
   unsigned has_broken_udf                              : 1;
   unsigned has_console_handle_problem                  : 1;
   unsigned has_broken_alloc_console                    : 1;
+  unsigned has_always_all_codepages                    : 1;
 };
 
 class wincapc
@@ -102,6 +103,7 @@ public:
   bool IMPLEMENT (has_broken_udf)
   bool IMPLEMENT (has_console_handle_problem)
   bool IMPLEMENT (has_broken_alloc_console)
+  bool IMPLEMENT (has_always_all_codepages)
 
 #undef IMPLEMENT
 };
This page took 0.045356 seconds and 5 git commands to generate.