aboutsummaryrefslogtreecommitdiffstats
path: root/intl/setlocale.c
diff options
context:
space:
mode:
Diffstat (limited to 'intl/setlocale.c')
-rw-r--r--intl/setlocale.c79
1 files changed, 67 insertions, 12 deletions
diff --git a/intl/setlocale.c b/intl/setlocale.c
index 2a5e2605b..45fbc7b75 100644
--- a/intl/setlocale.c
+++ b/intl/setlocale.c
@@ -2,20 +2,18 @@
Copyright (C) 2009 Free Software Foundation, Inc.
Written by Bruno Haible <[email protected]>, 2009.
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- USA. */
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -856,6 +854,14 @@ libintl_setlocale (int category, const char *locale)
if (setlocale_unixlike (LC_ALL, base_name) == NULL)
goto fail;
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
+ LC_CTYPE category to an invalid value ("C") when it does not
+ support the specified encoding. Report a failure instead. */
+ if (strchr (base_name, '.') != NULL
+ && strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
+ goto fail;
+# endif
for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++)
{
@@ -878,6 +884,7 @@ libintl_setlocale (int category, const char *locale)
}
/* All steps were successful. */
+ ++_nl_msg_cat_cntr;
free (saved_locale);
return setlocale (LC_ALL, NULL);
@@ -889,16 +896,64 @@ libintl_setlocale (int category, const char *locale)
}
else
{
+ char *result;
const char *name =
gl_locale_name_environ (category, category_to_name (category));
if (name == NULL)
name = gl_locale_name_default ();
- return setlocale_single (category, name);
+ result = setlocale_single (category, name);
+ if (result != NULL)
+ ++_nl_msg_cat_cntr;
+ return result;
}
}
else
- return setlocale_single (category, locale);
+ {
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ if (category == LC_ALL && locale != NULL && strchr (locale, '.') != NULL)
+ {
+ char *saved_locale;
+
+ /* Back up the old locale. */
+ saved_locale = setlocale (LC_ALL, NULL);
+ if (saved_locale == NULL)
+ return NULL;
+ saved_locale = strdup (saved_locale);
+ if (saved_locale == NULL)
+ return NULL;
+
+ if (setlocale_unixlike (LC_ALL, locale) == NULL)
+ {
+ free (saved_locale);
+ return NULL;
+ }
+
+ /* On native Windows, setlocale(LC_ALL,...) may succeed but set the
+ LC_CTYPE category to an invalid value ("C") when it does not
+ support the specified encoding. Report a failure instead. */
+ if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
+ {
+ if (saved_locale[0] != '\0') /* don't risk an endless recursion */
+ setlocale (LC_ALL, saved_locale);
+ free (saved_locale);
+ return NULL;
+ }
+
+ /* It was really successful. */
+ ++_nl_msg_cat_cntr;
+ free (saved_locale);
+ return setlocale (LC_ALL, NULL);
+ }
+ else
+# endif
+ {
+ char *result = setlocale_single (category, locale);
+ if (result != NULL)
+ ++_nl_msg_cat_cntr;
+ return result;
+ }
+ }
}
# if HAVE_NEWLOCALE