Make _g_compute_locale_variants return a char** directly
authorChristian Persch <chpe@gnome.org>
Mon, 1 Mar 2010 15:32:09 +0000 (16:32 +0100)
committerChristian Persch <chpe@gnome.org>
Wed, 5 Jan 2011 21:49:21 +0000 (22:49 +0100)
Bug #635998.

glib/gkeyfile.c
glib/gutils.c

index 10ca2a2..db90062 100644 (file)
@@ -1630,7 +1630,7 @@ g_key_file_set_locale_string (GKeyFile     *key_file,
   g_free (value);
 }
 
-extern GSList *_g_compute_locale_variants (const gchar *locale);
+extern gchar **_g_compute_locale_variants (const gchar *locale);
 
 /**
  * g_key_file_get_locale_string:
@@ -1677,16 +1677,7 @@ g_key_file_get_locale_string (GKeyFile     *key_file,
 
   if (locale)
     {
-      GSList *l, *list;
-
-      list = _g_compute_locale_variants (locale);
-
-      languages = g_new (gchar *, g_slist_length (list) + 1);
-      for (l = list, i = 0; l; l = l->next, i++)
-       languages[i] = l->data;
-      languages[i] = NULL;
-
-      g_slist_free (list);
+      languages = _g_compute_locale_variants (locale);
       free_languages = TRUE;
     }
   else
index 73165ba..3e01dae 100644 (file)
@@ -68,6 +68,7 @@
 #include "gtestutils.h"
 #include "gunicode.h"
 #include "gstrfuncs.h"
+#include "garray.h"
 #include "glibintl.h"
 
 #ifdef G_PLATFORM_WIN32
@@ -3157,36 +3158,39 @@ explode_locale (const gchar *locale,
  *       but it is big, ugly, and complicated, so I'm reluctant
  *       to do so when this should handle 99% of the time...
  */
-GSList *
-_g_compute_locale_variants (const gchar *locale)
+static void
+append_locale_variants (GPtrArray *array,
+                        const gchar *locale)
 {
-  GSList *retval = NULL;
-
   gchar *language = NULL;
   gchar *territory = NULL;
   gchar *codeset = NULL;
   gchar *modifier = NULL;
 
   guint mask;
-  guint i;
+  guint i, j;
 
-  g_return_val_if_fail (locale != NULL, NULL);
+  g_return_if_fail (locale != NULL);
 
   mask = explode_locale (locale, &language, &territory, &codeset, &modifier);
 
   /* Iterate through all possible combinations, from least attractive
    * to most attractive.
    */
-  for (i = 0; i <= mask; i++)
-    if ((i & ~mask) == 0)
-      {
-       gchar *val = g_strconcat (language,
-                                 (i & COMPONENT_TERRITORY) ? territory : "",
-                                 (i & COMPONENT_CODESET) ? codeset : "",
-                                 (i & COMPONENT_MODIFIER) ? modifier : "",
-                                 NULL);
-       retval = g_slist_prepend (retval, val);
-      }
+  for (j = 0; j <= mask; ++j)
+    {
+      i = mask - j;
+
+      if ((i & ~mask) == 0)
+        {
+          gchar *val = g_strconcat (language,
+                                    (i & COMPONENT_TERRITORY) ? territory : "",
+                                    (i & COMPONENT_CODESET) ? codeset : "",
+                                    (i & COMPONENT_MODIFIER) ? modifier : "",
+                                    NULL);
+          g_ptr_array_add (array, val);
+        }
+    }
 
   g_free (language);
   if (mask & COMPONENT_CODESET)
@@ -3195,8 +3199,20 @@ _g_compute_locale_variants (const gchar *locale)
     g_free (territory);
   if (mask & COMPONENT_MODIFIER)
     g_free (modifier);
+}
 
-  return retval;
+gchar **
+_g_compute_locale_variants (const gchar *locale)
+{
+  GPtrArray *array;
+
+  g_return_val_if_fail (locale != NULL, NULL);
+
+  array = g_ptr_array_sized_new (8);
+  append_locale_variants (array, locale);
+  g_ptr_array_add (array, NULL);
+
+  return (gchar **) g_ptr_array_free (array, FALSE);
 }
 
 /* The following is (partly) taken from the gettext package.
@@ -3305,31 +3321,23 @@ g_get_language_names (void)
 
   if (!(cache->languages && strcmp (cache->languages, value) == 0))
     {
-      gchar **languages;
+      GPtrArray *array;
       gchar **alist, **a;
-      GSList *list, *l;
-      gint i;
 
       g_free (cache->languages);
       g_strfreev (cache->language_names);
       cache->languages = g_strdup (value);
 
+      array = g_ptr_array_sized_new (8);
+
       alist = g_strsplit (value, ":", 0);
-      list = NULL;
       for (a = alist; *a; a++)
-       {
-         gchar *b = unalias_lang (*a);
-         list = g_slist_concat (list, _g_compute_locale_variants (b));
-       }
+        append_locale_variants (array, unalias_lang (*a));
       g_strfreev (alist);
-      list = g_slist_append (list, g_strdup ("C"));
-
-      cache->language_names = languages = g_new (gchar *, g_slist_length (list) + 1);
-      for (l = list, i = 0; l; l = l->next, i++)
-       languages[i] = l->data;
-      languages[i] = NULL;
+      g_ptr_array_add (array, g_strdup ("C"));
+      g_ptr_array_add (array, NULL);
 
-      g_slist_free (list);
+      cache->language_names = (gchar **) g_ptr_array_free (array, FALSE);
     }
 
   return (G_CONST_RETURN gchar * G_CONST_RETURN *) cache->language_names;