4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-28 12:05:47 +08:00

Consolidate wctomb/mbtowc calls for POSIX-1.2008

- Remove charset parameter from low level __foo_wctomb/__foo_mbtowc calls.
- Instead, create array of function for ISO and Windows codepages to point
  to function which does not require to evaluate the charset string on
  each call.  Create matching helper functions.  I.e., __iso_wctomb,
  __iso_mbtowc, __cp_wctomb and __cp_mbtowc are functions returning the
  right function pointer now.
- Create __WCTOMB/__MBTOWC macros utilizing per-reent locale and replace
  calls to __wctomb/__mbtowc with calls to __WCTOMB/__MBTOWC.
- Drop global __wctomb/__mbtowc vars.
- Utilize aforementioned changes in Cygwin to get rid of charset in other,
  calling functions and simplify the code.
- In Cygwin restrict global cygheap locale info to the job performed
  by internal_setlocale.  Use UTF-8 instead of ASCII on the fly in
  internal conversion functions.
- In Cygwin dll_entry, make sure to initialize a TLS area with a NULL
  _REENT->_locale pointer.  Add comment to explain why.

Signed-off by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-07-20 22:05:59 +02:00
parent 88208d3735
commit d16a56306d
31 changed files with 941 additions and 355 deletions

View File

@ -56,6 +56,6 @@ _DEFUN(isgraph,(c),int c)
int int
_DEFUN(isprint,(c),int c) _DEFUN(isprint,(c),int c)
{ {
return(__ctype_ptr__[c+1] & (_P|_U|_L|_N|_B)); return(__CTYPE_PTR[c+1] & (_P|_U|_L|_N|_B));
} }

View File

@ -1,6 +1,7 @@
/* wctrans constants */ /* wctrans constants */
#include <_ansi.h> #include <_ansi.h>
#include "../locale/setlocale.h"
/* valid values for wctrans_t */ /* valid values for wctrans_t */
#define WCT_TOLOWER 1 #define WCT_TOLOWER 1
@ -20,8 +21,6 @@
#define WC_UPPER 11 #define WC_UPPER 11
#define WC_XDIGIT 12 #define WC_XDIGIT 12
extern char *__locale_charset(_NOARGS);
/* internal function to translate JP to Unicode */ /* internal function to translate JP to Unicode */
#ifdef __CYGWIN__ #ifdef __CYGWIN__
/* Under Cygwin, the incoming wide character is already given in UTF due /* Under Cygwin, the incoming wide character is already given in UTF due

View File

@ -459,12 +459,11 @@ loadlocale(struct _reent *p, int category)
dependent on the cateogry. */ dependent on the cateogry. */
char *locale = NULL; char *locale = NULL;
char charset[ENCODING_LEN + 1]; char charset[ENCODING_LEN + 1];
unsigned long val; long val = 0;
char *end, *c = NULL; char *end, *c = NULL;
int mbc_max; int mbc_max;
int (*l_wctomb) (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_p l_wctomb;
int (*l_mbtowc) (struct _reent *, wchar_t *, const char *, size_t, mbtowc_p l_mbtowc;
const char *, mbstate_t *);
int cjknarrow = 0; int cjknarrow = 0;
/* Avoid doing everything twice if nothing has changed. */ /* Avoid doing everything twice if nothing has changed. */
@ -674,8 +673,8 @@ restart:
*c = '\0'; *c = '\0';
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_ISO #ifdef _MB_EXTENDED_CHARSETS_ISO
l_wctomb = __iso_wctomb; l_wctomb = __iso_wctomb (val);
l_mbtowc = __iso_mbtowc; l_mbtowc = __iso_mbtowc (val);
#else /* !_MB_EXTENDED_CHARSETS_ISO */ #else /* !_MB_EXTENDED_CHARSETS_ISO */
l_wctomb = __ascii_wctomb; l_wctomb = __ascii_wctomb;
l_mbtowc = __ascii_mbtowc; l_mbtowc = __ascii_mbtowc;
@ -715,8 +714,8 @@ restart:
case 1258: case 1258:
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
l_wctomb = __cp_wctomb; l_wctomb = __cp_wctomb (val);
l_mbtowc = __cp_mbtowc; l_mbtowc = __cp_mbtowc (val);
#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
l_wctomb = __ascii_wctomb; l_wctomb = __ascii_wctomb;
l_mbtowc = __ascii_mbtowc; l_mbtowc = __ascii_mbtowc;
@ -740,15 +739,21 @@ restart:
if (*c == '-') if (*c == '-')
++c; ++c;
if (*c == 'R' || *c == 'r') if (*c == 'R' || *c == 'r')
strcpy (charset, "CP20866"); {
val = 20866;
strcpy (charset, "CP20866");
}
else if (*c == 'U' || *c == 'u') else if (*c == 'U' || *c == 'u')
strcpy (charset, "CP21866"); {
val = 21866;
strcpy (charset, "CP21866");
}
else else
FAIL; FAIL;
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
l_wctomb = __cp_wctomb; l_wctomb = __cp_wctomb (val);
l_mbtowc = __cp_mbtowc; l_mbtowc = __cp_mbtowc (val);
#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
l_wctomb = __ascii_wctomb; l_wctomb = __ascii_wctomb;
l_mbtowc = __ascii_mbtowc; l_mbtowc = __ascii_mbtowc;
@ -786,11 +791,12 @@ restart:
++c; ++c;
if (strcasecmp (c, "PS")) if (strcasecmp (c, "PS"))
FAIL; FAIL;
val = 101;
strcpy (charset, "CP101"); strcpy (charset, "CP101");
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
l_wctomb = __cp_wctomb; l_wctomb = __cp_wctomb (val);
l_mbtowc = __cp_mbtowc; l_mbtowc = __cp_mbtowc (val);
#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
l_wctomb = __ascii_wctomb; l_wctomb = __ascii_wctomb;
l_mbtowc = __ascii_mbtowc; l_mbtowc = __ascii_mbtowc;
@ -804,11 +810,12 @@ restart:
/* PT154 */ /* PT154 */
if (strcasecmp (charset, "PT154")) if (strcasecmp (charset, "PT154"))
FAIL; FAIL;
val = 102;
strcpy (charset, "CP102"); strcpy (charset, "CP102");
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
l_wctomb = __cp_wctomb; l_wctomb = __cp_wctomb (val);
l_mbtowc = __cp_mbtowc; l_mbtowc = __cp_mbtowc (val);
#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
l_wctomb = __ascii_wctomb; l_wctomb = __ascii_wctomb;
l_mbtowc = __ascii_mbtowc; l_mbtowc = __ascii_mbtowc;
@ -826,8 +833,8 @@ restart:
strcpy (charset, "CP874"); strcpy (charset, "CP874");
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
l_wctomb = __cp_wctomb; l_wctomb = __cp_wctomb (val);
l_mbtowc = __cp_mbtowc; l_mbtowc = __cp_mbtowc (val);
#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
l_wctomb = __ascii_wctomb; l_wctomb = __ascii_wctomb;
l_mbtowc = __ascii_mbtowc; l_mbtowc = __ascii_mbtowc;
@ -859,8 +866,8 @@ restart:
#ifdef __CYGWIN__ #ifdef __CYGWIN__
__mb_cur_max = mbc_max; /* Only for backward compat */ __mb_cur_max = mbc_max; /* Only for backward compat */
#endif #endif
__wctomb = l_wctomb; __global_locale.wctomb = l_wctomb;
__mbtowc = l_mbtowc; __global_locale.mbtowc = l_mbtowc;
__set_ctype (NULL, charset); __set_ctype (NULL, charset);
/* Determine the width for the "CJK Ambiguous Width" category of /* Determine the width for the "CJK Ambiguous Width" category of
characters. This is used in wcwidth(). Assume single width for characters. This is used in wcwidth(). Assume single width for
@ -943,16 +950,6 @@ __get_locale_env(struct _reent *p, int category)
} }
#endif /* _MB_CAPABLE */ #endif /* _MB_CAPABLE */
char *
_DEFUN_VOID(__locale_charset)
{
#ifdef __HAVE_LOCALE_INFO__
return __get_current_ctype_locale ()->codeset;
#else
return __global_locale.ctype_codeset;
#endif
}
int int
_DEFUN_VOID(__locale_mb_cur_max) _DEFUN_VOID(__locale_mb_cur_max)
{ {
@ -963,36 +960,16 @@ _DEFUN_VOID(__locale_mb_cur_max)
#endif #endif
} }
char *
_DEFUN_VOID(__locale_msgcharset)
{
#ifdef __HAVE_LOCALE_INFO__
return (char *) __get_current_messages_locale ()->codeset;
#else
return (char *) __global_locale.message_codeset;
#endif
}
int
_DEFUN_VOID(__locale_cjk_lang)
{
#ifdef __HAVE_LOCALE_INFO__
return __get_current_locale ()->cjk_lang;
#else
return __global_locale.cjk_lang;
#endif
}
#ifdef __HAVE_LOCALE_INFO__ #ifdef __HAVE_LOCALE_INFO__
char * char *
_DEFUN_VOID(__locale_ctype_ptr) _DEFUN_VOID(__locale_ctype_ptr)
{ {
/* Only check if the current thread/reent has a locale. ctype_ptr is unused /* Only check if the current thread/reent has a locale. ctype_ptr is unused
in __global_locale, rather the global variable __ctype_ptr__ is used. */ in __global_locale, rather the global variable __ctype_ptr__ is used. */
extern char *__ctype_ptr__;
return __get_locale_r (_REENT) ? __get_locale_r (_REENT)->ctype_ptr return __get_locale_r (_REENT) ? __get_locale_r (_REENT)->ctype_ptr
: __ctype_ptr__; : __ctype_ptr__;
} }
#endif #endif
struct lconv * struct lconv *

View File

@ -172,8 +172,6 @@ static struct _nl_item_t
#define _REL(BASE) ((int)item-BASE) #define _REL(BASE) ((int)item-BASE)
extern char *__locale_charset ();
char * char *
_DEFUN(nl_langinfo, (item), _DEFUN(nl_langinfo, (item),
nl_item item) { nl_item item) {

View File

@ -159,8 +159,7 @@ typedef __uint32_t LCID;
struct lc_collate_T struct lc_collate_T
{ {
LCID lcid; LCID lcid;
int (*mbtowc) (struct _reent *, wchar_t *, const char *, size_t, const char *, int (*mbtowc) (struct _reent *, wchar_t *, const char *, size_t, mbstate_t *);
mbstate_t *);
char codeset[ENCODING_LEN + 1]; char codeset[ENCODING_LEN + 1];
}; };
extern const struct lc_collate_T _C_collate_locale; extern const struct lc_collate_T _C_collate_locale;
@ -169,13 +168,12 @@ extern const struct lc_collate_T _C_collate_locale;
struct _thr_locale_t struct _thr_locale_t
{ {
char categories[_LC_LAST][ENCODING_LEN + 1]; char categories[_LC_LAST][ENCODING_LEN + 1];
int (*__wctomb) (struct _reent *, char *, wchar_t, int (*wctomb) (struct _reent *, char *, wchar_t,
const char *, mbstate_t *); mbstate_t *);
int (*__mbtowc) (struct _reent *, wchar_t *, int (*mbtowc) (struct _reent *, wchar_t *,
const char *, size_t, const char *, const char *, size_t, mbstate_t *);
mbstate_t *);
char *ctype_ptr; /* Unused in __global_locale */
int cjk_lang; int cjk_lang;
char *ctype_ptr; /* Unused in __global_locale */
#ifndef __HAVE_LOCALE_INFO__ #ifndef __HAVE_LOCALE_INFO__
char mb_cur_max[2]; char mb_cur_max[2];
char ctype_codeset[ENCODING_LEN + 1]; char ctype_codeset[ENCODING_LEN + 1];
@ -264,6 +262,36 @@ __get_current_collate_locale (void)
} }
#endif #endif
_ELIDABLE_INLINE const char *
__locale_charset (void)
{
#ifdef __HAVE_LOCALE_INFO__
return __get_current_ctype_locale ()->codeset;
#else
return __global_locale.ctype_codeset;
#endif
}
_ELIDABLE_INLINE const char *
__locale_msgcharset (void)
{
#ifdef __HAVE_LOCALE_INFO__
return (char *) __get_current_messages_locale ()->codeset;
#else
return (char *) __global_locale.message_codeset;
#endif
}
_ELIDABLE_INLINE int
__locale_cjk_lang (void)
{
#ifdef __HAVE_LOCALE_INFO__
return __get_current_locale ()->cjk_lang;
#else
return __global_locale.cjk_lang;
#endif
}
int __ctype_load_locale (struct _thr_locale_t *, const char *, void *, int __ctype_load_locale (struct _thr_locale_t *, const char *, void *,
const char *, int); const char *, int);
int __monetary_load_locale (struct _thr_locale_t *, const char *, void *, int __monetary_load_locale (struct _thr_locale_t *, const char *, void *,

View File

@ -910,8 +910,8 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
for (;;) { for (;;) {
cp = fmt; cp = fmt;
#ifdef _MB_CAPABLE #ifdef _MB_CAPABLE
while ((n = __mbtowc (data, &wc, fmt, MB_CUR_MAX, while ((n = __MBTOWC (data, &wc, fmt, MB_CUR_MAX,
__locale_charset (), &state)) != 0) { &state)) != 0) {
if (n < 0) { if (n < 0) {
/* Wave invalid chars through. */ /* Wave invalid chars through. */
memset (&state, 0, sizeof state); memset (&state, 0, sizeof state);
@ -2079,8 +2079,7 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
while (*fmt && n >= numargs) while (*fmt && n >= numargs)
{ {
# ifdef _MB_CAPABLE # ifdef _MB_CAPABLE
while ((nbytes = __mbtowc (data, &wc, fmt, MB_CUR_MAX, while ((nbytes = __MBTOWC (data, &wc, fmt, MB_CUR_MAX, &wc_state)) > 0)
__locale_charset (), &wc_state)) > 0)
{ {
fmt += nbytes; fmt += nbytes;
if (wc == '%') if (wc == '%')

View File

@ -508,8 +508,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
#ifndef _MB_CAPABLE #ifndef _MB_CAPABLE
wc = *fmt; wc = *fmt;
#else #else
nbytes = __mbtowc (rptr, &wc, (char *) fmt, MB_CUR_MAX, nbytes = __MBTOWC (rptr, &wc, (char *) fmt, MB_CUR_MAX, &state);
__locale_charset (), &state);
if (nbytes < 0) { if (nbytes < 0) {
wc = 0xFFFD; /* Unicode replacement character */ wc = 0xFFFD; /* Unicode replacement character */
nbytes = 1; nbytes = 1;

View File

@ -23,8 +23,7 @@ btowc (int c)
_REENT_CHECK_MISC(_REENT); _REENT_CHECK_MISC(_REENT);
retval = __mbtowc (_REENT, &pwc, (const char *) &b, 1, retval = __MBTOWC (_REENT, &pwc, (const char *) &b, 1, &mbs);
__locale_charset (), &mbs);
if (retval != 0 && retval != 1) if (retval != 0 && retval != 1)
return WEOF; return WEOF;

View File

@ -5,62 +5,59 @@
char * _EXFUN(_gcvt,(struct _reent *, double , int , char *, char, int)); char * _EXFUN(_gcvt,(struct _reent *, double , int , char *, char, int));
char *__locale_charset(_NOARGS); #include "../locale/setlocale.h"
#ifndef __machine_mbstate_t_defined #ifndef __machine_mbstate_t_defined
#include <wchar.h> #include <wchar.h>
#endif #endif
extern int (*__wctomb) (struct _reent *, char *, wchar_t, const char *, typedef int wctomb_f (struct _reent *, char *, wchar_t, mbstate_t *);
mbstate_t *); typedef wctomb_f *wctomb_p;
int __ascii_wctomb (struct _reent *, char *, wchar_t, const char *,
mbstate_t *); wctomb_f __ascii_wctomb;
#ifdef _MB_CAPABLE #ifdef _MB_CAPABLE
int __utf8_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_f __utf8_wctomb;
int __sjis_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_f __sjis_wctomb;
int __eucjp_wctomb (struct _reent *, char *, wchar_t, const char *, wctomb_f __eucjp_wctomb;
mbstate_t *); wctomb_f __jis_wctomb;
int __jis_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_p __iso_wctomb (int val);
int __iso_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_p __cp_wctomb (int val);
int __cp_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *);
#ifdef __CYGWIN__ #ifdef __CYGWIN__
int __gbk_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_f __gbk_wctomb;
int __kr_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_f __kr_wctomb;
int __big5_wctomb (struct _reent *, char *, wchar_t, const char *, mbstate_t *); wctomb_f __big5_wctomb;
#endif #endif
#endif #endif
extern int (*__mbtowc) (struct _reent *, wchar_t *, const char *, size_t, #define __WCTOMB (__get_current_locale ()->wctomb)
const char *, mbstate_t *);
int __ascii_mbtowc (struct _reent *, wchar_t *, const char *, size_t, typedef int mbtowc_f (struct _reent *, wchar_t *, const char *, size_t,
const char *, mbstate_t *); mbstate_t *);
typedef mbtowc_f *mbtowc_p;
mbtowc_f __ascii_mbtowc;
#ifdef _MB_CAPABLE #ifdef _MB_CAPABLE
int __utf8_mbtowc (struct _reent *, wchar_t *, const char *, size_t, mbtowc_f __utf8_mbtowc;
const char *, mbstate_t *); mbtowc_f __sjis_mbtowc;
int __sjis_mbtowc (struct _reent *, wchar_t *, const char *, size_t, mbtowc_f __eucjp_mbtowc;
const char *, mbstate_t *); mbtowc_f __jis_mbtowc;
int __eucjp_mbtowc (struct _reent *, wchar_t *, const char *, size_t, mbtowc_p __iso_mbtowc (int val);
const char *, mbstate_t *); mbtowc_p __cp_mbtowc (int val);
int __jis_mbtowc (struct _reent *, wchar_t *, const char *, size_t,
const char *, mbstate_t *);
int __iso_mbtowc (struct _reent *, wchar_t *, const char *, size_t,
const char *, mbstate_t *);
int __cp_mbtowc (struct _reent *, wchar_t *, const char *, size_t,
const char *, mbstate_t *);
#ifdef __CYGWIN__ #ifdef __CYGWIN__
int __gbk_mbtowc (struct _reent *, wchar_t *, const char *, size_t, mbtowc_f __gbk_mbtowc;
const char *, mbstate_t *); mbtowc_f __kr_mbtowc;
int __kr_mbtowc (struct _reent *, wchar_t *, const char *, size_t, mbtowc_f __big5_mbtowc;
const char *, mbstate_t *);
int __big5_mbtowc (struct _reent *, wchar_t *, const char *, size_t,
const char *, mbstate_t *);
#endif #endif
#endif #endif
#define __MBTOWC (__get_current_locale ()->mbtowc)
extern wchar_t __iso_8859_conv[14][0x60]; extern wchar_t __iso_8859_conv[14][0x60];
int __iso_8859_val_index (int);
int __iso_8859_index (const char *); int __iso_8859_index (const char *);
extern wchar_t __cp_conv[][0x80]; extern wchar_t __cp_conv[][0x80];
int __cp_val_index (int);
int __cp_index (const char *); int __cp_index (const char *);
#endif #endif

View File

@ -60,7 +60,7 @@ _DEFUN (mblen, (s, n),
_REENT_CHECK_MISC(reent); _REENT_CHECK_MISC(reent);
state = &(_REENT_MBLEN_STATE(reent)); state = &(_REENT_MBLEN_STATE(reent));
retval = __mbtowc (reent, NULL, s, n, __locale_charset (), state); retval = __MBTOWC (reent, NULL, s, n, state);
if (retval < 0) if (retval < 0)
{ {
state->__count = 0; state->__count = 0;

View File

@ -57,7 +57,7 @@ _DEFUN (_mblen_r, (r, s, n, state),
{ {
#ifdef _MB_CAPABLE #ifdef _MB_CAPABLE
int retval; int retval;
retval = __mbtowc (r, NULL, s, n, __locale_charset (), state); retval = __MBTOWC (r, NULL, s, n, state);
if (retval < 0) if (retval < 0)
{ {

View File

@ -26,9 +26,9 @@ _DEFUN (_mbrtowc_r, (ptr, pwc, s, n, ps),
#endif #endif
if (s == NULL) if (s == NULL)
retval = __mbtowc (ptr, NULL, "", 1, __locale_charset (), ps); retval = __MBTOWC (ptr, NULL, "", 1, ps);
else else
retval = __mbtowc (ptr, pwc, s, n, __locale_charset (), ps); retval = __MBTOWC (ptr, pwc, s, n, ps);
if (retval == -1) if (retval == -1)
{ {
@ -63,9 +63,9 @@ _DEFUN (mbrtowc, (pwc, s, n, ps),
#endif #endif
if (s == NULL) if (s == NULL)
retval = __mbtowc (reent, NULL, "", 1, __locale_charset (), ps); retval = __MBTOWC (reent, NULL, "", 1, ps);
else else
retval = __mbtowc (reent, pwc, s, n, __locale_charset (), ps); retval = __MBTOWC (reent, pwc, s, n, ps);
if (retval == -1) if (retval == -1)
{ {

View File

@ -18,7 +18,7 @@ _DEFUN (_mbstowcs_r, (reent, pwcs, s, n, state),
n = (size_t) 1; /* Value doesn't matter as long as it's not 0. */ n = (size_t) 1; /* Value doesn't matter as long as it's not 0. */
while (n > 0) while (n > 0)
{ {
bytes = __mbtowc (r, pwcs, t, MB_CUR_MAX, __locale_charset (), state); bytes = __MBTOWC (r, pwcs, t, MB_CUR_MAX, state);
if (bytes < 0) if (bytes < 0)
{ {
state->__count = 0; state->__count = 0;

View File

@ -70,7 +70,7 @@ _DEFUN (mbtowc, (pwc, s, n),
_REENT_CHECK_MISC(reent); _REENT_CHECK_MISC(reent);
ps = &(_REENT_MBTOWC_STATE(reent)); ps = &(_REENT_MBTOWC_STATE(reent));
retval = __mbtowc (reent, pwc, s, n, __locale_charset (), ps); retval = __MBTOWC (reent, pwc, s, n, ps);
if (retval < 0) if (retval < 0)
{ {

View File

@ -7,15 +7,6 @@
#include <errno.h> #include <errno.h>
#include "local.h" #include "local.h"
int (*__mbtowc) (struct _reent *, wchar_t *, const char *, size_t,
const char *, mbstate_t *)
#ifdef __CYGWIN__
/* Cygwin starts up in UTF-8 mode. */
= __utf8_mbtowc;
#else
= __ascii_mbtowc;
#endif
int int
_DEFUN (_mbtowc_r, (r, pwc, s, n, state), _DEFUN (_mbtowc_r, (r, pwc, s, n, state),
struct _reent *r _AND struct _reent *r _AND
@ -24,16 +15,15 @@ _DEFUN (_mbtowc_r, (r, pwc, s, n, state),
size_t n _AND size_t n _AND
mbstate_t *state) mbstate_t *state)
{ {
return __mbtowc (r, pwc, s, n, __locale_charset (), state); return __MBTOWC (r, pwc, s, n, state);
} }
int int
_DEFUN (__ascii_mbtowc, (r, pwc, s, n, charset, state), _DEFUN (__ascii_mbtowc, (r, pwc, s, n, state),
struct _reent *r _AND struct _reent *r _AND
wchar_t *pwc _AND wchar_t *pwc _AND
const char *s _AND const char *s _AND
size_t n _AND size_t n _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wchar_t dummy; wchar_t dummy;
@ -106,14 +96,9 @@ static JIS_ACTION JIS_action_table[JIS_S_NUM][JIS_C_NUM] = {
#define __state __count #define __state __count
#ifdef _MB_EXTENDED_CHARSETS_ISO #ifdef _MB_EXTENDED_CHARSETS_ISO
int static int
_DEFUN (__iso_mbtowc, (r, pwc, s, n, charset, state), ___iso_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
struct _reent *r _AND int iso_idx, mbstate_t *state)
wchar_t *pwc _AND
const char *s _AND
size_t n _AND
const char *charset _AND
mbstate_t *state)
{ {
wchar_t dummy; wchar_t dummy;
unsigned char *t = (unsigned char *)s; unsigned char *t = (unsigned char *)s;
@ -129,7 +114,6 @@ _DEFUN (__iso_mbtowc, (r, pwc, s, n, charset, state),
if (*t >= 0xa0) if (*t >= 0xa0)
{ {
int iso_idx = __iso_8859_index (charset + 9);
if (iso_idx >= 0) if (iso_idx >= 0)
{ {
*pwc = __iso_8859_conv[iso_idx][*t - 0xa0]; *pwc = __iso_8859_conv[iso_idx][*t - 0xa0];
@ -149,17 +133,145 @@ _DEFUN (__iso_mbtowc, (r, pwc, s, n, charset, state),
return 1; return 1;
} }
static int
__iso_8859_1_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, -1, state);
}
static int
__iso_8859_2_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 0, state);
}
static int
__iso_8859_3_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 1, state);
}
static int
__iso_8859_4_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 2, state);
}
static int
__iso_8859_5_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 3, state);
}
static int
__iso_8859_6_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 4, state);
}
static int
__iso_8859_7_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 5, state);
}
static int
__iso_8859_8_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 6, state);
}
static int
__iso_8859_9_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 7, state);
}
static int
__iso_8859_10_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 8, state);
}
static int
__iso_8859_11_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 9, state);
}
static int
__iso_8859_13_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 10, state);
}
static int
__iso_8859_14_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 11, state);
}
static int
__iso_8859_15_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 12, state);
}
static int
__iso_8859_16_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___iso_mbtowc (r, pwc, s, n, 13, state);
}
static mbtowc_p __iso_8859_mbtowc[17] = {
NULL,
__iso_8859_1_mbtowc,
__iso_8859_2_mbtowc,
__iso_8859_3_mbtowc,
__iso_8859_4_mbtowc,
__iso_8859_5_mbtowc,
__iso_8859_6_mbtowc,
__iso_8859_7_mbtowc,
__iso_8859_8_mbtowc,
__iso_8859_9_mbtowc,
__iso_8859_10_mbtowc,
__iso_8859_11_mbtowc,
NULL, /* No ISO 8859-12 */
__iso_8859_13_mbtowc,
__iso_8859_14_mbtowc,
__iso_8859_15_mbtowc,
__iso_8859_16_mbtowc
};
/* val *MUST* be valid! All checks for validity are supposed to be
performed before calling this function. */
mbtowc_p
__iso_mbtowc (int val)
{
return __iso_8859_mbtowc[val];
}
#endif /* _MB_EXTENDED_CHARSETS_ISO */ #endif /* _MB_EXTENDED_CHARSETS_ISO */
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
int static int
_DEFUN (__cp_mbtowc, (r, pwc, s, n, charset, state), ___cp_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
struct _reent *r _AND int cp_idx, mbstate_t *state)
wchar_t *pwc _AND
const char *s _AND
size_t n _AND
const char *charset _AND
mbstate_t *state)
{ {
wchar_t dummy; wchar_t dummy;
unsigned char *t = (unsigned char *)s; unsigned char *t = (unsigned char *)s;
@ -175,7 +287,6 @@ _DEFUN (__cp_mbtowc, (r, pwc, s, n, charset, state),
if (*t >= 0x80) if (*t >= 0x80)
{ {
int cp_idx = __cp_index (charset + 2);
if (cp_idx >= 0) if (cp_idx >= 0)
{ {
*pwc = __cp_conv[cp_idx][*t - 0x80]; *pwc = __cp_conv[cp_idx][*t - 0x80];
@ -195,15 +306,233 @@ _DEFUN (__cp_mbtowc, (r, pwc, s, n, charset, state),
return 1; return 1;
} }
static int
__cp_437_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 0, state);
}
static int
__cp_720_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 1, state);
}
static int
__cp_737_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 2, state);
}
static int
__cp_775_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 3, state);
}
static int
__cp_850_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 4, state);
}
static int
__cp_852_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 5, state);
}
static int
__cp_855_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 6, state);
}
static int
__cp_857_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 7, state);
}
static int
__cp_858_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 8, state);
}
static int
__cp_862_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 9, state);
}
static int
__cp_866_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 10, state);
}
static int
__cp_874_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 11, state);
}
static int
__cp_1125_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 12, state);
}
static int
__cp_1250_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 13, state);
}
static int
__cp_1251_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 14, state);
}
static int
__cp_1252_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 15, state);
}
static int
__cp_1253_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 16, state);
}
static int
__cp_1254_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 17, state);
}
static int
__cp_1255_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 18, state);
}
static int
__cp_1256_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 19, state);
}
static int
__cp_1257_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 20, state);
}
static int
__cp_1258_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 21, state);
}
static int
__cp_20866_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 22, state);
}
static int
__cp_21866_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 23, state);
}
static int
__cp_101_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 24, state);
}
static int
__cp_102_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
mbstate_t *state)
{
return ___cp_mbtowc (r, pwc, s, n, 25, state);
}
static mbtowc_p __cp_xxx_mbtowc[26] = {
__cp_437_mbtowc,
__cp_720_mbtowc,
__cp_737_mbtowc,
__cp_775_mbtowc,
__cp_850_mbtowc,
__cp_852_mbtowc,
__cp_855_mbtowc,
__cp_857_mbtowc,
__cp_858_mbtowc,
__cp_862_mbtowc,
__cp_866_mbtowc,
__cp_874_mbtowc,
__cp_1125_mbtowc,
__cp_1250_mbtowc,
__cp_1251_mbtowc,
__cp_1252_mbtowc,
__cp_1253_mbtowc,
__cp_1254_mbtowc,
__cp_1255_mbtowc,
__cp_1256_mbtowc,
__cp_1257_mbtowc,
__cp_1258_mbtowc,
__cp_20866_mbtowc,
__cp_21866_mbtowc,
__cp_101_mbtowc,
__cp_102_mbtowc
};
/* val *MUST* be valid! All checks for validity are supposed to be
performed before calling this function. */
mbtowc_p
__cp_mbtowc (int val)
{
return __cp_xxx_mbtowc[__cp_val_index (val)];
}
#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */ #endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
int int
_DEFUN (__utf8_mbtowc, (r, pwc, s, n, charset, state), _DEFUN (__utf8_mbtowc, (r, pwc, s, n, state),
struct _reent *r _AND struct _reent *r _AND
wchar_t *pwc _AND wchar_t *pwc _AND
const char *s _AND const char *s _AND
size_t n _AND size_t n _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wchar_t dummy; wchar_t dummy;
@ -401,12 +730,11 @@ _DEFUN (__utf8_mbtowc, (r, pwc, s, n, charset, state),
because the underlying OS requires wchar_t == UTF-16. */ because the underlying OS requires wchar_t == UTF-16. */
#ifndef __CYGWIN__ #ifndef __CYGWIN__
int int
_DEFUN (__sjis_mbtowc, (r, pwc, s, n, charset, state), _DEFUN (__sjis_mbtowc, (r, pwc, s, n, state),
struct _reent *r _AND struct _reent *r _AND
wchar_t *pwc _AND wchar_t *pwc _AND
const char *s _AND const char *s _AND
size_t n _AND size_t n _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wchar_t dummy; wchar_t dummy;
@ -459,12 +787,11 @@ _DEFUN (__sjis_mbtowc, (r, pwc, s, n, charset, state),
} }
int int
_DEFUN (__eucjp_mbtowc, (r, pwc, s, n, charset, state), _DEFUN (__eucjp_mbtowc, (r, pwc, s, n, state),
struct _reent *r _AND struct _reent *r _AND
wchar_t *pwc _AND wchar_t *pwc _AND
const char *s _AND const char *s _AND
size_t n _AND size_t n _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wchar_t dummy; wchar_t dummy;
@ -543,12 +870,11 @@ _DEFUN (__eucjp_mbtowc, (r, pwc, s, n, charset, state),
} }
int int
_DEFUN (__jis_mbtowc, (r, pwc, s, n, charset, state), _DEFUN (__jis_mbtowc, (r, pwc, s, n, state),
struct _reent *r _AND struct _reent *r _AND
wchar_t *pwc _AND wchar_t *pwc _AND
const char *s _AND const char *s _AND
size_t n _AND size_t n _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wchar_t dummy; wchar_t dummy;

View File

@ -2,8 +2,6 @@
#include <wchar.h> #include <wchar.h>
#ifdef _MB_CAPABLE #ifdef _MB_CAPABLE
extern char *__locale_charset ();
#ifdef _MB_EXTENDED_CHARSETS_ISO #ifdef _MB_EXTENDED_CHARSETS_ISO
/* Tables for the ISO-8859-x to UTF conversion. The first index into the /* Tables for the ISO-8859-x to UTF conversion. The first index into the
table is a value computed from the value x (function __iso_8859_index), table is a value computed from the value x (function __iso_8859_index),
@ -674,26 +672,31 @@ __micro_atoi (const char *s)
#ifdef _MB_EXTENDED_CHARSETS_ISO #ifdef _MB_EXTENDED_CHARSETS_ISO
int int
__iso_8859_index (const char *charset_ext) __iso_8859_val_index (int val)
{ {
int iso_idx = __micro_atoi (charset_ext); if (val >= 2 && val <= 16)
if (iso_idx >= 2 && iso_idx <= 16)
{ {
iso_idx -= 2; val -= 2;
if (iso_idx > 10) if (val > 10)
--iso_idx; --val;
return iso_idx; return (int) val;
} }
return -1; return -1;
} }
int
__iso_8859_index (const char *charset_ext)
{
return __iso_8859_val_index (__micro_atoi (charset_ext));
}
#endif /* _MB_EXTENDED_CHARSETS_ISO */ #endif /* _MB_EXTENDED_CHARSETS_ISO */
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
int int
__cp_index (const char *charset_ext) __cp_val_index (int val)
{ {
int cp_idx = __micro_atoi (charset_ext); int cp_idx;
switch (cp_idx) switch (val)
{ {
case 437: case 437:
cp_idx = 0; cp_idx = 0;
@ -779,5 +782,12 @@ __cp_index (const char *charset_ext)
} }
return cp_idx; return cp_idx;
} }
int
__cp_index (const char *charset_ext)
{
int cp_idx = __cp_val_index (__micro_atoi (charset_ext));
}
#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */ #endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
#endif /* _MB_CAPABLE */ #endif /* _MB_CAPABLE */

View File

@ -25,9 +25,9 @@ _DEFUN (_wcrtomb_r, (ptr, s, wc, ps),
#endif #endif
if (s == NULL) if (s == NULL)
retval = __wctomb (ptr, buf, L'\0', __locale_charset (), ps); retval = __WCTOMB (ptr, buf, L'\0', ps);
else else
retval = __wctomb (ptr, s, wc, __locale_charset (), ps); retval = __WCTOMB (ptr, s, wc, ps);
if (retval == -1) if (retval == -1)
{ {
@ -62,9 +62,9 @@ _DEFUN (wcrtomb, (s, wc, ps),
#endif #endif
if (s == NULL) if (s == NULL)
retval = __wctomb (reent, buf, L'\0', __locale_charset (), ps); retval = __WCTOMB (reent, buf, L'\0', ps);
else else
retval = __wctomb (reent, s, wc, __locale_charset (), ps); retval = __WCTOMB (reent, s, wc, ps);
if (retval == -1) if (retval == -1)
{ {

View File

@ -138,7 +138,7 @@ _DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps),
{ {
int count = ps->__count; int count = ps->__count;
wint_t wch = ps->__value.__wch; wint_t wch = ps->__value.__wch;
int bytes = __wctomb (r, buff, *pwcs, __locale_charset (), ps); int bytes = __WCTOMB (r, buff, *pwcs, ps);
if (bytes == -1) if (bytes == -1)
{ {
r->_errno = EILSEQ; r->_errno = EILSEQ;
@ -164,7 +164,7 @@ _DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps),
} }
else else
{ {
/* not enough room, we must back up state to before __wctomb call */ /* not enough room, we must back up state to before __WCTOMB call */
ps->__count = count; ps->__count = count;
ps->__value.__wch = wch; ps->__value.__wch = wch;
len = 0; len = 0;

View File

@ -20,7 +20,7 @@ _DEFUN (_wcstombs_r, (reent, s, pwcs, n, state),
size_t num_bytes = 0; size_t num_bytes = 0;
while (*pwcs != 0) while (*pwcs != 0)
{ {
bytes = __wctomb (r, buff, *pwcs++, __locale_charset (), state); bytes = __WCTOMB (r, buff, *pwcs++, state);
if (bytes == -1) if (bytes == -1)
return -1; return -1;
num_bytes += bytes; num_bytes += bytes;
@ -31,7 +31,7 @@ _DEFUN (_wcstombs_r, (reent, s, pwcs, n, state),
{ {
while (n > 0) while (n > 0)
{ {
bytes = __wctomb (r, buff, *pwcs, __locale_charset (), state); bytes = __WCTOMB (r, buff, *pwcs, state);
if (bytes == -1) if (bytes == -1)
return -1; return -1;
num_to_copy = (n > bytes ? bytes : (int)n); num_to_copy = (n > bytes ? bytes : (int)n);

View File

@ -21,6 +21,5 @@ wctob (wint_t wc)
reent = _REENT; reent = _REENT;
_REENT_CHECK_MISC(reent); _REENT_CHECK_MISC(reent);
return __wctomb (reent, (char *) pmb, wc, __locale_charset (), &mbs) == 1 return __WCTOMB (reent, (char *) pmb, wc, &mbs) == 1 ? (int) pmb[0] : EOF;
? (int) pmb[0] : EOF;
} }

View File

@ -61,8 +61,7 @@ _DEFUN (wctomb, (s, wchar),
_REENT_CHECK_MISC(reent); _REENT_CHECK_MISC(reent);
return __wctomb (reent, s, wchar, __locale_charset (), return __WCTOMB (reent, s, wchar, &(_REENT_WCTOMB_STATE(reent)));
&(_REENT_WCTOMB_STATE(reent)));
#else /* not _MB_CAPABLE */ #else /* not _MB_CAPABLE */
if (s == NULL) if (s == NULL)
return 0; return 0;

View File

@ -6,15 +6,6 @@
#include "mbctype.h" #include "mbctype.h"
#include "local.h" #include "local.h"
int (*__wctomb) (struct _reent *, char *, wchar_t, const char *charset,
mbstate_t *)
#ifdef __CYGWIN__
/* Cygwin starts up in UTF-8 mode. */
= __utf8_wctomb;
#else
= __ascii_wctomb;
#endif
int int
_DEFUN (_wctomb_r, (r, s, wchar, state), _DEFUN (_wctomb_r, (r, s, wchar, state),
struct _reent *r _AND struct _reent *r _AND
@ -22,15 +13,14 @@ _DEFUN (_wctomb_r, (r, s, wchar, state),
wchar_t _wchar _AND wchar_t _wchar _AND
mbstate_t *state) mbstate_t *state)
{ {
return __wctomb (r, s, _wchar, __locale_charset (), state); return __WCTOMB (r, s, _wchar, state);
} }
int int
_DEFUN (__ascii_wctomb, (r, s, wchar, charset, state), _DEFUN (__ascii_wctomb, (r, s, wchar, state),
struct _reent *r _AND struct _reent *r _AND
char *s _AND char *s _AND
wchar_t _wchar _AND wchar_t _wchar _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
/* Avoids compiler warnings about comparisons that are always false /* Avoids compiler warnings about comparisons that are always false
@ -60,11 +50,10 @@ _DEFUN (__ascii_wctomb, (r, s, wchar, charset, state),
#define __state __count #define __state __count
int int
_DEFUN (__utf8_wctomb, (r, s, wchar, charset, state), _DEFUN (__utf8_wctomb, (r, s, wchar, state),
struct _reent *r _AND struct _reent *r _AND
char *s _AND char *s _AND
wchar_t _wchar _AND wchar_t _wchar _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wint_t wchar = _wchar; wint_t wchar = _wchar;
@ -155,11 +144,10 @@ _DEFUN (__utf8_wctomb, (r, s, wchar, charset, state),
because the underlying OS requires wchar_t == UTF-16. */ because the underlying OS requires wchar_t == UTF-16. */
#ifndef __CYGWIN__ #ifndef __CYGWIN__
int int
_DEFUN (__sjis_wctomb, (r, s, wchar, charset, state), _DEFUN (__sjis_wctomb, (r, s, wchar, state),
struct _reent *r _AND struct _reent *r _AND
char *s _AND char *s _AND
wchar_t _wchar _AND wchar_t _wchar _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wint_t wchar = _wchar; wint_t wchar = _wchar;
@ -190,11 +178,10 @@ _DEFUN (__sjis_wctomb, (r, s, wchar, charset, state),
} }
int int
_DEFUN (__eucjp_wctomb, (r, s, wchar, charset, state), _DEFUN (__eucjp_wctomb, (r, s, wchar, state),
struct _reent *r _AND struct _reent *r _AND
char *s _AND char *s _AND
wchar_t _wchar _AND wchar_t _wchar _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wint_t wchar = _wchar; wint_t wchar = _wchar;
@ -231,11 +218,10 @@ _DEFUN (__eucjp_wctomb, (r, s, wchar, charset, state),
} }
int int
_DEFUN (__jis_wctomb, (r, s, wchar, charset, state), _DEFUN (__jis_wctomb, (r, s, wchar, state),
struct _reent *r _AND struct _reent *r _AND
char *s _AND char *s _AND
wchar_t _wchar _AND wchar_t _wchar _AND
const char *charset _AND
mbstate_t *state) mbstate_t *state)
{ {
wint_t wchar = _wchar; wint_t wchar = _wchar;
@ -282,13 +268,9 @@ _DEFUN (__jis_wctomb, (r, s, wchar, charset, state),
#endif /* !__CYGWIN__ */ #endif /* !__CYGWIN__ */
#ifdef _MB_EXTENDED_CHARSETS_ISO #ifdef _MB_EXTENDED_CHARSETS_ISO
int static int
_DEFUN (__iso_wctomb, (r, s, wchar, charset, state), ___iso_wctomb (struct _reent *r, char *s, wchar_t _wchar, int iso_idx,
struct _reent *r _AND mbstate_t *state)
char *s _AND
wchar_t _wchar _AND
const char *charset _AND
mbstate_t *state)
{ {
wint_t wchar = _wchar; wint_t wchar = _wchar;
@ -298,7 +280,6 @@ _DEFUN (__iso_wctomb, (r, s, wchar, charset, state),
/* wchars <= 0x9f translate to all ISO charsets directly. */ /* wchars <= 0x9f translate to all ISO charsets directly. */
if (wchar >= 0xa0) if (wchar >= 0xa0)
{ {
int iso_idx = __iso_8859_index (charset + 9);
if (iso_idx >= 0) if (iso_idx >= 0)
{ {
unsigned char mb; unsigned char mb;
@ -326,16 +307,130 @@ _DEFUN (__iso_wctomb, (r, s, wchar, charset, state),
*s = (char) wchar; *s = (char) wchar;
return 1; return 1;
} }
int __iso_8859_1_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, -1, state);
}
int __iso_8859_2_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 0, state);
}
int __iso_8859_3_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 1, state);
}
int __iso_8859_4_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 2, state);
}
int __iso_8859_5_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 3, state);
}
int __iso_8859_6_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 4, state);
}
int __iso_8859_7_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 5, state);
}
int __iso_8859_8_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 6, state);
}
int __iso_8859_9_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 7, state);
}
int __iso_8859_10_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 8, state);
}
int __iso_8859_11_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 9, state);
}
int __iso_8859_13_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 10, state);
}
int __iso_8859_14_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 11, state);
}
int __iso_8859_15_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 12, state);
}
int __iso_8859_16_wctomb (struct _reent *r, char *s, wchar_t _wchar,
mbstate_t *state)
{
return ___iso_wctomb (r, s, _wchar, 13, state);
}
static wctomb_p __iso_8859_wctomb[17] = {
NULL,
__iso_8859_1_wctomb,
__iso_8859_2_wctomb,
__iso_8859_3_wctomb,
__iso_8859_4_wctomb,
__iso_8859_5_wctomb,
__iso_8859_6_wctomb,
__iso_8859_7_wctomb,
__iso_8859_8_wctomb,
__iso_8859_9_wctomb,
__iso_8859_10_wctomb,
__iso_8859_11_wctomb,
NULL, /* No ISO 8859-12 */
__iso_8859_13_wctomb,
__iso_8859_14_wctomb,
__iso_8859_15_wctomb,
__iso_8859_16_wctomb
};
/* val *MUST* be valid! All checks for validity are supposed to be
performed before calling this function. */
wctomb_p
__iso_wctomb (int val)
{
return __iso_8859_wctomb[val];
}
#endif /* _MB_EXTENDED_CHARSETS_ISO */ #endif /* _MB_EXTENDED_CHARSETS_ISO */
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
int static int
_DEFUN (__cp_wctomb, (r, s, wchar, charset, state), ___cp_wctomb (struct _reent *r, char *s, wchar_t _wchar, int cp_idx,
struct _reent *r _AND mbstate_t *state)
char *s _AND
wchar_t _wchar _AND
const char *charset _AND
mbstate_t *state)
{ {
wint_t wchar = _wchar; wint_t wchar = _wchar;
@ -344,7 +439,6 @@ _DEFUN (__cp_wctomb, (r, s, wchar, charset, state),
if (wchar >= 0x80) if (wchar >= 0x80)
{ {
int cp_idx = __cp_index (charset + 2);
if (cp_idx >= 0) if (cp_idx >= 0)
{ {
unsigned char mb; unsigned char mb;
@ -372,5 +466,198 @@ _DEFUN (__cp_wctomb, (r, s, wchar, charset, state),
*s = (char) wchar; *s = (char) wchar;
return 1; return 1;
} }
static int
__cp_437_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 0, state);
}
static int
__cp_720_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 1, state);
}
static int
__cp_737_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 2, state);
}
static int
__cp_775_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 3, state);
}
static int
__cp_850_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 4, state);
}
static int
__cp_852_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 5, state);
}
static int
__cp_855_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 6, state);
}
static int
__cp_857_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 7, state);
}
static int
__cp_858_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 8, state);
}
static int
__cp_862_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 9, state);
}
static int
__cp_866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 10, state);
}
static int
__cp_874_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 11, state);
}
static int
__cp_1125_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 12, state);
}
static int
__cp_1250_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 13, state);
}
static int
__cp_1251_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 14, state);
}
static int
__cp_1252_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 15, state);
}
static int
__cp_1253_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 16, state);
}
static int
__cp_1254_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 17, state);
}
static int
__cp_1255_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 18, state);
}
static int
__cp_1256_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 19, state);
}
static int
__cp_1257_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 20, state);
}
static int
__cp_1258_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 21, state);
}
static int
__cp_20866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 22, state);
}
static int
__cp_21866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 23, state);
}
static int
__cp_101_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 24, state);
}
static int
__cp_102_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
{
return ___cp_wctomb (r, s, _wchar, 25, state);
}
static wctomb_p __cp_xxx_wctomb[26] = {
__cp_437_wctomb,
__cp_720_wctomb,
__cp_737_wctomb,
__cp_775_wctomb,
__cp_850_wctomb,
__cp_852_wctomb,
__cp_855_wctomb,
__cp_857_wctomb,
__cp_858_wctomb,
__cp_862_wctomb,
__cp_866_wctomb,
__cp_874_wctomb,
__cp_1125_wctomb,
__cp_1250_wctomb,
__cp_1251_wctomb,
__cp_1252_wctomb,
__cp_1253_wctomb,
__cp_1254_wctomb,
__cp_1255_wctomb,
__cp_1256_wctomb,
__cp_1257_wctomb,
__cp_1258_wctomb,
__cp_20866_wctomb,
__cp_21866_wctomb,
__cp_101_wctomb,
__cp_102_wctomb
};
/* val *MUST* be valid! All checks for validity are supposed to be
performed before calling this function. */
wctomb_p
__cp_wctomb (int val)
{
return __cp_xxx_wctomb[__cp_val_index (val)];
}
#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */ #endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
#endif /* _MB_CAPABLE */ #endif /* _MB_CAPABLE */

View File

@ -68,7 +68,7 @@ is_leap_year (int year)
/* Needed for strptime. */ /* Needed for strptime. */
static int static int
match_string (const char *__restrict *buf, const char **strs) match_string (const char *__restrict *buf, const char * const*strs)
{ {
int i = 0; int i = 0;

View File

@ -28,7 +28,7 @@
static mini_cygheap NO_COPY cygheap_dummy = static mini_cygheap NO_COPY cygheap_dummy =
{ {
{__utf8_mbtowc, __utf8_wctomb} {__utf8_mbtowc}
}; };
init_cygheap NO_COPY *cygheap = (init_cygheap *) &cygheap_dummy; init_cygheap NO_COPY *cygheap = (init_cygheap *) &cygheap_dummy;
@ -245,8 +245,6 @@ cygheap_init ()
cygheap->bucket_val[b] = sz[b & 1]; cygheap->bucket_val[b] = sz[b & 1];
/* Default locale settings. */ /* Default locale settings. */
cygheap->locale.mbtowc = __utf8_mbtowc; cygheap->locale.mbtowc = __utf8_mbtowc;
cygheap->locale.wctomb = __utf8_wctomb;
strcpy (cygheap->locale.charset, "UTF-8");
/* Set umask to a sane default. */ /* Set umask to a sane default. */
cygheap->umask = 022; cygheap->umask = 022;
cygheap->rlim_core = RLIM_INFINITY; cygheap->rlim_core = RLIM_INFINITY;

View File

@ -346,8 +346,6 @@ struct cygheap_debug
struct cygheap_locale struct cygheap_locale
{ {
mbtowc_p mbtowc; mbtowc_p mbtowc;
wctomb_p wctomb;
char charset[ENCODING_LEN + 1];
}; };
struct user_heap_info struct user_heap_info

View File

@ -1355,7 +1355,7 @@ class dev_console
inline UINT get_console_cp (); inline UINT get_console_cp ();
DWORD con_to_str (char *d, int dlen, WCHAR w); DWORD con_to_str (char *d, int dlen, WCHAR w);
DWORD str_to_con (mbtowc_p, const char *, PWCHAR d, const char *s, DWORD sz); DWORD str_to_con (mbtowc_p, PWCHAR d, const char *s, DWORD sz);
void set_color (HANDLE); void set_color (HANDLE);
void set_default_attr (); void set_default_attr ();
int set_cl_x (cltype); int set_cl_x (cltype);

View File

@ -225,10 +225,9 @@ dev_console::get_console_cp ()
} }
inline DWORD inline DWORD
dev_console::str_to_con (mbtowc_p f_mbtowc, const char *charset, dev_console::str_to_con (mbtowc_p f_mbtowc, PWCHAR d, const char *s, DWORD sz)
PWCHAR d, const char *s, DWORD sz)
{ {
return sys_cp_mbstowcs (f_mbtowc, charset, d, CONVERT_LIMIT, s, sz); return sys_cp_mbstowcs (f_mbtowc, d, CONVERT_LIMIT, s, sz);
} }
bool bool
@ -2002,21 +2001,10 @@ fhandler_console::write_normal (const unsigned char *src,
const unsigned char *found = src; const unsigned char *found = src;
size_t ret; size_t ret;
mbstate_t ps; mbstate_t ps;
UINT cp = con.get_console_cp ();
const char *charset;
mbtowc_p f_mbtowc; mbtowc_p f_mbtowc;
if (cp) /* The alternate charset is always 437, just as in the Linux console. */
{ f_mbtowc = con.get_console_cp () ? __cp_mbtowc (437) : __MBTOWC;
/* The alternate charset is always 437, just as in the Linux console. */
f_mbtowc = __cp_mbtowc;
charset = "CP437";
}
else
{
f_mbtowc = cygheap->locale.mbtowc;
charset = cygheap->locale.charset;
}
/* First check if we have cached lead bytes of a former try to write /* First check if we have cached lead bytes of a former try to write
a truncated multibyte sequence. If so, process it. */ a truncated multibyte sequence. If so, process it. */
@ -2027,7 +2015,7 @@ fhandler_console::write_normal (const unsigned char *src,
memcpy (trunc_buf.buf + trunc_buf.len, src, cp_len); memcpy (trunc_buf.buf + trunc_buf.len, src, cp_len);
memset (&ps, 0, sizeof ps); memset (&ps, 0, sizeof ps);
switch (ret = f_mbtowc (_REENT, NULL, (const char *) trunc_buf.buf, switch (ret = f_mbtowc (_REENT, NULL, (const char *) trunc_buf.buf,
trunc_buf.len + cp_len, charset, &ps)) trunc_buf.len + cp_len, &ps))
{ {
case -2: case -2:
/* Still truncated multibyte sequence? Keep in trunc_buf. */ /* Still truncated multibyte sequence? Keep in trunc_buf. */
@ -2052,9 +2040,9 @@ fhandler_console::write_normal (const unsigned char *src,
/* Valid multibyte sequence? Process. */ /* Valid multibyte sequence? Process. */
if (nfound) if (nfound)
{ {
buf_len = con.str_to_con (f_mbtowc, charset, write_buf, buf_len = con.str_to_con (f_mbtowc, write_buf,
(const char *) trunc_buf.buf, (const char *) trunc_buf.buf,
nfound - trunc_buf.buf); nfound - trunc_buf.buf);
if (!write_console (write_buf, buf_len, done)) if (!write_console (write_buf, buf_len, done))
{ {
debug_printf ("multibyte sequence write failed, handle %p", get_output_handle ()); debug_printf ("multibyte sequence write failed, handle %p", get_output_handle ());
@ -2075,7 +2063,7 @@ fhandler_console::write_normal (const unsigned char *src,
&& base_chars[*found] == NOR) && base_chars[*found] == NOR)
{ {
switch (ret = f_mbtowc (_REENT, NULL, (const char *) found, switch (ret = f_mbtowc (_REENT, NULL, (const char *) found,
end - found, charset, &ps)) end - found, &ps))
{ {
case -2: /* Truncated multibyte sequence. Store for next write. */ case -2: /* Truncated multibyte sequence. Store for next write. */
trunc_buf.len = end - found; trunc_buf.len = end - found;
@ -2098,8 +2086,7 @@ do_print:
if (found != src) if (found != src)
{ {
DWORD len = found - src; DWORD len = found - src;
buf_len = con.str_to_con (f_mbtowc, charset, write_buf, buf_len = con.str_to_con (f_mbtowc, write_buf, (const char *) src, len);
(const char *) src, len);
if (!buf_len) if (!buf_len)
{ {
debug_printf ("conversion error, handle %p", debug_printf ("conversion error, handle %p",
@ -2178,7 +2165,7 @@ do_print:
if (found + 1 < end) if (found + 1 < end)
{ {
ret = __utf8_mbtowc (_REENT, NULL, (const char *) found + 1, ret = __utf8_mbtowc (_REENT, NULL, (const char *) found + 1,
end - found - 1, NULL, &ps); end - found - 1, &ps);
if (ret != (size_t) -1) if (ret != (size_t) -1)
while (ret-- > 0) while (ret-- > 0)
{ {

View File

@ -83,6 +83,15 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
cygwin_hmodule = (HMODULE) h; cygwin_hmodule = (HMODULE) h;
dynamically_loaded = (static_load == NULL); dynamically_loaded = (static_load == NULL);
/* Starting with adding the POSIX-1.2008 per-thread locale functionality,
we need an initalized _REENT area even for the functions called from
dll_crt0_0. In fact, we only need the _REENT->_locale pointer
initialized to NULL, so subsequent calls to locale-specific functions
will always fall back to __global_locale, rather then crash due to
_REENT->_locale having an arbitrary value. */
(void) alloca (CYGTLS_PADSIZE);
_REENT->_locale = NULL;
dll_crt0_0 (); dll_crt0_0 ();
_my_oldfunc = TlsAlloc (); _my_oldfunc = TlsAlloc ();
dll_finished_loading = true; dll_finished_loading = true;

View File

@ -16,8 +16,6 @@ details. */
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include "tls_pbuf.h" #include "tls_pbuf.h"
/* Internal headers from newlib */
#include "../locale/setlocale.h"
#include "lc_msg.h" #include "lc_msg.h"
#include "lc_era.h" #include "lc_era.h"
@ -31,8 +29,7 @@ details. */
__eval_datetimefmt(lcid,(type),(flags),&lc_time_ptr,\ __eval_datetimefmt(lcid,(type),(flags),&lc_time_ptr,\
lc_time_end-lc_time_ptr) lc_time_end-lc_time_ptr)
#define charfromwchar(category,in) \ #define charfromwchar(category,in) \
__charfromwchar (_##category##_locale->in,_LC(category),\ __charfromwchar (_##category##_locale->in,_LC(category),f_wctomb)
f_wctomb,charset)
#define has_modifier(x) ((x)[0] && !strcmp (modifier, (x))) #define has_modifier(x) ((x)[0] && !strcmp (modifier, (x)))
@ -159,8 +156,7 @@ __get_lcid_from_locale (const char *name)
is set, s==NULL returns -1 since then it's used to recognize invalid strings is set, s==NULL returns -1 since then it's used to recognize invalid strings
in the used charset. */ in the used charset. */
static size_t static size_t
lc_wcstombs (wctomb_p f_wctomb, const char *charset, lc_wcstombs (wctomb_p f_wctomb, char *s, const wchar_t *pwcs, size_t n,
char *s, const wchar_t *pwcs, size_t n,
bool return_invalid = false) bool return_invalid = false)
{ {
char *ptr = s; char *ptr = s;
@ -175,7 +171,7 @@ lc_wcstombs (wctomb_p f_wctomb, const char *charset,
size_t num_bytes = 0; size_t num_bytes = 0;
while (*pwcs != 0) while (*pwcs != 0)
{ {
bytes = f_wctomb (_REENT, buf, *pwcs++, charset, &state); bytes = f_wctomb (_REENT, buf, *pwcs++, &state);
if (bytes != (size_t) -1) if (bytes != (size_t) -1)
num_bytes += bytes; num_bytes += bytes;
else if (return_invalid) else if (return_invalid)
@ -185,7 +181,7 @@ lc_wcstombs (wctomb_p f_wctomb, const char *charset,
} }
while (n > 0) while (n > 0)
{ {
bytes = f_wctomb (_REENT, buf, *pwcs, charset, &state); bytes = f_wctomb (_REENT, buf, *pwcs, &state);
if (bytes == (size_t) -1) if (bytes == (size_t) -1)
{ {
memset (&state, 0, sizeof state); memset (&state, 0, sizeof state);
@ -207,8 +203,7 @@ lc_wcstombs (wctomb_p f_wctomb, const char *charset,
/* Never returns -1. Invalid sequences are translated to replacement /* Never returns -1. Invalid sequences are translated to replacement
wide-chars. */ wide-chars. */
static size_t static size_t
lc_mbstowcs (mbtowc_p f_mbtowc, const char *charset, lc_mbstowcs (mbtowc_p f_mbtowc, wchar_t *pwcs, const char *s, size_t n)
wchar_t *pwcs, const char *s, size_t n)
{ {
size_t ret = 0; size_t ret = 0;
char *t = (char *) s; char *t = (char *) s;
@ -220,8 +215,7 @@ lc_mbstowcs (mbtowc_p f_mbtowc, const char *charset,
n = 1; n = 1;
while (n > 0) while (n > 0)
{ {
bytes = f_mbtowc (_REENT, pwcs, t, 6 /* fake, always enough */, bytes = f_mbtowc (_REENT, pwcs, t, 6 /* fake, always enough */, &state);
charset, &state);
if (bytes == (size_t) -1) if (bytes == (size_t) -1)
{ {
state.__count = 0; state.__count = 0;
@ -294,13 +288,12 @@ __setlocaleinfo (char **ptr, size_t size, wchar_t val)
} }
static char * static char *
__charfromwchar (const wchar_t *in, char **ptr, size_t size, __charfromwchar (const wchar_t *in, char **ptr, size_t size, wctomb_p f_wctomb)
wctomb_p f_wctomb, const char *charset)
{ {
size_t num; size_t num;
char *ret; char *ret;
num = lc_wcstombs (f_wctomb, charset, ret = *ptr, in, size); num = lc_wcstombs (f_wctomb, ret = *ptr, in, size);
*ptr += num + 1; *ptr += num + 1;
return ret; return ret;
} }
@ -600,11 +593,11 @@ __set_lc_time_from_win (const char *name,
/* Evaluate string length in target charset. Characters invalid in the /* Evaluate string length in target charset. Characters invalid in the
target charset are simply ignored, as on Linux. */ target charset are simply ignored, as on Linux. */
len = 0; len = 0;
len += lc_wcstombs (f_wctomb, charset, NULL, era->era, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, era->era, 0) + 1;
len += lc_wcstombs (f_wctomb, charset, NULL, era->era_d_fmt, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, era->era_d_fmt, 0) + 1;
len += lc_wcstombs (f_wctomb, charset, NULL, era->era_d_t_fmt, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, era->era_d_t_fmt, 0) + 1;
len += lc_wcstombs (f_wctomb, charset, NULL, era->era_t_fmt, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, era->era_t_fmt, 0) + 1;
len += lc_wcstombs (f_wctomb, charset, NULL, era->alt_digits, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, era->alt_digits, 0) + 1;
len += (wcslen (era->era) + 1) * sizeof (wchar_t); len += (wcslen (era->era) + 1) * sizeof (wchar_t);
len += (wcslen (era->era_d_fmt) + 1) * sizeof (wchar_t); len += (wcslen (era->era_d_fmt) + 1) * sizeof (wchar_t);
len += (wcslen (era->era_d_t_fmt) + 1) * sizeof (wchar_t); len += (wcslen (era->era_d_t_fmt) + 1) * sizeof (wchar_t);
@ -742,8 +735,7 @@ __set_lc_ctype_from_win (const char *name,
lc_ctype_ptr = (char *) woutdig; lc_ctype_ptr = (char *) woutdig;
_ctype_locale->outdigits[i] = lc_ctype_ptr; _ctype_locale->outdigits[i] = lc_ctype_ptr;
memset (&state, 0, sizeof state); memset (&state, 0, sizeof state);
lc_ctype_ptr += f_wctomb (_REENT, lc_ctype_ptr, digits[i], charset, lc_ctype_ptr += f_wctomb (_REENT, lc_ctype_ptr, digits[i], &state);
&state);
*lc_ctype_ptr++ = '\0'; *lc_ctype_ptr++ = '\0';
} }
} }
@ -885,8 +877,7 @@ __set_lc_monetary_from_win (const char *name,
LOCALE_SCURRENCY); LOCALE_SCURRENCY);
/* As on Linux: If the currency_symbol can't be represented in the /* As on Linux: If the currency_symbol can't be represented in the
given charset, use int_curr_symbol. */ given charset, use int_curr_symbol. */
if (lc_wcstombs (f_wctomb, charset, NULL, if (lc_wcstombs (f_wctomb, NULL, _monetary_locale->wcurrency_symbol,
_monetary_locale->wcurrency_symbol,
0, true) == (size_t) -1) 0, true) == (size_t) -1)
_monetary_locale->currency_symbol = _monetary_locale->int_curr_symbol; _monetary_locale->currency_symbol = _monetary_locale->int_curr_symbol;
else else
@ -1026,10 +1017,10 @@ __set_lc_messages_from_win (const char *name,
len += (strlen (charset) + 1); len += (strlen (charset) + 1);
if (lcid) if (lcid)
{ {
len += lc_wcstombs (f_wctomb, charset, NULL, msg->yesexpr, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, msg->yesexpr, 0) + 1;
len += lc_wcstombs (f_wctomb, charset, NULL, msg->noexpr, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, msg->noexpr, 0) + 1;
len += lc_wcstombs (f_wctomb, charset, NULL, msg->yesstr, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, msg->yesstr, 0) + 1;
len += lc_wcstombs (f_wctomb, charset, NULL, msg->nostr, 0) + 1; len += lc_wcstombs (f_wctomb, NULL, msg->nostr, 0) + 1;
len += (wcslen (msg->yesexpr) + 1) * sizeof (wchar_t); len += (wcslen (msg->yesexpr) + 1) * sizeof (wchar_t);
len += (wcslen (msg->noexpr) + 1) * sizeof (wchar_t); len += (wcslen (msg->noexpr) + 1) * sizeof (wchar_t);
len += (wcslen (msg->yesstr) + 1) * sizeof (wchar_t); len += (wcslen (msg->yesstr) + 1) * sizeof (wchar_t);
@ -1051,13 +1042,13 @@ __set_lc_messages_from_win (const char *name,
if (lcid) if (lcid)
{ {
_messages_locale->yesexpr = (const char *) c; _messages_locale->yesexpr = (const char *) c;
len = lc_wcstombs (f_wctomb, charset, c, msg->yesexpr, lc_messages_end - c); len = lc_wcstombs (f_wctomb, c, msg->yesexpr, lc_messages_end - c);
_messages_locale->noexpr = (const char *) (c += len + 1); _messages_locale->noexpr = (const char *) (c += len + 1);
len = lc_wcstombs (f_wctomb, charset, c, msg->noexpr, lc_messages_end - c); len = lc_wcstombs (f_wctomb, c, msg->noexpr, lc_messages_end - c);
_messages_locale->yesstr = (const char *) (c += len + 1); _messages_locale->yesstr = (const char *) (c += len + 1);
len = lc_wcstombs (f_wctomb, charset, c, msg->yesstr, lc_messages_end - c); len = lc_wcstombs (f_wctomb, c, msg->yesstr, lc_messages_end - c);
_messages_locale->nostr = (const char *) (c += len + 1); _messages_locale->nostr = (const char *) (c += len + 1);
len = lc_wcstombs (f_wctomb, charset, c, msg->nostr, lc_messages_end - c); len = lc_wcstombs (f_wctomb, c, msg->nostr, lc_messages_end - c);
c += len + 1; c += len + 1;
if ((uintptr_t) c % 1) if ((uintptr_t) c % 1)
++c; ++c;
@ -1149,15 +1140,14 @@ strcoll (const char *__restrict s1, const char *__restrict s2)
/* The ANSI version of CompareString uses the default charset of the lcid, /* The ANSI version of CompareString uses the default charset of the lcid,
so we must use the Unicode version. */ so we must use the Unicode version. */
mbtowc_p collate_mbtowc = __get_current_collate_locale ()->mbtowc; mbtowc_p collate_mbtowc = __get_current_collate_locale ()->mbtowc;
const char *collate_charset = __get_current_collate_locale ()->codeset; n1 = lc_mbstowcs (collate_mbtowc, NULL, s1, 0) + 1;
n1 = lc_mbstowcs (collate_mbtowc, collate_charset, NULL, s1, 0) + 1;
ws1 = (n1 > NT_MAX_PATH ? (wchar_t *) malloc (n1 * sizeof (wchar_t)) ws1 = (n1 > NT_MAX_PATH ? (wchar_t *) malloc (n1 * sizeof (wchar_t))
: tp.w_get ()); : tp.w_get ());
lc_mbstowcs (collate_mbtowc, collate_charset, ws1, s1, n1); lc_mbstowcs (collate_mbtowc, ws1, s1, n1);
n2 = lc_mbstowcs (collate_mbtowc, collate_charset, NULL, s2, 0) + 1; n2 = lc_mbstowcs (collate_mbtowc, NULL, s2, 0) + 1;
ws2 = (n2 > NT_MAX_PATH ? (wchar_t *) malloc (n2 * sizeof (wchar_t)) ws2 = (n2 > NT_MAX_PATH ? (wchar_t *) malloc (n2 * sizeof (wchar_t))
: tp.w_get ()); : tp.w_get ());
lc_mbstowcs (collate_mbtowc, collate_charset, ws2, s2, n2); lc_mbstowcs (collate_mbtowc, ws2, s2, n2);
ret = CompareStringW (collate_lcid, 0, ws1, -1, ws2, -1); ret = CompareStringW (collate_lcid, 0, ws1, -1, ws2, -1);
if (n1 > NT_MAX_PATH) if (n1 > NT_MAX_PATH)
free (ws1); free (ws1);
@ -1226,13 +1216,12 @@ strxfrm (char *__restrict s1, const char *__restrict s2, size_t sn)
/* The ANSI version of LCMapString uses the default charset of the lcid, /* The ANSI version of LCMapString uses the default charset of the lcid,
so we must use the Unicode version. */ so we must use the Unicode version. */
mbtowc_p collate_mbtowc = __get_current_collate_locale ()->mbtowc; mbtowc_p collate_mbtowc = __get_current_collate_locale ()->mbtowc;
const char *collate_charset = __get_current_collate_locale ()->codeset; n2 = lc_mbstowcs (collate_mbtowc, NULL, s2, 0) + 1;
n2 = lc_mbstowcs (collate_mbtowc, collate_charset, NULL, s2, 0) + 1;
ws2 = (n2 > NT_MAX_PATH ? (wchar_t *) malloc (n2 * sizeof (wchar_t)) ws2 = (n2 > NT_MAX_PATH ? (wchar_t *) malloc (n2 * sizeof (wchar_t))
: tp.w_get ()); : tp.w_get ());
if (ws2) if (ws2)
{ {
lc_mbstowcs (collate_mbtowc, collate_charset, ws2, s2, n2); lc_mbstowcs (collate_mbtowc, ws2, s2, n2);
/* The sort key is a NUL-terminated byte string. */ /* The sort key is a NUL-terminated byte string. */
ret = LCMapStringW (collate_lcid, LCMAP_SORTKEY, ws2, -1, ret = LCMapStringW (collate_lcid, LCMAP_SORTKEY, ws2, -1,
(PWCHAR) s1, sn); (PWCHAR) s1, sn);
@ -1474,7 +1463,7 @@ __set_locale_from_locale_alias (const char *locale, char *new_locale)
if (strlen (replace) > ENCODING_LEN) if (strlen (replace) > ENCODING_LEN)
continue; continue;
/* The file is latin1 encoded */ /* The file is latin1 encoded */
lc_mbstowcs (__iso_mbtowc, "ISO-8859-1", walias, alias, ENCODING_LEN + 1); lc_mbstowcs (__iso_mbtowc (1), walias, alias, ENCODING_LEN + 1);
walias[ENCODING_LEN] = L'\0'; walias[ENCODING_LEN] = L'\0';
if (!wcscmp (wlocale, walias)) if (!wcscmp (wlocale, walias))
{ {
@ -1503,33 +1492,25 @@ internal_setlocale ()
wchar_t *w_path = NULL, *w_cwd; wchar_t *w_path = NULL, *w_cwd;
/* Don't do anything if the charset hasn't actually changed. */ /* Don't do anything if the charset hasn't actually changed. */
if (strcmp (cygheap->locale.charset, __locale_charset ()) == 0) if (cygheap->locale.mbtowc == __global_locale.mbtowc)
return; return;
debug_printf ("Cygwin charset changed from %s to %s", debug_printf ("Cygwin charset chang to %s", __locale_charset ());
cygheap->locale.charset, __locale_charset ());
/* Fetch PATH and CWD and convert to wchar_t in previous charset. */ /* Fetch PATH and CWD and convert to wchar_t in previous charset. */
path = getenv ("PATH"); path = getenv ("PATH");
if (path && *path) /* $PATH can be potentially unset. */ if (path && *path) /* $PATH can be potentially unset. */
{ {
w_path = tp.w_get (); w_path = tp.w_get ();
sys_mbstowcs (w_path, 32768, path); sys_cp_mbstowcs (cygheap->locale.mbtowc, w_path, 32768, path);
} }
w_cwd = tp.w_get (); w_cwd = tp.w_get ();
cwdstuff::cwd_lock.acquire (); cwdstuff::cwd_lock.acquire ();
sys_mbstowcs (w_cwd, 32768, cygheap->cwd.get_posix ()); sys_cp_mbstowcs (cygheap->locale.mbtowc, w_cwd, 32768,
cygheap->cwd.get_posix ());
/* Set charset for internal conversion functions. */ /* Set charset for internal conversion functions. */
if (*__locale_charset () == 'A'/*SCII*/) cygheap->locale.mbtowc = __global_locale.mbtowc;
{ if (cygheap->locale.mbtowc == __ascii_mbtowc)
cygheap->locale.mbtowc = __utf8_mbtowc; 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. */ /* Restore CWD and PATH in new charset. */
cygheap->cwd.reset_posix (w_cwd); cygheap->cwd.reset_posix (w_cwd);
cwdstuff::cwd_lock.release (); cwdstuff::cwd_lock.release ();

View File

@ -140,15 +140,13 @@ __db_wctomb (struct _reent *r, char *s, wchar_t wchar, UINT cp)
} }
extern "C" int extern "C" int
__sjis_wctomb (struct _reent *r, char *s, wchar_t wchar, const char *charset, __sjis_wctomb (struct _reent *r, char *s, wchar_t wchar, mbstate_t *state)
mbstate_t *state)
{ {
return __db_wctomb (r,s, wchar, 932); return __db_wctomb (r,s, wchar, 932);
} }
extern "C" int extern "C" int
__eucjp_wctomb (struct _reent *r, char *s, wchar_t wchar, const char *charset, __eucjp_wctomb (struct _reent *r, char *s, wchar_t wchar, mbstate_t *state)
mbstate_t *state)
{ {
/* Unfortunately, the Windows eucJP codepage 20932 is not really 100% /* Unfortunately, the Windows eucJP codepage 20932 is not really 100%
compatible to eucJP. It's a cute approximation which makes it a compatible to eucJP. It's a cute approximation which makes it a
@ -192,22 +190,19 @@ __eucjp_wctomb (struct _reent *r, char *s, wchar_t wchar, const char *charset,
} }
extern "C" int extern "C" int
__gbk_wctomb (struct _reent *r, char *s, wchar_t wchar, const char *charset, __gbk_wctomb (struct _reent *r, char *s, wchar_t wchar, mbstate_t *state)
mbstate_t *state)
{ {
return __db_wctomb (r,s, wchar, 936); return __db_wctomb (r,s, wchar, 936);
} }
extern "C" int extern "C" int
__kr_wctomb (struct _reent *r, char *s, wchar_t wchar, const char *charset, __kr_wctomb (struct _reent *r, char *s, wchar_t wchar, mbstate_t *state)
mbstate_t *state)
{ {
return __db_wctomb (r,s, wchar, 949); return __db_wctomb (r,s, wchar, 949);
} }
extern "C" int extern "C" int
__big5_wctomb (struct _reent *r, char *s, wchar_t wchar, const char *charset, __big5_wctomb (struct _reent *r, char *s, wchar_t wchar, mbstate_t *state)
mbstate_t *state)
{ {
return __db_wctomb (r,s, wchar, 950); return __db_wctomb (r,s, wchar, 950);
} }
@ -268,14 +263,14 @@ __db_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n, UINT cp,
extern "C" int extern "C" int
__sjis_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n, __sjis_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
const char *charset, mbstate_t *state) mbstate_t *state)
{ {
return __db_mbtowc (r, pwc, s, n, 932, state); return __db_mbtowc (r, pwc, s, n, 932, state);
} }
extern "C" int extern "C" int
__eucjp_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n, __eucjp_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
const char *charset, mbstate_t *state) mbstate_t *state)
{ {
/* See comment in __eucjp_wctomb above. */ /* See comment in __eucjp_wctomb above. */
wchar_t dummy; wchar_t dummy;
@ -352,21 +347,21 @@ jis_x_0212:
extern "C" int extern "C" int
__gbk_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n, __gbk_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
const char *charset, mbstate_t *state) mbstate_t *state)
{ {
return __db_mbtowc (r, pwc, s, n, 936, state); return __db_mbtowc (r, pwc, s, n, 936, state);
} }
extern "C" int extern "C" int
__kr_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n, __kr_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
const char *charset, mbstate_t *state) mbstate_t *state)
{ {
return __db_mbtowc (r, pwc, s, n, 949, state); return __db_mbtowc (r, pwc, s, n, 949, state);
} }
extern "C" int extern "C" int
__big5_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n, __big5_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
const char *charset, mbstate_t *state) mbstate_t *state)
{ {
return __db_mbtowc (r, pwc, s, n, 950, state); return __db_mbtowc (r, pwc, s, n, 950, state);
} }
@ -408,7 +403,7 @@ __big5_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
*/ */
static size_t __reg3 static size_t __reg3
sys_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc, sys_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc,
bool is_path) bool is_path)
{ {
char buf[10]; char buf[10];
char *ptr = dst; char *ptr = dst;
@ -416,9 +411,10 @@ sys_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc,
size_t n = 0; size_t n = 0;
mbstate_t ps; mbstate_t ps;
save_errno save; save_errno save;
wctomb_p f_wctomb = cygheap->locale.wctomb; wctomb_p f_wctomb = __WCTOMB;
const char *charset = cygheap->locale.charset;
if (f_wctomb == __ascii_wctomb)
f_wctomb = __utf8_wctomb;
memset (&ps, 0, sizeof ps); memset (&ps, 0, sizeof ps);
if (dst == NULL) if (dst == NULL)
len = (size_t) -1; len = (size_t) -1;
@ -441,13 +437,13 @@ sys_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc,
} }
else else
{ {
bytes = f_wctomb (_REENT, buf, pw, charset, &ps); bytes = f_wctomb (_REENT, buf, pw, &ps);
if (bytes == -1 && *charset != 'U'/*TF-8*/) if (bytes == -1 && f_wctomb != __utf8_wctomb)
{ {
/* Convert chars invalid in the current codepage to a sequence /* Convert chars invalid in the current codepage to a sequence
ASCII CAN; UTF-8 representation of invalid char. */ ASCII CAN; UTF-8 representation of invalid char. */
buf[0] = 0x18; /* ASCII CAN */ buf[0] = 0x18; /* ASCII CAN */
bytes = __utf8_wctomb (_REENT, buf + 1, pw, charset, &ps); bytes = __utf8_wctomb (_REENT, buf + 1, pw, &ps);
if (bytes == -1) if (bytes == -1)
{ {
++pwcs; ++pwcs;
@ -465,8 +461,7 @@ sys_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc,
ps.__count = 0; ps.__count = 0;
continue; continue;
} }
bytes += __utf8_wctomb (_REENT, buf + bytes, *pwcs, charset, bytes += __utf8_wctomb (_REENT, buf + bytes, *pwcs, &ps);
&ps);
nwc--; nwc--;
} }
} }
@ -557,8 +552,8 @@ sys_wcstombs_alloc_no_path (char **dst_p, int type, const wchar_t *src,
charset, which is the charset returned by GetConsoleCP (). Most of the charset, which is the charset returned by GetConsoleCP (). Most of the
time this is used for box and line drawing characters. */ time this is used for box and line drawing characters. */
size_t __reg3 size_t __reg3
sys_cp_mbstowcs (mbtowc_p f_mbtowc, const char *charset, wchar_t *dst, sys_cp_mbstowcs (mbtowc_p f_mbtowc, wchar_t *dst, size_t dlen,
size_t dlen, const char *src, size_t nms) const char *src, size_t nms)
{ {
wchar_t *ptr = dst; wchar_t *ptr = dst;
unsigned const char *pmbs = (unsigned const char *) src; unsigned const char *pmbs = (unsigned const char *) src;
@ -581,10 +576,11 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, const char *charset, wchar_t *dst,
next byte must be a valid UTF-8 start byte. If the charset next byte must be a valid UTF-8 start byte. If the charset
isn't UTF-8 anyway, try to convert the following bytes as UTF-8 isn't UTF-8 anyway, try to convert the following bytes as UTF-8
sequence. */ sequence. */
if (nms > 2 && pmbs[1] >= 0xc2 && pmbs[1] <= 0xf4 && *charset != 'U'/*TF-8*/) if (nms > 2 && pmbs[1] >= 0xc2 && pmbs[1] <= 0xf4
&& f_mbtowc != __utf8_mbtowc)
{ {
bytes = __utf8_mbtowc (_REENT, ptr, (const char *) pmbs + 1, bytes = __utf8_mbtowc (_REENT, ptr, (const char *) pmbs + 1,
nms - 1, charset, &ps); nms - 1, &ps);
if (bytes < 0) if (bytes < 0)
{ {
/* Invalid UTF-8 sequence? Treat the ASCII CAN character as /* Invalid UTF-8 sequence? Treat the ASCII CAN character as
@ -603,7 +599,7 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, const char *charset, wchar_t *dst,
wchar_t *ptr2 = dst ? ptr + 1 : NULL; wchar_t *ptr2 = dst ? ptr + 1 : NULL;
int bytes2 = __utf8_mbtowc (_REENT, ptr2, int bytes2 = __utf8_mbtowc (_REENT, ptr2,
(const char *) pmbs + bytes, (const char *) pmbs + bytes,
nms - bytes, charset, &ps); nms - bytes, &ps);
if (bytes2 < 0) if (bytes2 < 0)
memset (&ps, 0, sizeof ps); memset (&ps, 0, sizeof ps);
else else
@ -625,7 +621,7 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, const char *charset, wchar_t *dst,
} }
} }
else if ((bytes = f_mbtowc (_REENT, ptr, (const char *) pmbs, nms, else if ((bytes = f_mbtowc (_REENT, ptr, (const char *) pmbs, nms,
charset, &ps)) < 0) &ps)) < 0)
{ {
/* The technique is based on a discussion here: /* The technique is based on a discussion here:
http://www.mail-archive.com/linux-utf8@nl.linux.org/msg00080.html http://www.mail-archive.com/linux-utf8@nl.linux.org/msg00080.html
@ -668,8 +664,10 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, const char *charset, wchar_t *dst,
size_t __reg3 size_t __reg3
sys_mbstowcs (wchar_t * dst, size_t dlen, const char *src, size_t nms) sys_mbstowcs (wchar_t * dst, size_t dlen, const char *src, size_t nms)
{ {
return sys_cp_mbstowcs (cygheap->locale.mbtowc, cygheap->locale.charset, mbtowc_p f_mbtowc = __MBTOWC;
dst, dlen, src, nms); if (f_mbtowc == __ascii_mbtowc)
f_mbtowc = __utf8_mbtowc;
return sys_cp_mbstowcs (f_mbtowc, dst, dlen, src, nms);
} }
/* Same as sys_wcstombs_alloc, just backwards. */ /* Same as sys_wcstombs_alloc, just backwards. */

View File

@ -11,6 +11,9 @@ details. */
#include_next <wchar.h> #include_next <wchar.h>
/* Internal headers from newlib */
#include "../locale/setlocale.h"
#define ENCODING_LEN 31 #define ENCODING_LEN 31
#ifdef __cplusplus #ifdef __cplusplus
@ -18,29 +21,23 @@ extern "C" {
#endif #endif
typedef int mbtowc_f (struct _reent *, wchar_t *, const char *, size_t, typedef int mbtowc_f (struct _reent *, wchar_t *, const char *, size_t,
const char *, mbstate_t *); mbstate_t *);
typedef mbtowc_f *mbtowc_p; typedef mbtowc_f *mbtowc_p;
extern mbtowc_p __mbtowc;
extern mbtowc_f __ascii_mbtowc; extern mbtowc_f __ascii_mbtowc;
extern mbtowc_f __utf8_mbtowc; extern mbtowc_f __utf8_mbtowc;
extern mbtowc_f __iso_mbtowc; extern mbtowc_p __iso_mbtowc (int);
extern mbtowc_f __cp_mbtowc; extern mbtowc_p __cp_mbtowc (int);
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 *, #define __MBTOWC (__get_current_locale ()->mbtowc)
mbstate_t *);
typedef int wctomb_f (struct _reent *, char *, wchar_t, mbstate_t *);
typedef wctomb_f *wctomb_p; typedef wctomb_f *wctomb_p;
extern wctomb_p __wctomb;
extern wctomb_f __ascii_wctomb; extern wctomb_f __ascii_wctomb;
extern wctomb_f __utf8_wctomb; extern wctomb_f __utf8_wctomb;
extern char *__locale_charset (); #define __WCTOMB (__get_current_locale ()->wctomb)
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -49,20 +46,21 @@ extern char *__locale_charset ();
#ifdef __INSIDE_CYGWIN__ #ifdef __INSIDE_CYGWIN__
#ifdef __cplusplus #ifdef __cplusplus
size_t __reg3 sys_wcstombs (char *dst, size_t len, const wchar_t * src, size_t __reg3 sys_wcstombs (char *dst, size_t len, const wchar_t * src,
size_t nwc = (size_t) -1); size_t nwc = (size_t) -1);
size_t __reg3 sys_wcstombs_no_path (char *dst, size_t len, size_t __reg3 sys_wcstombs_no_path (char *dst, size_t len,
const wchar_t * src, size_t nwc = (size_t) -1); const wchar_t * src,
size_t nwc = (size_t) -1);
size_t __reg3 sys_wcstombs_alloc (char **, int, const wchar_t *, size_t __reg3 sys_wcstombs_alloc (char **, int, const wchar_t *,
size_t = (size_t) -1); size_t = (size_t) -1);
size_t __reg3 sys_wcstombs_alloc_no_path (char **, int, const wchar_t *, size_t __reg3 sys_wcstombs_alloc_no_path (char **, int, const wchar_t *,
size_t = (size_t) -1); size_t = (size_t) -1);
size_t __reg3 sys_cp_mbstowcs (mbtowc_p, const char *, wchar_t *, size_t, size_t __reg3 sys_cp_mbstowcs (mbtowc_p, wchar_t *, size_t, const char *,
const char *, size_t = (size_t) -1); size_t = (size_t) -1);
size_t __reg3 sys_mbstowcs (wchar_t * dst, size_t dlen, const char *src, size_t __reg3 sys_mbstowcs (wchar_t * dst, size_t dlen, const char *src,
size_t nms = (size_t) -1); size_t nms = (size_t) -1);
size_t __reg3 sys_mbstowcs_alloc (wchar_t **, int, const char *, size_t __reg3 sys_mbstowcs_alloc (wchar_t **, int, const char *,
size_t = (size_t) -1); size_t = (size_t) -1);
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __INSIDE_CYGWIN__ */ #endif /* __INSIDE_CYGWIN__ */