changeset 12347:8fcfa42d797d

duplocale: Fix logic bug.
author Bruno Haible <bruno@clisp.org>
date Tue, 24 Nov 2009 10:44:40 +0100
parents 7839ef932c72
children 8877edbaae37
files ChangeLog lib/duplocale.c tests/test-duplocale.c
diffstat 3 files changed, 38 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-11-24  Bruno Haible  <bruno@clisp.org>
+
+	duplocale: Fix logic bug.
+	* lib/duplocale.c: Don't include <langinfo.h>.
+	(_NL_LOCALE_NAME): Remove macro.
+	(rpl_duplocale): Use setlocale instead of nl_langinfo.
+	* tests/test-duplocale.c (main): Also test duplocale after uselocale.
+
 2009-11-23  Jim Meyering  <meyering@redhat.com>
 
 	test-update-copyright: don't hard-code /usr/bin/perl
--- a/lib/duplocale.c
+++ b/lib/duplocale.c
@@ -22,15 +22,8 @@
 #include <locale.h>
 
 #include <errno.h>
-#include <langinfo.h>
 #include <string.h>
 
-/* Work around an incorrect definition of the _NL_LOCALE_NAME macro in
-   glibc < 2.12.
-   See <http://sourceware.org/bugzilla/show_bug.cgi?id=10968>.  */
-#undef _NL_LOCALE_NAME
-#define _NL_LOCALE_NAME(category) _NL_ITEM ((category), _NL_ITEM_INDEX (-1))
-
 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
 
 #undef duplocale
@@ -74,11 +67,7 @@
       locale_t base_copy;
       unsigned int i;
 
-      base_name = nl_langinfo (_NL_LOCALE_NAME (LC_CTYPE));
-      if (base_name[0] == '\0')
-	/* Fallback code for glibc < 2.4, which did not implement
-	   nl_langinfo (_NL_LOCALE_NAME (category)).  */
-	base_name = setlocale (LC_CTYPE, NULL);
+      base_name = setlocale (LC_CTYPE, NULL);
       base_copy = newlocale (LC_ALL_MASK, base_name, NULL);
       if (base_copy == NULL)
 	return NULL;
@@ -87,11 +76,7 @@
 	{
 	  int category = categories[i].cat;
 	  int category_mask = categories[i].mask;
-	  const char *name = nl_langinfo (_NL_LOCALE_NAME (category));
-	  if (name[0] == '\0')
-	    /* Fallback code for glibc < 2.4, which did not implement
-	       nl_langinfo (_NL_LOCALE_NAME (category)).  */
-	    name = setlocale (category, NULL);
+	  const char *name = setlocale (category, NULL);
 	  if (strcmp (name, base_name) != 0)
 	    {
 	      locale_t copy = newlocale (category_mask, name, base_copy);
--- a/tests/test-duplocale.c
+++ b/tests/test-duplocale.c
@@ -64,7 +64,8 @@
 main ()
 {
   struct locale_dependent_values expected_results;
-  locale_t mixed;
+  locale_t mixed1;
+  locale_t mixed2;
 
   /* Set up a locale which is a mix between different system locales.  */
   setlocale (LC_ALL, "en_US.UTF-8");
@@ -73,18 +74,40 @@
   get_locale_dependent_values (&expected_results);
 
   /* Save the locale in a locale_t object.  */
-  mixed = duplocale (LC_GLOBAL_LOCALE);
-  ASSERT (mixed != NULL);
+  mixed1 = duplocale (LC_GLOBAL_LOCALE);
+  ASSERT (mixed1 != NULL);
+
+  /* Use a per-thread locale.  */
+  uselocale (newlocale (LC_ALL_MASK, "es_ES.UTF-8", NULL));
+
+  /* Save the locale in a locale_t object again.  */
+  mixed2 = duplocale (LC_GLOBAL_LOCALE);
+  ASSERT (mixed2 != NULL);
 
   /* Set up a default locale.  */
   setlocale (LC_ALL, "C");
+  uselocale (LC_GLOBAL_LOCALE);
   {
     struct locale_dependent_values c_results;
     get_locale_dependent_values (&c_results);
   }
 
-  /* Now use the saved locale again.  */
-  uselocale (mixed);
+  /* Now use the saved locale mixed1 again.  */
+  setlocale (LC_ALL, "C");
+  uselocale (LC_GLOBAL_LOCALE);
+  uselocale (mixed1);
+  {
+    struct locale_dependent_values results;
+    get_locale_dependent_values (&results);
+    ASSERT (strcmp (results.monetary, expected_results.monetary) == 0);
+    ASSERT (strcmp (results.numeric, expected_results.numeric) == 0);
+    ASSERT (strcmp (results.time, expected_results.time) == 0);
+  }
+
+  /* Now use the saved locale mixed2 again.  */
+  setlocale (LC_ALL, "C");
+  uselocale (LC_GLOBAL_LOCALE);
+  uselocale (mixed2);
   {
     struct locale_dependent_values results;
     get_locale_dependent_values (&results);