mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-18 20:39:33 +08:00
* 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.
This commit is contained in:
parent
cb8ee36ae8
commit
20fc2f4936
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user