[gnome-desktop] Obtain supported locales from "locale -a" output.
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-desktop] Obtain supported locales from "locale -a" output.
- Date: Wed, 2 Oct 2013 14:42:13 +0000 (UTC)
commit 91082e8d0ef7dc3fe372fb5228fd3bb5a26efa81
Author: Stefan Sperling <stsp openbsd org>
Date: Wed Aug 28 18:25:34 2013 +0200
Obtain supported locales from "locale -a" output.
Instead of parsing the locale archive file which is private to glibc
(see https://bugzilla.redhat.com/show_bug.cgi?id=956993), run the
"locale -a" command to obtain the list of supported locales.
"locale -a" is specified in POSIX and should thus exist on most UNIX-like
systems (e.g. on OpenBSD, which triggered the related bugzilla entry
because GNOME was unable to find a list of supported locales).
Keep scanning the /usr/share/locale directory as a fallback.
Remove code wrapped in #ifdef WITH_INCOMPLETE_LOCALES. This code was
inherited from gdm but is now unused.
https://bugzilla.gnome.org/show_bug.cgi?id=698383
libgnome-desktop/gnome-languages.c | 150 ++++++++---------------------------
1 files changed, 35 insertions(+), 115 deletions(-)
---
diff --git a/libgnome-desktop/gnome-languages.c b/libgnome-desktop/gnome-languages.c
index 18e3705..667eb81 100644
--- a/libgnome-desktop/gnome-languages.c
+++ b/libgnome-desktop/gnome-languages.c
@@ -44,10 +44,7 @@
#ifndef __LC_LAST
#define __LC_LAST 13
#endif
-#include "locarchive.h"
-#define ARCHIVE_FILE LIBLOCALEDIR "/locale-archive"
-#define SYSTEM_ARCHIVE_FILE "/usr/lib/locale/locale-archive"
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
@@ -310,11 +307,7 @@ language_name_is_valid (const char *language_name)
{
char *old_locale;
gboolean is_valid;
-#ifdef WITH_INCOMPLETE_LOCALES
- int lc_type_id = LC_CTYPE;
-#else
int lc_type_id = LC_MESSAGES;
-#endif
old_locale = g_strdup (setlocale (lc_type_id, NULL));
is_valid = setlocale (lc_type_id, language_name) != NULL;
@@ -445,22 +438,11 @@ add_locale (const char *language_name,
g_free (name);
name = NULL;
-#ifdef WITH_INCOMPLETE_LOCALES
- if (utf8_only) {
- if (locale->territory_code == NULL || locale->modifier) {
- g_debug ("Ignoring '%s' as a locale, since it lacks territory code or modifier",
name);
- gnome_locale_free (locale);
- return FALSE;
- }
- }
-#endif
-
locale->id = construct_language_name (locale->language_code, locale->territory_code,
NULL, locale->modifier);
locale->name = construct_language_name (locale->language_code, locale->territory_code,
locale->codeset, locale->modifier);
-#ifndef WITH_INCOMPLETE_LOCALES
if (!gnome_language_has_translations (locale->name) &&
!gnome_language_has_translations (locale->id) &&
!gnome_language_has_translations (locale->language_code) &&
@@ -469,7 +451,6 @@ add_locale (const char *language_name,
gnome_locale_free (locale);
return FALSE;
}
-#endif
if (!utf8_only) {
g_free (locale->id);
@@ -492,94 +473,9 @@ add_locale (const char *language_name,
struct nameent
{
char *name;
- uint32_t locrec_offset;
+ guint32 locrec_offset;
};
-static gboolean
-mapped_file_new_allow_noent (const char *path,
- GMappedFile **out_mfile,
- GError **error)
-{
- gboolean ret = FALSE;
- GError *tmp_error = NULL;
- GMappedFile *mfile = NULL;
-
- mfile = g_mapped_file_new (path, FALSE, &tmp_error);
- if (mfile == NULL) {
- if (!g_error_matches (tmp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
- g_propagate_error (error, tmp_error);
- goto out;
- }
- g_clear_error (&tmp_error);
- }
-
- ret = TRUE;
- out:
- *out_mfile = mfile;
- return ret;
-}
-
-static gboolean
-collect_locales_from_archive (gboolean *out_found_locales,
- GError **error)
-{
- gboolean ret = FALSE;
- GMappedFile *mapped;
- char *addr;
- struct locarhead *head;
- struct namehashent *namehashtab;
- struct nameent *names = NULL;
- uint32_t used;
- uint32_t cnt;
- gsize len;
- gboolean locales_collected = FALSE;
-
- if (!mapped_file_new_allow_noent (ARCHIVE_FILE, &mapped, error))
- goto out;
- if (!mapped) {
- if (!mapped_file_new_allow_noent (SYSTEM_ARCHIVE_FILE, &mapped, error))
- goto out;
- }
- if (!mapped) {
- goto out_success;
- }
-
- addr = g_mapped_file_get_contents (mapped);
- len = g_mapped_file_get_length (mapped);
-
- head = (struct locarhead *) addr;
- if (head->namehash_offset + head->namehash_size > len
- || head->string_offset + head->string_size > len
- || head->locrectab_offset + head->locrectab_size > len
- || head->sumhash_offset + head->sumhash_size > len) {
- goto out;
- }
-
- namehashtab = (struct namehashent *) (addr + head->namehash_offset);
-
- names = (struct nameent *) g_new0 (struct nameent, head->namehash_used);
- for (cnt = used = 0; cnt < head->namehash_size; ++cnt) {
- if (namehashtab[cnt].locrec_offset != 0) {
- names[used].name = addr + namehashtab[cnt].name_offset;
- names[used++].locrec_offset = namehashtab[cnt].locrec_offset;
- }
- }
-
- for (cnt = 0; cnt < used; ++cnt) {
- if (add_locale (names[cnt].name, TRUE))
- locales_collected = TRUE;
- }
-
-
- out_success:
- ret = TRUE;
- *out_found_locales = locales_collected;
- out:
- g_free (names);
- g_clear_pointer (&mapped, g_mapped_file_unref);
- return ret;
-}
-
static int
select_dirs (const struct dirent *dirent)
{
@@ -631,6 +527,37 @@ collect_locales_from_directory (void)
return found_locales;
}
+static gboolean
+collect_locales_from_localebin (void)
+{
+ gboolean found_locales = FALSE;
+ gchar *argv[] = { "locale", "-a", NULL };
+ gchar *output;
+ gchar **lines, **linep;
+
+ if (g_spawn_sync (NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH|G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL, &output, NULL, NULL, NULL) == FALSE)
+ return FALSE;
+
+ g_return_val_if_fail (output != NULL, FALSE);
+
+ lines = g_strsplit (output, "\n", 0);
+ if (lines) {
+ linep = lines;
+ while (*linep) {
+ if (*linep[0] && add_locale (*linep, TRUE))
+ found_locales = TRUE;
+ linep++;
+ }
+ g_strfreev(lines);
+ }
+
+ g_free(output);
+
+ return found_locales;
+}
+
static void
count_languages_and_territories (void)
{
@@ -667,28 +594,21 @@ count_languages_and_territories (void)
static void
collect_locales (void)
{
- gboolean found_archive_locales = FALSE;
+ gboolean found_localebin_locales = FALSE;
gboolean found_dir_locales = FALSE;
- GError *error = NULL;
if (gnome_available_locales_map == NULL) {
gnome_available_locales_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gnome_locale_free);
}
-
- if (!collect_locales_from_archive (&found_archive_locales, &error)) {
- g_warning ("Failed to load locales from archive: %s", error->message);
- g_clear_error (&error);
- }
+ found_localebin_locales = collect_locales_from_localebin ();
found_dir_locales = collect_locales_from_directory ();
- if (!(found_archive_locales || found_dir_locales)) {
-#ifndef WITH_INCOMPLETE_LOCALES
+ if (!(found_localebin_locales || found_dir_locales)) {
g_warning ("Could not read list of available locales from libc, "
"guessing possible locales from available translations, "
"but list may be incomplete!");
-#endif
}
count_languages_and_territories ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]