locale-util: normalize UTF-8 locale names
authorLennart Poettering <lennart@poettering.net>
Fri, 12 Jul 2019 11:37:13 +0000 (13:37 +0200)
committerLennart Poettering <lennart@poettering.net>
Sun, 14 Jul 2019 09:05:34 +0000 (11:05 +0200)
Let's generate out lists in the format people expect.

src/basic/locale-util.c

index ce9daff..17302ab 100644 (file)
 #include "strv.h"
 #include "utf8.h"
 
+static char *normalize_locale(const char *name) {
+        const char *e;
+
+        /* Locale names are weird: glibc has some magic rules when looking for the charset name on disk: it
+         * lowercases everything, and removes most special chars. This means the official .UTF-8 suffix
+         * becomes .utf8 when looking things up on disk. When enumerating locales, let's do the reverse
+         * operation, and go back to ".UTF-8" which appears to be the more commonly accepted name. We only do
+         * that for UTF-8 however, since it's kinda the only charset that matters. */
+
+        e = endswith(name, ".utf8");
+        if (e) {
+                _cleanup_free_ char *prefix = NULL;
+
+                prefix = strndup(name, e - name);
+                if (!prefix)
+                        return NULL;
+
+                return strjoin(prefix, ".UTF-8");
+        }
+
+        e = strstr(name, ".utf8@");
+        if (e) {
+                _cleanup_free_ char *prefix = NULL;
+
+                prefix = strndup(name, e - name);
+                if (!prefix)
+                        return NULL;
+
+                return strjoin(prefix, ".UTF-8@", e + 6);
+        }
+
+        return strdup(name);
+}
+
 static int add_locales_from_archive(Set *locales) {
         /* Stolen from glibc... */
 
@@ -107,7 +141,7 @@ static int add_locales_from_archive(Set *locales) {
                 if (!utf8_is_valid((char*) p + e[i].name_offset))
                         continue;
 
-                z = strdup((char*) p + e[i].name_offset);
+                z = normalize_locale((char*) p + e[i].name_offset);
                 if (!z) {
                         r = -ENOMEM;
                         goto finish;
@@ -144,7 +178,7 @@ static int add_locales_from_libdir (Set *locales) {
                 if (entry->d_type != DT_DIR)
                         continue;
 
-                z = strdup(entry->d_name);
+                z = normalize_locale(entry->d_name);
                 if (!z)
                         return -ENOMEM;