From 07d061aeecd0b8086ac01f253cd15d5d5752f926 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 7 Feb 2010 13:31:08 +0000 Subject: [PATCH] * nlsfuncs.cc (__set_locale_from_locale_alias): New function to read locale aliases from /usr/share/locale/locale.alias. --- winsup/cygwin/ChangeLog | 5 ++++ winsup/cygwin/nlsfuncs.cc | 63 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 6d52d0d4e..7254a50aa 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2010-02-07 Corinna Vinschen + + * nlsfuncs.cc (__set_locale_from_locale_alias): New function to read + locale aliases from /usr/share/locale/locale.alias. + 2010-02-06 Corinna Vinschen * nlsfuncs.cc (__get_lcid_from_locale): Handle no_NO as nb_NO, rather diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc index bd061b87e..0b28f8301 100644 --- a/winsup/cygwin/nlsfuncs.cc +++ b/winsup/cygwin/nlsfuncs.cc @@ -10,6 +10,7 @@ details. */ #include "winsup.h" #include +#include #include #include #include @@ -925,6 +926,68 @@ __set_charset_from_locale (const char *locale, char *charset) stpcpy (charset, cs); } +/* This function is called from newlib's loadlocale if the locale identifier + was invalid, one way or the other. It looks for the file + + /usr/share/locale/locale.alias + + which is part of the gettext package, and if it finds the locale alias + in that file, it replaces the locale with the correct locale string from + that file. + + If successful, it returns a pointer to new_locale, NULL otherwise.*/ +extern "C" char * +__set_locale_from_locale_alias (const char *locale, char *new_locale) +{ + wchar_t wlocale[ENCODING_LEN + 1]; + wchar_t walias[ENCODING_LEN + 1]; +#define LOCALE_ALIAS_LINE_LEN 255 + char alias_buf[LOCALE_ALIAS_LINE_LEN + 1], *c; + const char *alias, *replace; + char *ret = NULL; + + FILE *fp = fopen ("/usr/share/locale/locale.alias", "rt"); + if (!fp) + return NULL; + /* The incoming locale is given in the application charset, or in + the Cygwin internal charset. We try both. */ + if (mbstowcs (wlocale, locale, ENCODING_LEN + 1) == (size_t) -1) + sys_mbstowcs (wlocale, ENCODING_LEN + 1, locale); + wlocale[ENCODING_LEN] = L'\0'; + while (fgets (alias_buf, LOCALE_ALIAS_LINE_LEN + 1, fp)) + { + alias_buf[LOCALE_ALIAS_LINE_LEN] = '\0'; + c = strrchr (alias_buf, '\n'); + if (c) + *c = '\0'; + c = alias_buf; + c += strspn (c, " \t"); + if (!*c || *c == '#') + continue; + alias = c; + c += strcspn (c, " \t"); + *c++ = '\0'; + c += strspn (c, " \t"); + if (*c == '#') + continue; + replace = c; + c += strcspn (c, " \t"); + *c++ = '\0'; + if (strlen (replace) > ENCODING_LEN) + continue; + /* The file is latin1 encoded */ + lc_mbstowcs (__iso_mbtowc, "ISO-8859-1", walias, alias, ENCODING_LEN + 1); + walias[ENCODING_LEN] = L'\0'; + if (!wcscmp (wlocale, walias)) + { + ret = strcpy (new_locale, replace); + break; + } + } + fclose (fp); + return ret; +} + static char * check_codepage (char *ret) {