[easytag] Refactor get_encoding_from_locale()



commit b22f0a517dcb5b2a6b19c86ad3dc946a617cbf3c
Author: David King <amigadave amigadave com>
Date:   Tue Jan 12 23:08:39 2016 +0000

    Refactor get_encoding_from_locale()
    
    Use g_get_locale_variants() when looking up the non-Unicode character
    encoding for a locale, to ensure that variants are checked (such as when
    checking "en_GB", so that "en" is checked). Additionally, treat "utf8"
    as synonymous with "UTF-8" as per locale(7). As a fallback, return
    UTF-8.

 src/charset.c |   68 +++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 49 insertions(+), 19 deletions(-)
---
diff --git a/src/charset.c b/src/charset.c
index 8c764f5..9021790 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -241,37 +241,67 @@ Charset_Insert_Locales_Destroy (void)
     g_hash_table_destroy (encodings);
 }
 
-/* stolen from gnome-desktop-item.c */
+/*
+ * get_encoding_from_locale:
+ * @locale: a locale string, of the form
+ *          language[_territory][ codeset][ modifer]
+ *
+ * Get the legacy (pre-Unicode) character encoding for the @locale, falling
+ * back to a hardcoded table if is not part of @locale, and as a last resort
+ * falling back to UTF-8.
+ *
+ * Returns: the legacy character encoding of @locale, or "UTF-8" on failure
+ */
 const char *
 get_encoding_from_locale (const char *locale)
 {
-    char lang[3];
     const char *encoding;
+    GStrv variants;
+    gsize i;
 
     g_return_val_if_fail (locale != NULL, NULL);
 
-    /* if locale includes encoding, use it *//*
-    encoding = strchr (locale, '.');
-    if (encoding != NULL) {
-        return encoding+1;
-    }*/
-    /* if locale includes encoding (that isn't UTF-8), use it */
+    /* Return early if the encoding is part of the locale. */
     encoding = strchr (locale, '.');
-    if (encoding != NULL && strncmp (encoding, ".UTF-8", 6)) {
-        return encoding+1;
-    }
 
-    /* first try the entire locale (at this point ll_CC) */
-    encoding = g_hash_table_lookup (encodings, locale);
     if (encoding != NULL)
-        return encoding;
+    {
+        /* Ignore UTF-8 (and utf8). */
+        if ((strncmp (encoding, ".UTF-8", 6) != 0)
+            && (strncmp (encoding, ".utf8", 5) != 0))
+        {
+            const gchar *modifier;
 
-    /* Try just the language */
-    strncpy (lang, locale, 2);
-    lang[2] = '\0';
-    return g_hash_table_lookup (encodings, lang);
-}
+            modifier = strchr (encoding ? encoding : locale, '@');
+
+            if (modifier != NULL)
+            {
+                g_warning ("%s",
+                           "Returning modifier in addition to character set");
+            }
+
+            return encoding;
+        }
+    }
+
+    /* Loop over variants of the locale, returning the first match. */
+    variants = g_get_locale_variants (locale);
+
+    for (i = 0; variants[i]; i++)
+    {
+        encoding = g_hash_table_lookup (encodings, variants[i]);
 
+        if (encoding != NULL)
+        {
+            g_strfreev (variants);
+            return encoding;
+        }
+    }
+
+    g_strfreev (variants);
+
+    return "UTF-8";
+}
 
 /*
  * Return the locale from LANG if exists, else from LC_ALL


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]