summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-02-07 13:31:08 +0000
committerCorinna Vinschen <corinna@vinschen.de>2010-02-07 13:31:08 +0000
commit07d061aeecd0b8086ac01f253cd15d5d5752f926 (patch)
tree956dd0c76eb2d7f4cc7c6de5dfdde6563a0ed7ba
parentbc3677c557711d91ce3a8cbc8b537a0ef8b1dcca (diff)
downloadcygnal-07d061aeecd0b8086ac01f253cd15d5d5752f926.tar.gz
cygnal-07d061aeecd0b8086ac01f253cd15d5d5752f926.tar.bz2
cygnal-07d061aeecd0b8086ac01f253cd15d5d5752f926.zip
* nlsfuncs.cc (__set_locale_from_locale_alias): New function to read
locale aliases from /usr/share/locale/locale.alias.
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/nlsfuncs.cc63
2 files changed, 68 insertions, 0 deletions
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 <corinna@vinschen.de>
+
+ * nlsfuncs.cc (__set_locale_from_locale_alias): New function to read
+ locale aliases from /usr/share/locale/locale.alias.
+
2010-02-06 Corinna Vinschen <corinna@vinschen.de>
* 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 <winnls.h>
+#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
@@ -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)
{