diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2016-07-20 23:05:59 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2016-08-15 11:56:57 +0300 |
commit | d16a56306d63b4d94412b479a8ea83463a3514ab (patch) | |
tree | b37c2954976f314628637e660e039f1be4034b1c /newlib/libc/locale | |
parent | 88208d3735821df0f5a66c5f8781282a7f5bf284 (diff) |
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>
Diffstat (limited to 'newlib/libc/locale')
-rw-r--r-- | newlib/libc/locale/locale.c | 79 | ||||
-rw-r--r-- | newlib/libc/locale/nl_langinfo.c | 2 | ||||
-rw-r--r-- | newlib/libc/locale/setlocale.h | 44 |
3 files changed, 64 insertions, 61 deletions
diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c index eb08dade5..0430f1f53 100644 --- a/newlib/libc/locale/locale.c +++ b/newlib/libc/locale/locale.c @@ -459,12 +459,11 @@ loadlocale(struct _reent *p, int category) dependent on the cateogry. */ char *locale = NULL; char charset[ENCODING_LEN + 1]; - unsigned long val; + long val = 0; char *end, *c = NULL; int mbc_max; - int (*l_wctomb) (struct _reent *, char *, wchar_t, const char *, mbstate_t *); - int (*l_mbtowc) (struct _reent *, wchar_t *, const char *, size_t, - const char *, mbstate_t *); + wctomb_p l_wctomb; + mbtowc_p l_mbtowc; int cjknarrow = 0; /* Avoid doing everything twice if nothing has changed. */ @@ -674,8 +673,8 @@ restart: *c = '\0'; mbc_max = 1; #ifdef _MB_EXTENDED_CHARSETS_ISO - l_wctomb = __iso_wctomb; - l_mbtowc = __iso_mbtowc; + l_wctomb = __iso_wctomb (val); + l_mbtowc = __iso_mbtowc (val); #else /* !_MB_EXTENDED_CHARSETS_ISO */ l_wctomb = __ascii_wctomb; l_mbtowc = __ascii_mbtowc; @@ -715,8 +714,8 @@ restart: case 1258: mbc_max = 1; #ifdef _MB_EXTENDED_CHARSETS_WINDOWS - l_wctomb = __cp_wctomb; - l_mbtowc = __cp_mbtowc; + l_wctomb = __cp_wctomb (val); + l_mbtowc = __cp_mbtowc (val); #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ l_wctomb = __ascii_wctomb; l_mbtowc = __ascii_mbtowc; @@ -740,15 +739,21 @@ restart: if (*c == '-') ++c; if (*c == 'R' || *c == 'r') - strcpy (charset, "CP20866"); + { + val = 20866; + strcpy (charset, "CP20866"); + } else if (*c == 'U' || *c == 'u') - strcpy (charset, "CP21866"); + { + val = 21866; + strcpy (charset, "CP21866"); + } else FAIL; mbc_max = 1; #ifdef _MB_EXTENDED_CHARSETS_WINDOWS - l_wctomb = __cp_wctomb; - l_mbtowc = __cp_mbtowc; + l_wctomb = __cp_wctomb (val); + l_mbtowc = __cp_mbtowc (val); #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ l_wctomb = __ascii_wctomb; l_mbtowc = __ascii_mbtowc; @@ -786,11 +791,12 @@ restart: ++c; if (strcasecmp (c, "PS")) FAIL; + val = 101; strcpy (charset, "CP101"); mbc_max = 1; #ifdef _MB_EXTENDED_CHARSETS_WINDOWS - l_wctomb = __cp_wctomb; - l_mbtowc = __cp_mbtowc; + l_wctomb = __cp_wctomb (val); + l_mbtowc = __cp_mbtowc (val); #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ l_wctomb = __ascii_wctomb; l_mbtowc = __ascii_mbtowc; @@ -804,11 +810,12 @@ restart: /* PT154 */ if (strcasecmp (charset, "PT154")) FAIL; + val = 102; strcpy (charset, "CP102"); mbc_max = 1; #ifdef _MB_EXTENDED_CHARSETS_WINDOWS - l_wctomb = __cp_wctomb; - l_mbtowc = __cp_mbtowc; + l_wctomb = __cp_wctomb (val); + l_mbtowc = __cp_mbtowc (val); #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ l_wctomb = __ascii_wctomb; l_mbtowc = __ascii_mbtowc; @@ -826,8 +833,8 @@ restart: strcpy (charset, "CP874"); mbc_max = 1; #ifdef _MB_EXTENDED_CHARSETS_WINDOWS - l_wctomb = __cp_wctomb; - l_mbtowc = __cp_mbtowc; + l_wctomb = __cp_wctomb (val); + l_mbtowc = __cp_mbtowc (val); #else /* !_MB_EXTENDED_CHARSETS_WINDOWS */ l_wctomb = __ascii_wctomb; l_mbtowc = __ascii_mbtowc; @@ -859,8 +866,8 @@ restart: #ifdef __CYGWIN__ __mb_cur_max = mbc_max; /* Only for backward compat */ #endif - __wctomb = l_wctomb; - __mbtowc = l_mbtowc; + __global_locale.wctomb = l_wctomb; + __global_locale.mbtowc = l_mbtowc; __set_ctype (NULL, charset); /* Determine the width for the "CJK Ambiguous Width" category of 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 */ -char * -_DEFUN_VOID(__locale_charset) -{ -#ifdef __HAVE_LOCALE_INFO__ - return __get_current_ctype_locale ()->codeset; -#else - return __global_locale.ctype_codeset; -#endif -} - int _DEFUN_VOID(__locale_mb_cur_max) { @@ -963,36 +960,16 @@ _DEFUN_VOID(__locale_mb_cur_max) #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__ char * _DEFUN_VOID(__locale_ctype_ptr) { /* 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. */ + extern char *__ctype_ptr__; return __get_locale_r (_REENT) ? __get_locale_r (_REENT)->ctype_ptr : __ctype_ptr__; } - #endif struct lconv * diff --git a/newlib/libc/locale/nl_langinfo.c b/newlib/libc/locale/nl_langinfo.c index ce6d8d8c2..46e8b0e92 100644 --- a/newlib/libc/locale/nl_langinfo.c +++ b/newlib/libc/locale/nl_langinfo.c @@ -172,8 +172,6 @@ static struct _nl_item_t #define _REL(BASE) ((int)item-BASE) -extern char *__locale_charset (); - char * _DEFUN(nl_langinfo, (item), nl_item item) { diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h index ffb1cf13e..50797db0c 100644 --- a/newlib/libc/locale/setlocale.h +++ b/newlib/libc/locale/setlocale.h @@ -159,8 +159,7 @@ typedef __uint32_t LCID; struct lc_collate_T { LCID lcid; - int (*mbtowc) (struct _reent *, wchar_t *, const char *, size_t, const char *, - mbstate_t *); + int (*mbtowc) (struct _reent *, wchar_t *, const char *, size_t, mbstate_t *); char codeset[ENCODING_LEN + 1]; }; 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 { char categories[_LC_LAST][ENCODING_LEN + 1]; - int (*__wctomb) (struct _reent *, char *, wchar_t, - const char *, mbstate_t *); - int (*__mbtowc) (struct _reent *, wchar_t *, - const char *, size_t, const char *, - mbstate_t *); - char *ctype_ptr; /* Unused in __global_locale */ + int (*wctomb) (struct _reent *, char *, wchar_t, + mbstate_t *); + int (*mbtowc) (struct _reent *, wchar_t *, + const char *, size_t, mbstate_t *); int cjk_lang; + char *ctype_ptr; /* Unused in __global_locale */ #ifndef __HAVE_LOCALE_INFO__ char mb_cur_max[2]; char ctype_codeset[ENCODING_LEN + 1]; @@ -264,6 +262,36 @@ __get_current_collate_locale (void) } #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 *, const char *, int); int __monetary_load_locale (struct _thr_locale_t *, const char *, void *, |