summaryrefslogtreecommitdiffstats
path: root/newlib/libc/locale
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/locale')
-rw-r--r--newlib/libc/locale/lmonetary.c24
-rw-r--r--newlib/libc/locale/lmonetary.h8
-rw-r--r--newlib/libc/locale/lnumeric.c23
-rw-r--r--newlib/libc/locale/lnumeric.h8
-rw-r--r--newlib/libc/locale/locale.c73
-rw-r--r--newlib/libc/locale/nl_langinfo.c4
-rw-r--r--newlib/libc/locale/timelocal.c26
-rw-r--r--newlib/libc/locale/timelocal.h11
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_ */