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-02-19 20:30:19 +0300
committerCorinna Vinschen <corinna@vinschen.de>2010-02-19 20:30:19 +0300
commit6c36e83bab1daa032e567b7f9f8c2e063eaf5a20 (patch)
tree94e19d910e6af9750c4b5057db8e4b2de1d04790 /winsup/cygwin/nlsfuncs.cc
parentf13fe164754007fc2ce315fd3a3cc336943752b3 (diff)
* lc_era.h: New file.
* nlsfuncs.cc: Include lc_era.h. (locale_cmp): convert arguments to char** to be usable for both types, lc_msg_t and lc_era_t. (__set_lc_time_from_win): Handle era-related data
Diffstat (limited to 'winsup/cygwin/nlsfuncs.cc')
-rw-r--r--winsup/cygwin/nlsfuncs.cc115
1 files changed, 92 insertions, 23 deletions
diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc
index fa1b91566..c31632a76 100644
--- a/winsup/cygwin/nlsfuncs.cc
+++ b/winsup/cygwin/nlsfuncs.cc
@@ -25,6 +25,7 @@ details. */
#include "../locale/lmonetary.h"
#include "../locale/lmessages.h"
#include "lc_msg.h"
+#include "lc_era.h"
#define _LC(x) &lc_##x##_ptr,lc_##x##_end-lc_##x##_ptr
@@ -316,6 +317,14 @@ lc_mbstowcs (mbtowc_p f_mbtowc, const char *charset,
return ret;
}
+static int
+locale_cmp (const void *a, const void *b)
+{
+ char **la = (char **) a;
+ char **lb = (char **) b;
+ return strcmp (*la, *lb);
+}
+
static char *
__getlocaleinfo (LCID lcid, LCTYPE type, char **ptr, size_t size,
wctomb_p f_wctomb, const char *charset)
@@ -531,22 +540,90 @@ __set_lc_time_from_win (const char *name, struct lc_time_T *_time_locale,
_time_locale->ampm_fmt = eval_datetimefmt (LOCALE_STIMEFORMAT, DT_AMPM);
/* TODO */
+ char locale[ENCODING_LEN + 1];
+ char *c, *c2;
- /* era */
- _time_locale->era = lc_time_ptr;
- *lc_time_ptr++ = '\0';
- /* era_d_fmt */
- _time_locale->era_d_fmt = lc_time_ptr;
- *lc_time_ptr++ = '\0';
- /* era_d_t_fmt */
- _time_locale->era_d_t_fmt = lc_time_ptr;
- *lc_time_ptr++ = '\0';
- /* era_t_fmt */
- _time_locale->era_t_fmt = lc_time_ptr;
- *lc_time_ptr++ = '\0';
- /* alt_digits */
- _time_locale->alt_digits = lc_time_ptr;
- *lc_time_ptr++ = '\0';
+ strcpy (locale, name);
+ /* Removes the charset from the locale and attach the modifer to the
+ language_TERRITORY part. */
+ c = strchr (locale, '.');
+ if (c)
+ {
+ *c = '\0';
+ c2 = strchr (c + 1, '@');
+ /* Ignore @cjknarrow modifier since it's a very personal thing between
+ Cygwin and newlib... */
+ if (c2 && strcmp (c2, "@cjknarrow"))
+ memmove (c, c2, strlen (c2) + 1);
+ }
+ /* Now search in the alphabetically order lc_era array for the
+ locale. */
+ lc_era_t locale_key = { locale, NULL, NULL, NULL, NULL, NULL };
+ lc_era_t *res = (lc_era_t *) bsearch ((void *) &locale_key, (void *) lc_era,
+ sizeof lc_era / sizeof *lc_era,
+ sizeof *lc_era, locale_cmp);
+ if (res)
+ {
+ /* Evaluate string length in target charset. Characters invalid in the
+ target charset are simply ignored, as on Linux. */
+ size_t len = 0;
+ len += lc_wcstombs (f_wctomb, charset, NULL, res->era, 0) + 1;
+ len += lc_wcstombs (f_wctomb, charset, NULL, res->era_d_fmt, 0) + 1;
+ len += lc_wcstombs (f_wctomb, charset, NULL, res->era_d_t_fmt, 0) + 1;
+ len += lc_wcstombs (f_wctomb, charset, NULL, res->era_t_fmt, 0) + 1;
+ len += lc_wcstombs (f_wctomb, charset, NULL, res->alt_digits, 0) + 1;
+
+ /* Make sure data fits into the buffer */
+ if (lc_time_ptr + len > lc_time_end)
+ {
+ len = lc_time_ptr + len - new_lc_time_buf;
+ char *tmp = (char *) realloc (new_lc_time_buf, len);
+ if (!tmp)
+ res = NULL;
+ else
+ {
+ lc_time_ptr = tmp + (lc_time_ptr - new_lc_time_buf);
+ new_lc_time_buf = tmp;
+ lc_time_end = new_lc_time_buf + len;
+ }
+ }
+ /* Copy over */
+ if (res)
+ {
+ /* era */
+ _time_locale->era = (const char *) lc_time_ptr;
+ len = lc_wcstombs (f_wctomb, charset, lc_time_ptr, res->era,
+ lc_time_end - lc_time_ptr) + 1;
+ /* era_d_fmt */
+ _time_locale->era_d_fmt = (const char *) (lc_time_ptr += len);
+ len = lc_wcstombs (f_wctomb, charset, lc_time_ptr, res->era_d_fmt,
+ lc_time_end - lc_time_ptr) + 1;
+ /* era_d_t_fmt */
+ _time_locale->era_d_t_fmt = (const char *) (lc_time_ptr += len);
+ len = lc_wcstombs (f_wctomb, charset, lc_time_ptr, res->era_d_t_fmt,
+ lc_time_end - lc_time_ptr) + 1;
+ /* era_t_fmt */
+ _time_locale->era_t_fmt = (const char *) (lc_time_ptr += len);
+ len = lc_wcstombs (f_wctomb, charset, lc_time_ptr, res->era_t_fmt,
+ lc_time_end - lc_time_ptr) + 1;
+ /* alt_digits */
+ _time_locale->alt_digits = (const char *) (lc_time_ptr += len);
+ len = lc_wcstombs (f_wctomb, charset, lc_time_ptr, res->alt_digits,
+ lc_time_end - lc_time_ptr) + 1;
+ lc_time_ptr += len;
+ }
+ }
+ if (!res)
+ {
+ _time_locale->era =
+ _time_locale->era_d_fmt =
+ _time_locale->era_d_t_fmt =
+ _time_locale->era_t_fmt =
+ _time_locale->alt_digits = (const char *) lc_time_ptr;
+ /* Twice, to make sure era and alt_strings are correctly terminated
+ with two NULs */
+ *lc_time_ptr++ = '\0';
+ }
char *tmp = (char *) realloc (new_lc_time_buf, lc_time_ptr - new_lc_time_buf);
if (!tmp)
@@ -702,14 +779,6 @@ __set_lc_monetary_from_win (const char *name,
return 1;
}
-static int
-locale_cmp (const void *a, const void *b)
-{
- struct lc_msg_t *la = (struct lc_msg_t *) a;
- struct lc_msg_t *lb = (struct lc_msg_t *) b;
- return strcmp (la->locale, lb->locale);
-}
-
extern "C" int
__set_lc_messages_from_win (const char *name,
struct lc_messages_T *_messages_locale,