Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-04-28 13:59:37 +0400
committerCorinna Vinschen <corinna@vinschen.de>2010-04-28 13:59:37 +0400
commitd47d5b850bed398357e7f05d8fef508be1bb7f51 (patch)
tree8571d6a5751c102c12b11c58261ee663e83d7fce /newlib/libc/locale/locale.c
parent9b53b52a80f79a7746f51e2092b23dfab3d50c6f (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.c77
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__ */