diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2010-04-28 13:59:37 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2010-04-28 13:59:37 +0400 |
commit | d47d5b850bed398357e7f05d8fef508be1bb7f51 (patch) | |
tree | 8571d6a5751c102c12b11c58261ee663e83d7fce /newlib/libc/locale/locale.c | |
parent | 9b53b52a80f79a7746f51e2092b23dfab3d50c6f (diff) |
Extend locale support to maintain wide char values of native strings
if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/include/langinfo.h (enum __nl_item): New type. Define all
native values accessible through nl_langinfo. Define previously
existing POSIX-compatible values as macros as well.
* libc/include/stdlib.h (__mb_cur_max): Drop declaration.
(__locale_mb_cur_max): Declare.
(MB_CUR_MAX): Re-define calling __locale_mb_cur_max.
* libc/locale/Makefile.am (ELIX_SOURCES): Add lctype.c.
* libc/locale/Makefile.in: Regenerate.
* libc/locale/lctype.c: New file to define and load LC_CTYPE category.
* libc/locale/lctype.h: New file, matching header.
* libc/locale/lmessages.c (_C_messages_locale): Add default values for
wide char members.
(__messages_load_locale): Add _C_messages_locale in call to
__set_lc_messages_from_win.
* libc/locale/lmessages.h (struct lc_messages_T): Add wide char members.
* libc/locale/lmonetary.c (_C_monetary_locale): Add default values for
wide char members.
(__monetary_load_locale): Add _C_monetary_locale in call to
__set_lc_monetary_from_win.
* libc/locale/lmonetary.h (struct lc_monetary_T): Add wide char members.
Add numerical values for international currency formatting per
POSIX-1.2008, if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/locale/lnumeric.c (_C_numeric_locale): Add default values for
wide char members.
(__numeric_load_locale): Add _C_numeric_locale in call to
__set_lc_numeric_from_win.
* libc/locale/lnumeric.h (struct lc_numeric_T): Add wide char members.
* libc/locale/locale.c (loadlocale): Return doing nothing if category
locale didn't change. Convert category if chain to switch statement.
Call __ctype_load_locale in LC_CTYPE case.
(__locale_charset): Add (but disable for now) returning codeset from
__get_current_ctype_locale.
(__locale_mb_cur_max): Add (but disable for now) returning mb_cur_max
from __get_current_ctype_locale.
(__locale_msgcharset): Add returning codeset from
__get_current_messages_locale.
(_localeconv_r): Accommodate int_XXX values.
* libc/locale/nl_langinfo.c (nl_ext): New array to define what is to
be returned for non-POSIX values.
(nl_Langinfo): Return correct codeset for each locale category. Return
extended values if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/locale/timelocal.c (_C_time_locale): Add default values for
wide char members.
(__time_load_locale): Add _C_time_locale in call to
__set_lc_time_from_win.
* libc/locale/timelocal.h (struct lc_time_T): Add wide char members.
* libc/stdio/vfwprintf.c (_VFWPRINTF_R): Use wide char decimal point
and thousands_sep if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
* libc/time/strftime.c: Rework to accommodate availability of wide char
strings in LC_TIME category if __HAVE_LOCALE_INFO_EXTENDED__ is defined.
Diffstat (limited to 'newlib/libc/locale/locale.c')
-rw-r--r-- | newlib/libc/locale/locale.c | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c index 14ee907ff..a204d3412 100644 --- a/newlib/libc/locale/locale.c +++ b/newlib/libc/locale/locale.c @@ -179,8 +179,10 @@ No supporting OS subroutines are required. #include <reent.h> #include <stdlib.h> #include <wchar.h> +#include "lmessages.h" #include "lmonetary.h" #include "lnumeric.h" +#include "lctype.h" #include "../stdlib/local.h" #define _LC_LAST 7 @@ -457,6 +459,11 @@ loadlocale(struct _reent *p, int category) int (*l_mbtowc) (struct _reent *, wchar_t *, const char *, size_t, const char *, mbstate_t *); int cjknarrow = 0; + + /* Avoid doing everything twice if nothing has changed. */ + if (!strcmp (new_categories[category], current_categories[category])) + return current_categories[category]; + #ifdef __CYGWIN__ /* This additional code handles the case that the incoming locale string is not valid. If so, it calls the function __set_locale_from_locale_alias, @@ -830,8 +837,9 @@ restart: default: FAIL; } - if (category == LC_CTYPE) + switch (category) { + case LC_CTYPE: strcpy (lc_ctype_charset, charset); __mb_cur_max = mbc_max; __wctomb = l_wctomb; @@ -847,27 +855,36 @@ restart: && ((strncmp (locale, "ja", 2) == 0 || strncmp (locale, "ko", 2) == 0 || strncmp (locale, "zh", 2) == 0)); - } - else if (category == LC_MESSAGES) - { +#ifdef __HAVE_LOCALE_INFO__ + ret = __ctype_load_locale (locale, (void *) l_wctomb, charset, mbc_max); +#endif /* __HAVE_LOCALE_INFO__ */ + break; + case LC_MESSAGES: + strcpy (lc_message_charset, charset); #ifdef __HAVE_LOCALE_INFO__ ret = __messages_load_locale (locale, (void *) l_wctomb, charset); if (!ret) #endif /* __HAVE_LOCALE_INFO__ */ - strcpy (lc_message_charset, charset); - } + break; #ifdef __HAVE_LOCALE_INFO__ #ifdef __CYGWIN__ /* Right now only Cygwin supports a __collate_load_locale function at all. */ - else if (category == LC_COLLATE) - ret = __collate_load_locale (locale, (void *) l_mbtowc, charset); + case LC_COLLATE: + ret = __collate_load_locale (locale, (void *) l_mbtowc, charset); + break; #endif - else if (category == LC_MONETARY) - ret = __monetary_load_locale (locale, (void *) l_wctomb, charset); - else if (category == LC_NUMERIC) - ret = __numeric_load_locale (locale, (void *) l_wctomb, charset); - else if (category == LC_TIME) - ret = __time_load_locale (locale, (void *) l_wctomb, charset); + case LC_MONETARY: + ret = __monetary_load_locale (locale, (void *) l_wctomb, charset); + break; + case LC_NUMERIC: + ret = __numeric_load_locale (locale, (void *) l_wctomb, charset); + break; + case LC_TIME: + ret = __time_load_locale (locale, (void *) l_wctomb, charset); + break; + default: + break; + } if (ret) FAIL; #endif /* __HAVE_LOCALE_INFO__ */ @@ -901,13 +918,32 @@ __get_locale_env(struct _reent *p, int category) char * _DEFUN_VOID(__locale_charset) { +#if 0//def __HAVE_LOCALE_INFO__ + return __get_current_ctype_locale ()->codeset; +#else return lc_ctype_charset; +#endif +} + +int +_DEFUN_VOID(__locale_mb_cur_max) +{ +#if 0//def __HAVE_LOCALE_INFO__ + return __get_current_ctype_locale ()->mb_cur_max[0]; +#else + return __mb_cur_max; +#endif } + char * _DEFUN_VOID(__locale_msgcharset) { +#ifdef __HAVE_LOCALE_INFO__ + return __get_current_messages_locale ()->codeset; +#else return lc_message_charset; +#endif } int @@ -947,12 +983,21 @@ _DEFUN(_localeconv_r, (data), lconv.n_sep_by_space = m->n_sep_by_space[0]; lconv.p_sign_posn = m->p_sign_posn[0]; lconv.n_sign_posn = m->n_sign_posn[0]; +#ifdef __HAVE_LOCALE_INFO_EXTENDED__ + lconv.int_p_cs_precedes = m->int_p_cs_precedes[0]; + lconv.int_p_sep_by_space = m->int_p_sep_by_space[0]; + lconv.int_n_cs_precedes = m->int_n_cs_precedes[0]; + lconv.int_n_sep_by_space = m->int_n_sep_by_space[0]; + lconv.int_n_sign_posn = m->int_n_sign_posn[0]; + lconv.int_p_sign_posn = m->int_p_sign_posn[0]; +#else /* !__HAVE_LOCALE_INFO_EXTENDED__ */ + lconv.int_p_cs_precedes = m->p_cs_precedes[0]; + lconv.int_p_sep_by_space = m->p_sep_by_space[0]; lconv.int_n_cs_precedes = m->n_cs_precedes[0]; lconv.int_n_sep_by_space = m->n_sep_by_space[0]; lconv.int_n_sign_posn = m->n_sign_posn[0]; - lconv.int_p_cs_precedes = m->p_cs_precedes[0]; - lconv.int_p_sep_by_space = m->p_sep_by_space[0]; lconv.int_p_sign_posn = m->p_sign_posn[0]; +#endif /* !__HAVE_LOCALE_INFO_EXTENDED__ */ __mlocale_changed = 0; } #endif /* __HAVE_LOCALE_INFO__ */ |