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/nl_langinfo.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/nl_langinfo.c')
-rw-r--r--newlib/libc/locale/nl_langinfo.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/newlib/libc/locale/nl_langinfo.c b/newlib/libc/locale/nl_langinfo.c
index d4f30e932..97d835bef 100644
--- a/newlib/libc/locale/nl_langinfo.c
+++ b/newlib/libc/locale/nl_langinfo.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
+#include "lctype.h"
#include "timelocal.h"
#include "lnumeric.h"
#include "lmonetary.h"
@@ -41,6 +42,138 @@
#define TRANSITION_PERIOD_HACK
#endif
+#undef offsetoff
+#define _O(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+
+#define _NLITEM(cat,memb) { { cat:__get_current_##cat##_locale }, \
+ _O (struct lc_##cat##_T, memb) }
+
+#ifdef __HAVE_LOCALE_INFO_EXTENDED__
+static struct _nl_item_t
+{
+ union {
+ struct lc_ctype_T * (*ctype)(void);
+ struct lc_time_T * (*time)(void);
+ struct lc_numeric_T * (*numeric)(void);
+ struct lc_monetary_T * (*monetary)(void);
+ struct lc_messages_T * (*messages)(void);
+ void * (*base)(void);
+ };
+ _off_t offset;
+} nl_ext[] =
+{
+ /* First element has an nl_item value of _NL_LOCALE_EXTENDED_FIRST_ENTRY */
+ _NLITEM (ctype, outdigits[0]),
+ _NLITEM (ctype, outdigits[1]),
+ _NLITEM (ctype, outdigits[2]),
+ _NLITEM (ctype, outdigits[3]),
+ _NLITEM (ctype, outdigits[4]),
+ _NLITEM (ctype, outdigits[5]),
+ _NLITEM (ctype, outdigits[6]),
+ _NLITEM (ctype, outdigits[7]),
+ _NLITEM (ctype, outdigits[8]),
+ _NLITEM (ctype, outdigits[9]),
+ _NLITEM (ctype, woutdigits[0]),
+ _NLITEM (ctype, woutdigits[1]),
+ _NLITEM (ctype, woutdigits[2]),
+ _NLITEM (ctype, woutdigits[3]),
+ _NLITEM (ctype, woutdigits[4]),
+ _NLITEM (ctype, woutdigits[5]),
+ _NLITEM (ctype, woutdigits[6]),
+ _NLITEM (ctype, woutdigits[7]),
+ _NLITEM (ctype, woutdigits[8]),
+ _NLITEM (ctype, woutdigits[9]),
+ _NLITEM (time, codeset),
+ _NLITEM (time, wmon[1]),
+ _NLITEM (time, wmon[2]),
+ _NLITEM (time, wmon[3]),
+ _NLITEM (time, wmon[4]),
+ _NLITEM (time, wmon[5]),
+ _NLITEM (time, wmon[6]),
+ _NLITEM (time, wmon[7]),
+ _NLITEM (time, wmon[8]),
+ _NLITEM (time, wmon[9]),
+ _NLITEM (time, wmon[10]),
+ _NLITEM (time, wmon[11]),
+ _NLITEM (time, wmon[12]),
+ _NLITEM (time, wmonth[1]),
+ _NLITEM (time, wmonth[2]),
+ _NLITEM (time, wmonth[3]),
+ _NLITEM (time, wmonth[4]),
+ _NLITEM (time, wmonth[5]),
+ _NLITEM (time, wmonth[6]),
+ _NLITEM (time, wmonth[7]),
+ _NLITEM (time, wmonth[8]),
+ _NLITEM (time, wmonth[9]),
+ _NLITEM (time, wmonth[10]),
+ _NLITEM (time, wmonth[11]),
+ _NLITEM (time, wmonth[12]),
+ _NLITEM (time, wwday[1]),
+ _NLITEM (time, wwday[2]),
+ _NLITEM (time, wwday[3]),
+ _NLITEM (time, wwday[4]),
+ _NLITEM (time, wwday[5]),
+ _NLITEM (time, wwday[6]),
+ _NLITEM (time, wwday[7]),
+ _NLITEM (time, wweekday[1]),
+ _NLITEM (time, wweekday[2]),
+ _NLITEM (time, wweekday[3]),
+ _NLITEM (time, wweekday[4]),
+ _NLITEM (time, wweekday[5]),
+ _NLITEM (time, wweekday[6]),
+ _NLITEM (time, wweekday[7]),
+ _NLITEM (time, wX_fmt),
+ _NLITEM (time, wx_fmt),
+ _NLITEM (time, wc_fmt),
+ _NLITEM (time, wam_pm[0]),
+ _NLITEM (time, wam_pm[1]),
+ _NLITEM (time, wdate_fmt),
+ _NLITEM (time, wampm_fmt),
+ _NLITEM (time, wera),
+ _NLITEM (time, wera_d_fmt),
+ _NLITEM (time, wera_d_t_fmt),
+ _NLITEM (time, wera_t_fmt),
+ _NLITEM (time, walt_digits),
+ _NLITEM (numeric, codeset),
+ _NLITEM (numeric, grouping),
+ _NLITEM (numeric, wdecimal_point),
+ _NLITEM (numeric, wthousands_sep),
+ _NLITEM (monetary, int_curr_symbol),
+ _NLITEM (monetary, currency_symbol),
+ _NLITEM (monetary, mon_decimal_point),
+ _NLITEM (monetary, mon_thousands_sep),
+ _NLITEM (monetary, mon_grouping),
+ _NLITEM (monetary, positive_sign),
+ _NLITEM (monetary, negative_sign),
+ _NLITEM (monetary, int_frac_digits),
+ _NLITEM (monetary, frac_digits),
+ _NLITEM (monetary, p_cs_precedes),
+ _NLITEM (monetary, p_sep_by_space),
+ _NLITEM (monetary, n_cs_precedes),
+ _NLITEM (monetary, n_sep_by_space),
+ _NLITEM (monetary, p_sign_posn),
+ _NLITEM (monetary, n_sign_posn),
+ _NLITEM (monetary, int_p_cs_precedes),
+ _NLITEM (monetary, int_p_sep_by_space),
+ _NLITEM (monetary, int_n_cs_precedes),
+ _NLITEM (monetary, int_n_sep_by_space),
+ _NLITEM (monetary, int_p_sign_posn),
+ _NLITEM (monetary, int_n_sign_posn),
+ _NLITEM (monetary, codeset),
+ _NLITEM (monetary, wint_curr_symbol),
+ _NLITEM (monetary, wcurrency_symbol),
+ _NLITEM (monetary, wmon_decimal_point),
+ _NLITEM (monetary, wmon_thousands_sep),
+ _NLITEM (monetary, wpositive_sign),
+ _NLITEM (monetary, wnegative_sign),
+ _NLITEM (messages, codeset),
+ _NLITEM (messages, wyesexpr),
+ _NLITEM (messages, wnoexpr),
+ _NLITEM (messages, wyesstr),
+ _NLITEM (messages, wnostr),
+};
+#endif /* __HAVE_LOCALE_INFO_EXTENDED__ */
+
#define _REL(BASE) ((int)item-BASE)
extern char *__locale_charset ();
@@ -57,9 +190,36 @@ _DEFUN(nl_langinfo, (item),
char *nptr;
switch (item) {
+#ifdef __HAVE_LOCALE_INFO__
+ case _NL_MESSAGES_CODESET:
+ ret = (char *) __get_current_messages_locale ()->codeset;
+ goto do_codeset;
+#ifdef __HAVE_LOCALE_INFO_EXTENDED__
+ case _NL_TIME_CODESET:
+ ret = (char *) __get_current_time_locale ()->codeset;
+ goto do_codeset;
+ case _NL_NUMERIC_CODESET:
+ ret = (char *) __get_current_numeric_locale ()->codeset;
+ goto do_codeset;
+ case _NL_MONETARY_CODESET:
+ ret = (char *) __get_current_monetary_locale ()->codeset;
+ goto do_codeset;
+#ifdef __CYGWIN__
+ case _NL_COLLATE_CODESET:
+ {
+ extern const char *__get_current_collate_codeset (void);
+ ret = (char *) __get_current_collate_codeset ();
+ goto do_codeset;
+ }
+#endif /* __CYGWIN__ */
+#endif /* __HAVE_LOCALE_INFO_EXTENDED__ */
+#endif /* __HAVE_LOCALE_INFO__ */
case CODESET:
#ifdef __CYGWIN__
ret = __locale_charset ();
+#endif
+do_codeset:
+#ifdef __CYGWIN__
/* Convert charset to Linux compatible codeset string. */
if (ret[0] == 'A'/*SCII*/)
ret = "ANSI_X3.4-1968";
@@ -252,7 +412,18 @@ _DEFUN(nl_langinfo, (item),
case D_MD_ORDER: /* local extension */
ret = (char *) __get_current_time_locale()->md_order;
break;
+ case _NL_CTYPE_MB_CUR_MAX:
+ ret = (char *) __get_current_ctype_locale()->mb_cur_max;
+ break;
default:
+#ifdef __HAVE_LOCALE_INFO_EXTENDED__
+ if (item > _NL_LOCALE_EXTENDED_FIRST_ENTRY
+ && item < _NL_LOCALE_EXTENDED_LAST_ENTRY) {
+ int idx = item - _NL_LOCALE_EXTENDED_FIRST_ENTRY - 1;
+ return *(char **) ((char *) (*nl_ext[idx].base)()
+ + nl_ext[idx].offset);
+ }
+#endif
ret = "";
}
return (ret);