diff options
Diffstat (limited to 'newlib/libc/locale')
-rw-r--r-- | newlib/libc/locale/lmonetary.c | 24 | ||||
-rw-r--r-- | newlib/libc/locale/lmonetary.h | 8 | ||||
-rw-r--r-- | newlib/libc/locale/lnumeric.c | 23 | ||||
-rw-r--r-- | newlib/libc/locale/lnumeric.h | 8 | ||||
-rw-r--r-- | newlib/libc/locale/locale.c | 73 | ||||
-rw-r--r-- | newlib/libc/locale/nl_langinfo.c | 4 | ||||
-rw-r--r-- | newlib/libc/locale/timelocal.c | 26 | ||||
-rw-r--r-- | newlib/libc/locale/timelocal.h | 11 |
8 files changed, 153 insertions, 24 deletions
diff --git a/newlib/libc/locale/lmonetary.c b/newlib/libc/locale/lmonetary.c index d31e88ccd..745ade517 100644 --- a/newlib/libc/locale/lmonetary.c +++ b/newlib/libc/locale/lmonetary.c @@ -70,9 +70,28 @@ cnv(const char *str) { } int -__monetary_load_locale(const char *name) { - +__monetary_load_locale(const char *name , void *f_wctomb, const char *charset) +{ int ret; + +#ifdef __CYGWIN__ + extern int __set_lc_monetary_from_win (const char *, + struct lc_monetary_T *, + void *, const char *); + int old_monetary_using_locale = _monetary_using_locale; + _monetary_using_locale = 0; + ret = __set_lc_monetary_from_win (name, &_monetary_locale, + f_wctomb, charset); + /* ret == -1: error, ret == 0: C/POSIX, ret > 0: valid */ + if (ret < 0) + _monetary_using_locale = old_monetary_using_locale; + else + { + _monetary_using_locale = ret; + __mlocale_changed = 1; + ret = 0; + } +#else __mlocale_changed = 1; ret = __part_load_locale(name, &_monetary_using_locale, _monetary_locale_buf, "LC_MONETARY", @@ -94,6 +113,7 @@ __monetary_load_locale(const char *name) { M_ASSIGN_CHAR(p_sign_posn); M_ASSIGN_CHAR(n_sign_posn); } +#endif return ret; } diff --git a/newlib/libc/locale/lmonetary.h b/newlib/libc/locale/lmonetary.h index bbe77db42..14c9cc15d 100644 --- a/newlib/libc/locale/lmonetary.h +++ b/newlib/libc/locale/lmonetary.h @@ -29,6 +29,10 @@ #ifndef _LMONETARY_H_ #define _LMONETARY_H_ +#include <sys/cdefs.h> + +__BEGIN_DECLS + struct lc_monetary_T { const char *int_curr_symbol; const char *currency_symbol; @@ -48,6 +52,8 @@ struct lc_monetary_T { }; struct lc_monetary_T *__get_current_monetary_locale(void); -int __monetary_load_locale(const char *); +int __monetary_load_locale(const char *, void *, const char *); + +__END_DECLS #endif /* !_LMONETARY_H_ */ diff --git a/newlib/libc/locale/lnumeric.c b/newlib/libc/locale/lnumeric.c index 90b404ca2..5bf0a7d11 100644 --- a/newlib/libc/locale/lnumeric.c +++ b/newlib/libc/locale/lnumeric.c @@ -48,10 +48,28 @@ static int _numeric_using_locale; static char *_numeric_locale_buf; int -__numeric_load_locale(const char *name) { - +__numeric_load_locale(const char *name , void *f_wctomb, const char *charset) +{ int ret; +#ifdef __CYGWIN__ + extern int __set_lc_numeric_from_win (const char *, + struct lc_numeric_T *, + void *, const char *); + int old_numeric_using_locale = _numeric_using_locale; + _numeric_using_locale = 0; + ret = __set_lc_numeric_from_win (name, &_numeric_locale, + f_wctomb, charset); + /* ret == -1: error, ret == 0: C/POSIX, ret > 0: valid */ + if (ret < 0) + _numeric_using_locale = old_numeric_using_locale; + else + { + _numeric_using_locale = ret; + __nlocale_changed = 1; + ret = 0; + } +#else __nlocale_changed = 1; ret = __part_load_locale(name, &_numeric_using_locale, _numeric_locale_buf, "LC_NUMERIC", @@ -60,6 +78,7 @@ __numeric_load_locale(const char *name) { if (ret == 0 && _numeric_using_locale) _numeric_locale.grouping = __fix_locale_grouping_str(_numeric_locale.grouping); +#endif return ret; } diff --git a/newlib/libc/locale/lnumeric.h b/newlib/libc/locale/lnumeric.h index 9678c1f02..bed75e868 100644 --- a/newlib/libc/locale/lnumeric.h +++ b/newlib/libc/locale/lnumeric.h @@ -29,6 +29,10 @@ #ifndef _LNUMERIC_H_ #define _LNUMERIC_H_ +#include <sys/cdefs.h> + +__BEGIN_DECLS + struct lc_numeric_T { const char *decimal_point; const char *thousands_sep; @@ -36,6 +40,8 @@ struct lc_numeric_T { }; struct lc_numeric_T *__get_current_numeric_locale(void); -int __numeric_load_locale(const char *); +int __numeric_load_locale(const char *, void *, const char *); + +__END_DECLS #endif /* !_LNUMERIC_H_ */ diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c index 1349927bf..4dd773463 100644 --- a/newlib/libc/locale/locale.c +++ b/newlib/libc/locale/locale.c @@ -75,7 +75,9 @@ Even when using POSIX locale strings, the only charsets allowed are 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258]. Charsets are case insensitive. For instance, <<"EUCJP">> and <<"eucJP">> are equivalent. <<"UTF-8">> can also be written without dash, as in -<<"UTF8">> or <<"utf8">>. +<<"UTF8">> or <<"utf8">>. <<"EUCJP">> and <<"EUCKR"> can also contain a +dash, <<"EUC-JP">> and <<"EUC-KR">>. + (<<"">> is also accepted; if given, the settings are read from the corresponding LC_* environment variables and $LANG according to POSIX rules. @@ -172,6 +174,8 @@ No supporting OS subroutines are required. #include <reent.h> #include <stdlib.h> #include <wchar.h> +#include "lmonetary.h" +#include "lnumeric.h" #include "../stdlib/local.h" #define _LC_LAST 7 @@ -183,7 +187,11 @@ int __nlocale_changed = 0; int __mlocale_changed = 0; char *_PathLocale = NULL; -static _CONST struct lconv lconv = +static +#ifndef __CYGWIN__ +_CONST +#endif +struct lconv lconv = { ".", "", "", "", "", "", "", "", "", "", CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, @@ -420,7 +428,8 @@ currentlocale() #ifdef _MB_CAPABLE #ifdef __CYGWIN__ -extern void *__set_charset_from_codepage (unsigned int, char *charset); +extern void __set_charset_from_locale (const char *locale, char *charset); +extern int __collate_load_locale (const char *, void *, const char *); #endif /* __CYGWIN__ */ extern void __set_ctype (const char *charset); @@ -447,6 +456,9 @@ loadlocale(struct _reent *p, int category) #ifdef _MB_CAPABLE int cjknarrow = 0; #endif +#ifdef __CYGWIN__ + int ret = 0; +#endif /* "POSIX" is translated to "C", as on Linux. */ if (!strcmp (locale, "POSIX")) @@ -502,7 +514,7 @@ loadlocale(struct _reent *p, int category) else if (c[0] == '\0' || c[0] == '@') /* End of string or just a modifier */ #ifdef __CYGWIN__ - __set_charset_from_codepage (0, charset); + __set_charset_from_locale (locale, charset); #else strcpy (charset, "ISO-8859-1"); #endif @@ -548,7 +560,7 @@ loadlocale(struct _reent *p, int category) break; case 'E': case 'e': - if (!strcasecmp (charset, "EUCJP")) + if (!strcasecmp (charset, "EUCJP") || !strcasecmp (charset, "EUC-JP")) { strcpy (charset, "EUCJP"); mbc_max = 3; @@ -558,7 +570,8 @@ loadlocale(struct _reent *p, int category) #endif } #ifdef __CYGWIN__ - else if (!strcasecmp (charset, "EUCKR")) + else if (!strcasecmp (charset, "EUCKR") + || !strcasecmp (charset, "EUC-KR")) { strcpy (charset, "EUCKR"); mbc_max = 2; @@ -729,6 +742,18 @@ loadlocale(struct _reent *p, int category) } else if (category == LC_MESSAGES) strcpy (lc_message_charset, charset); +#ifdef __CYGWIN__ + else if (category == LC_COLLATE) + ret = __collate_load_locale (locale, (void *) l_mbtowc, charset); + 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); + if (ret) + return NULL; +#endif return strcpy(current_categories[category], new_categories[category]); } @@ -778,6 +803,42 @@ struct lconv * _DEFUN(_localeconv_r, (data), struct _reent *data) { +#ifdef __CYGWIN__ + if (__nlocale_changed) + { + struct lc_numeric_T *n = __get_current_numeric_locale (); + lconv.decimal_point = n->decimal_point; + lconv.thousands_sep = n->thousands_sep; + lconv.grouping = n->grouping; + __nlocale_changed = 0; + } + if (__mlocale_changed) + { + struct lc_monetary_T *m = __get_current_monetary_locale (); + lconv.int_curr_symbol = m->int_curr_symbol; + lconv.currency_symbol = m->currency_symbol; + lconv.mon_decimal_point = m->mon_decimal_point; + lconv.mon_thousands_sep = m->mon_thousands_sep; + lconv.mon_grouping = m->mon_grouping; + lconv.positive_sign = m->positive_sign; + lconv.negative_sign = m->negative_sign; + lconv.int_frac_digits = m->int_frac_digits[0]; + lconv.frac_digits = m->frac_digits[0]; + lconv.p_cs_precedes = m->p_cs_precedes[0]; + lconv.p_sep_by_space = m->p_sep_by_space[0]; + lconv.n_cs_precedes = m->n_cs_precedes[0]; + 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]; + 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]; + __mlocale_changed = 0; + } +#endif return (struct lconv *) &lconv; } diff --git a/newlib/libc/locale/nl_langinfo.c b/newlib/libc/locale/nl_langinfo.c index 550f92efd..ae7228cf6 100644 --- a/newlib/libc/locale/nl_langinfo.c +++ b/newlib/libc/locale/nl_langinfo.c @@ -133,10 +133,10 @@ _DEFUN(nl_langinfo, (item), ret = (char *) __get_current_time_locale()->ampm_fmt; break; case AM_STR: - ret = (char *) __get_current_time_locale()->am; + ret = (char *) __get_current_time_locale()->am_pm[0]; break; case PM_STR: - ret = (char *) __get_current_time_locale()->pm; + ret = (char *) __get_current_time_locale()->am_pm[1]; break; case DAY_1: case DAY_2: case DAY_3: case DAY_4: case DAY_5: case DAY_6: case DAY_7: diff --git a/newlib/libc/locale/timelocal.c b/newlib/libc/locale/timelocal.c index 5b097ad7c..0fe53bf42 100644 --- a/newlib/libc/locale/timelocal.c +++ b/newlib/libc/locale/timelocal.c @@ -70,11 +70,8 @@ static const struct lc_time_T _C_time_locale = { */ "%a %b %e %H:%M:%S %Y", - /* am */ - "AM", - - /* pm */ - "PM", + /* am pm */ + { "AM", "PM" }, /* date_fmt */ "%a %b %e %H:%M:%S %Z %Y", @@ -106,14 +103,29 @@ __get_current_time_locale(void) { } int -__time_load_locale(const char *name) { +__time_load_locale(const char *name, void *f_wctomb, const char *charset) { int ret; +#ifdef __CYGWIN__ + extern int __set_lc_time_from_win (const char *, struct lc_time_T *, + void *, const char *); + int old_time_using_locale = _time_using_locale; + _time_using_locale = 0; + ret = __set_lc_time_from_win (name, &_time_locale, f_wctomb, charset); + /* ret == -1: error, ret == 0: C/POSIX, ret > 0: valid */ + if (ret < 0) + _time_using_locale = old_time_using_locale; + else + { + _time_using_locale = ret; + ret = 0; + } +#else ret = __part_load_locale(name, &_time_using_locale, time_locale_buf, "LC_TIME", LCTIME_SIZE, LCTIME_SIZE, (const char **)&_time_locale); - +#endif return (ret); } diff --git a/newlib/libc/locale/timelocal.h b/newlib/libc/locale/timelocal.h index 0b0a59a48..e232a7304 100644 --- a/newlib/libc/locale/timelocal.h +++ b/newlib/libc/locale/timelocal.h @@ -29,6 +29,10 @@ #ifndef _TIMELOCAL_H_ #define _TIMELOCAL_H_ +#include <sys/cdefs.h> + +__BEGIN_DECLS + /* * Private header file for the strftime and strptime localization * stuff. @@ -41,8 +45,7 @@ struct lc_time_T { const char *X_fmt; const char *x_fmt; const char *c_fmt; - const char *am; - const char *pm; + const char *am_pm[2]; const char *date_fmt; const char *alt_month[12]; const char *md_order; @@ -50,6 +53,8 @@ struct lc_time_T { }; struct lc_time_T *__get_current_time_locale(void); -int __time_load_locale(const char *); +int __time_load_locale(const char *, void *, const char *); + +__END_DECLS #endif /* !_TIMELOCAL_H_ */ |