(internal_setlocale): Ditto.
(initial_setlocale): Ditto.
(setlocale): Ditto.
* strfuncs.cc (__sjis_wctomb): Revert previous patch.
(__sjis_mbtowc): Ditto.
* syscalls.cc: Move setlocale-related functions to nlsfuncs.cc.
+2010-01-24 Corinna Vinschen <corinna@vinschen.de>
+
+ * nlsfuncs.cc (check_codepage): Move from syscalls.cc here.
+ (internal_setlocale): Ditto.
+ (initial_setlocale): Ditto.
+ (setlocale): Ditto.
+ * strfuncs.cc (__sjis_wctomb): Revert previous patch.
+ (__sjis_mbtowc): Ditto.
+ * syscalls.cc: Move setlocale-related functions to nlsfuncs.cc.
+
2010-01-23 Corinna Vinschen <corinna@vinschen.de>
* strfuncs.cc (__sjis_wctomb): Special handling for characters which
details. */
#include "winsup.h"
-#include <stdlib.h>
#include <winnls.h>
+#include <stdlib.h>
+#include <locale.h>
#include <wchar.h>
#include "path.h"
#include "fhandler.h"
strcpy (charset, "ISO-8859-15");
}
}
+
+static char *
+check_codepage (char *ret)
+{
+ 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 = 936;
+ 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;
+ }
+ return ret;
+}
+
+static void
+internal_setlocale ()
+{
+ /* Each setlocale from the environment potentially changes the
+ multibyte representation of the CWD. Therefore we have to
+ reevaluate the CWD's posix path and store in the new charset.
+ Same for the PATH environment variable. */
+ /* FIXME: Other buffered paths might be affected as well. */
+ /* FIXME: It could be necessary to convert the entire environment,
+ not just PATH. */
+ tmp_pathbuf tp;
+ char *path = getenv ("PATH");
+ wchar_t *w_path = NULL, *w_cwd;
+
+ debug_printf ("Cygwin charset changed from %s to %s",
+ cygheap->locale.charset, __locale_charset ());
+ /* Fetch PATH and CWD and convert to wchar_t in previous charset. */
+ if (path && *path) /* $PATH can be potentially unset. */
+ {
+ w_path = tp.w_get ();
+ sys_mbstowcs (w_path, 32768, path);
+ }
+ w_cwd = tp.w_get ();
+ cwdstuff::cwd_lock.acquire ();
+ sys_mbstowcs (w_cwd, 32768, cygheap->cwd.get_posix ());
+ /* Set charset for internal conversion functions. */
+ if (*__locale_charset () == 'A'/*SCII*/)
+ {
+ cygheap->locale.mbtowc = __utf8_mbtowc;
+ cygheap->locale.wctomb = __utf8_wctomb;
+ }
+ else
+ {
+ cygheap->locale.mbtowc = __mbtowc;
+ cygheap->locale.wctomb = __wctomb;
+ }
+ strcpy (cygheap->locale.charset, __locale_charset ());
+ /* Restore CWD and PATH in new charset. */
+ cygheap->cwd.reset_posix (w_cwd);
+ cwdstuff::cwd_lock.release ();
+ if (w_path)
+ {
+ char *c_path = tp.c_get ();
+ sys_wcstombs (c_path, 32768, w_path);
+ setenv ("PATH", c_path, 1);
+ }
+}
+
+/* Called from dll_crt0_1, before fetching the command line from Windows.
+ Set the internal charset according to the environment locale settings.
+ Check if a required codepage is available, and only switch internal
+ charset if so.
+ Make sure to reset the application locale to "C" per POSIX. */
+void
+initial_setlocale ()
+{
+ char *ret = _setlocale_r (_REENT, LC_CTYPE, "");
+ if (ret && check_codepage (ret)
+ && strcmp (cygheap->locale.charset, __locale_charset ()) != 0)
+ internal_setlocale ();
+}
+
+/* Like newlib's setlocale, but additionally check if the charset needs
+ OS support and the required codepage is actually installed. If codepage
+ is not available, revert to previous locale and return NULL. For details
+ about codepage availability, see the comment in check_codepage() above. */
+extern "C" char *
+setlocale (int category, const char *locale)
+{
+ char old[(LC_MESSAGES + 1) * (ENCODING_LEN + 1/*"/"*/ + 1)];
+ if (locale && !wincap.has_always_all_codepages ())
+ stpcpy (old, _setlocale_r (_REENT, category, NULL));
+ char *ret = _setlocale_r (_REENT, category, locale);
+ if (ret && locale && !(ret = check_codepage (ret)))
+ _setlocale_r (_REENT, category, old);
+ return ret;
+}
__sjis_wctomb (struct _reent *r, char *s, wchar_t wchar, const char *charset,
mbstate_t *state)
{
- if (*charset == 'S')
- {
- /* SJIS is not exactly CP932. Two ASCII code points are converted
- differently. */
- if (wchar == L'\x00a5') /* SJIS has Yen sign in place of Backslash */
- {
- if (s)
- *s = '\x5c';
- return 1;
- }
- else if (wchar == L'\x203e') /* SJIS has Overline in place of Tilde */
- {
- if (s)
- *s = '\x7e';
- return 1;
- }
- }
return __db_wctomb (r,s, wchar, 932);
}
__sjis_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
const char *charset, mbstate_t *state)
{
- int ret = __db_mbtowc (r, pwc, s, n, 932, state);
- if (*charset == 'S' && pwc && ret == 1)
- {
- /* CP932 is not exactly SJIS. Two ASCII code points are converted
- differently. */
- if (*s == '\x5c') /* SJIS has Yen sign in place of Backslash */
- *pwc = L'\x00a5';
- else if (*s == '\x7e') /* SJIS has Overline in place of Tilde */
- *pwc = L'\x203e';
- }
- return ret;
+ return __db_mbtowc (r, pwc, s, n, 932, state);
}
extern "C" int
#define pwrite __FOO_pwrite
#include "winsup.h"
-#include "winnls.h"
+#include <winnls.h>
#include "miscfuncs.h"
#include <sys/stat.h>
#include <sys/vfs.h> /* needed for statfs */
#include <utmpx.h>
#include <sys/uio.h>
#include <ctype.h>
-#include <locale.h>
-#include <wchar.h>
#include <unistd.h>
#include <sys/wait.h>
#include <rpc.h>
return -1;
return (flags & AT_REMOVEDIR) ? rmdir (path) : unlink (path);
}
-
-static char *
-check_codepage (char *ret)
-{
- 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 = 936;
- 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;
- }
- return ret;
-}
-
-static void
-internal_setlocale ()
-{
- /* Each setlocale from the environment potentially changes the
- multibyte representation of the CWD. Therefore we have to
- reevaluate the CWD's posix path and store in the new charset.
- Same for the PATH environment variable. */
- /* FIXME: Other buffered paths might be affected as well. */
- /* FIXME: It could be necessary to convert the entire environment,
- not just PATH. */
- tmp_pathbuf tp;
- char *path = getenv ("PATH");
- wchar_t *w_path = NULL, *w_cwd;
-
- debug_printf ("Cygwin charset changed from %s to %s",
- cygheap->locale.charset, __locale_charset ());
- /* Fetch PATH and CWD and convert to wchar_t in previous charset. */
- if (path && *path) /* $PATH can be potentially unset. */
- {
- w_path = tp.w_get ();
- sys_mbstowcs (w_path, 32768, path);
- }
- w_cwd = tp.w_get ();
- cwdstuff::cwd_lock.acquire ();
- sys_mbstowcs (w_cwd, 32768, cygheap->cwd.get_posix ());
- /* Set charset for internal conversion functions. */
- if (*__locale_charset () == 'A'/*SCII*/)
- {
- cygheap->locale.mbtowc = __utf8_mbtowc;
- cygheap->locale.wctomb = __utf8_wctomb;
- }
- else
- {
- cygheap->locale.mbtowc = __mbtowc;
- cygheap->locale.wctomb = __wctomb;
- }
- strcpy (cygheap->locale.charset, __locale_charset ());
- /* Restore CWD and PATH in new charset. */
- cygheap->cwd.reset_posix (w_cwd);
- cwdstuff::cwd_lock.release ();
- if (w_path)
- {
- char *c_path = tp.c_get ();
- sys_wcstombs (c_path, 32768, w_path);
- setenv ("PATH", c_path, 1);
- }
-}
-
-/* Called from dll_crt0_1, before fetching the command line from Windows.
- Set the internal charset according to the environment locale settings.
- Check if a required codepage is available, and only switch internal
- charset if so.
- Make sure to reset the application locale to "C" per POSIX. */
-void
-initial_setlocale ()
-{
- char *ret = _setlocale_r (_REENT, LC_CTYPE, "");
- if (ret && check_codepage (ret)
- && strcmp (cygheap->locale.charset, __locale_charset ()) != 0)
- internal_setlocale ();
-}
-
-/* Like newlib's setlocale, but additionally check if the charset needs
- OS support and the required codepage is actually installed. If codepage
- is not available, revert to previous locale and return NULL. For details
- about codepage availability, see the comment in check_codepage() above. */
-extern "C" char *
-setlocale (int category, const char *locale)
-{
- char old[(LC_MESSAGES + 1) * (ENCODING_LEN + 1/*"/"*/ + 1)];
- if (locale && !wincap.has_always_all_codepages ())
- stpcpy (old, _setlocale_r (_REENT, category, NULL));
- char *ret = _setlocale_r (_REENT, category, locale);
- if (ret && locale && !(ret = check_codepage (ret)))
- _setlocale_r (_REENT, category, old);
- return ret;
-}