summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Cîrnaț <cirnatdan@NetBSD.org>2021-04-15 16:09:59 +0200
committerDan Cîrnaț <cirnatdan@NetBSD.org>2021-04-15 17:43:04 +0200
commit856cc6c6820810f0de81e4249a6a60996e0b80c5 (patch)
tree03f592e7716b8b4ba6433fc45a76cff46323c8b3
parent1b722ab622f3e0e8ad199e4f1db650416d198adb (diff)
downloadgnome-desktop-856cc6c6820810f0de81e4249a6a60996e0b80c5.tar.gz
Revert "Revert "Replace usage of non-portable `uselocale` with locale-dependent functions""
This reverts commit 96565763e950e9c281751c5fe35c9ba83cb61ac8.
-rw-r--r--config.h.meson6
-rw-r--r--libgnome-desktop/gnome-gettext-portable.c72
-rw-r--r--libgnome-desktop/gnome-gettext-portable.h42
-rw-r--r--libgnome-desktop/gnome-languages.c76
-rw-r--r--libgnome-desktop/gnome-wall-clock.c9
-rw-r--r--libgnome-desktop/meson.build3
-rw-r--r--meson.build1
-rw-r--r--tests/languages.c58
-rw-r--r--tests/meson.build3
-rw-r--r--tests/wall-clock.c52
-rw-r--r--tests/wallclock-reftest.c17
11 files changed, 234 insertions, 105 deletions
diff --git a/config.h.meson b/config.h.meson
index 75b0170d..2c4778b0 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -27,3 +27,9 @@
/* Define to include GNU extensions */
#mesondefine _GNU_SOURCE
+
+/* define on systems that have the `uselocale` function */
+#mesondefine HAVE_USELOCALE
+
+/* define on system if OS has extended locale header */
+#mesondefine HAVE_XLOCALE
diff --git a/libgnome-desktop/gnome-gettext-portable.c b/libgnome-desktop/gnome-gettext-portable.c
new file mode 100644
index 00000000..aaba4d08
--- /dev/null
+++ b/libgnome-desktop/gnome-gettext-portable.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2021 Dan Cîrnaț <dan@alt.md>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+#include "config.h"
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+
+#ifndef HAVE_USELOCALE
+/**
+ * FIXME: This function does nothing if there's no thread-safe
+ * alternative to uselocale on some systems (NetBSD). Replace it
+ * when an implementation becomes available.
+ */
+locale_t
+uselocale (locale_t newloc)
+{
+ return (locale_t) 0;
+}
+#endif
+
+char *
+dgettext_l (locale_t locale,
+ const char *domain,
+ const char *msgid)
+{
+ locale_t old_locale = uselocale (locale);
+ char *ret = dgettext (domain, msgid);
+ uselocale (old_locale);
+ return ret;
+}
+
+const gchar *
+g_dgettext_l (locale_t locale,
+ const gchar *domain,
+ const gchar *msgid)
+{
+ locale_t old_locale = uselocale (locale);
+ const gchar *ret = g_dgettext (domain, msgid);
+ uselocale (old_locale);
+ return ret;
+}
+
+const gchar *
+g_dpgettext_l (locale_t locale,
+ const gchar *domain,
+ const gchar *msgctxtid,
+ gsize msgidoffset)
+{
+ locale_t old_locale = uselocale (locale);
+ const gchar *ret = g_dpgettext (domain, msgctxtid, msgidoffset);
+ uselocale (old_locale);
+ return ret;
+}
diff --git a/libgnome-desktop/gnome-gettext-portable.h b/libgnome-desktop/gnome-gettext-portable.h
new file mode 100644
index 00000000..c8af3691
--- /dev/null
+++ b/libgnome-desktop/gnome-gettext-portable.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2021 Dan Cîrnaț <dan@alt.md>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <locale.h>
+#include <string.h>
+
+const char *
+dgettext_l (locale_t locale,
+ const char *domain,
+ const char *msgid);
+
+const gchar *
+g_dgettext_l (locale_t locale,
+ const gchar *domain,
+ const gchar *msgid);
+
+const gchar *
+g_dpgettext_l (locale_t locale,
+ const gchar *domain,
+ const gchar *msgctxtid,
+ gsize msgidoffset);
+
+#define _l(locale_t,String) ((char *) g_dgettext_l (locale_t, GETTEXT_PACKAGE, String))
diff --git a/libgnome-desktop/gnome-languages.c b/libgnome-desktop/gnome-languages.c
index d38f9b89..bd62489c 100644
--- a/libgnome-desktop/gnome-languages.c
+++ b/libgnome-desktop/gnome-languages.c
@@ -28,7 +28,6 @@
#include <string.h>
#include <errno.h>
#include <dirent.h>
-#include <locale.h>
#include <langinfo.h>
#include <sys/stat.h>
@@ -36,6 +35,8 @@
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
+#include "gnome-gettext-portable.h"
+
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include "gnome-languages.h"
@@ -303,16 +304,14 @@ language_name_get_codeset_details (const char *language_name,
gboolean *is_utf8)
{
locale_t locale;
- locale_t old_locale;
const char *codeset = NULL;
locale = newlocale (LC_CTYPE_MASK, language_name, (locale_t) 0);
if (locale == (locale_t) 0)
return;
- old_locale = uselocale (locale);
- codeset = nl_langinfo (CODESET);
+ codeset = nl_langinfo_l (CODESET, locale);
if (pcodeset != NULL) {
*pcodeset = g_strdup (codeset);
@@ -324,7 +323,6 @@ language_name_get_codeset_details (const char *language_name,
*is_utf8 = strcmp (normalized_codeset, "UTF-8") == 0;
}
- uselocale (old_locale);
freelocale (locale);
}
@@ -704,28 +702,24 @@ get_translated_language (const char *code,
if (language != NULL) {
const char *translated_name;
locale_t loc = 0;
- locale_t old_locale = 0;
- if (locale != NULL) {
- loc = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0);
- if (loc == (locale_t) 0)
- return NULL;
- old_locale = uselocale (loc);
+ if (locale == NULL) {
+ locale = setlocale (LC_MESSAGES, NULL);
}
+ loc = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0);
+ if (loc == (locale_t) 0)
+ return NULL;
if (is_fallback_language (code)) {
name = g_strdup (_("Unspecified"));
} else {
g_autofree char *tmp = NULL;
- translated_name = dgettext ("iso_639", language);
+ translated_name = dgettext_l (loc, "iso_639", language);
tmp = get_first_item_in_semicolon_list (translated_name);
name = capitalize_utf8_string (tmp);
}
- if (locale != NULL) {
- uselocale (old_locale);
- freelocale (loc);
- }
+ freelocale (loc);
}
return name;
@@ -762,24 +756,20 @@ get_translated_territory (const char *code,
if (territory != NULL) {
const char *translated_territory;
locale_t loc;
- locale_t old_locale = 0;
g_autofree char *tmp = NULL;
- if (locale != NULL) {
- loc = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0);
- if (loc == (locale_t) 0)
- return NULL;
- old_locale = uselocale (loc);
+ if (locale == NULL) {
+ locale = setlocale (LC_MESSAGES, NULL);
}
+ loc = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0);
+ if (loc == (locale_t) 0)
+ return NULL;
- translated_territory = dgettext ("iso_3166", territory);
+ translated_territory = dgettext_l (loc, "iso_3166", territory);
tmp = get_first_item_in_semicolon_list (translated_territory);
name = capitalize_utf8_string (tmp);
- if (locale != NULL) {
- uselocale (old_locale);
- freelocale (loc);
- }
+ freelocale (loc);
}
return name;
@@ -1359,16 +1349,15 @@ gnome_get_translated_modifier (const char *modifier,
char *retval;
GHashTable *modifiers_map;
locale_t loc;
- locale_t old_locale;
g_return_val_if_fail (modifier != NULL, NULL);
- if (translation != NULL) {
- loc = newlocale (LC_MESSAGES_MASK, translation, (locale_t) 0);
- if (loc == (locale_t) 0) {
- return NULL;
- }
- old_locale = uselocale (loc);
+ if (translation == NULL) {
+ translation = setlocale (LC_MESSAGES, NULL);
+ }
+ loc = newlocale (LC_MESSAGES_MASK, translation, (locale_t) 0);
+ if (loc == (locale_t) 0) {
+ return NULL;
}
/* Modifiers as listed in glibc's SUPPORTED file:
@@ -1379,26 +1368,26 @@ gnome_get_translated_modifier (const char *modifier,
/* TRANSLATORS: Used to distinguish the labels representing the gez_ER
and gez_ET locales from gez_ER@abegede respective gez_ET@abegede. The
difference is related to collation. */
- g_hash_table_insert (modifiers_map, "abegede", _("Abegede"));
+ g_hash_table_insert (modifiers_map, "abegede", _l(loc, "Abegede"));
/* TRANSLATORS: Used to distinguish Cyrillic from Latin written language variants. */
- g_hash_table_insert (modifiers_map, "cyrillic", _("Cyrillic"));
+ g_hash_table_insert (modifiers_map, "cyrillic", _l(loc, "Cyrillic"));
/* TRANSLATORS: Also known as "Nagari", a written variant for many languages
of the Indian subcontinent. See:
https://en.wikipedia.org/wiki/Devanagari */
- g_hash_table_insert (modifiers_map, "devanagari", _("Devanagari"));
+ g_hash_table_insert (modifiers_map, "devanagari", _l(loc, "Devanagari"));
/* TRANSLATORS: Used to distinguish the label representing the tt_RU
locale from tt_RU@iqtelif. It's a special alphabet for Tatar. */
- g_hash_table_insert (modifiers_map, "iqtelif", _("IQTElif"));
+ g_hash_table_insert (modifiers_map, "iqtelif", _l(loc, "IQTElif"));
/* TRANSLATORS: The alphabet/script, not the language. Used to distinguish
Latin from Cyrillic written language variants. */
- g_hash_table_insert (modifiers_map, "latin", _("Latin"));
+ g_hash_table_insert (modifiers_map, "latin", _l(loc, "Latin"));
/* TRANSLATORS: "Saho" is a variant of the Afar language. Used to
distinguish the label representing the aa_ER locale from aa_ER@saaho. */
- g_hash_table_insert (modifiers_map, "saaho", _("Saho"));
+ g_hash_table_insert (modifiers_map, "saaho", _l(loc, "Saho"));
/* TRANSLATORS: "Valencia" is a dialect of the Catalan language spoken
in Valencia. Used to distinguish the label representing the ca_ES
locale from ca_ES@valencia. */
- g_hash_table_insert (modifiers_map, "valencia", _("Valencia"));
+ g_hash_table_insert (modifiers_map, "valencia", _l(loc, "Valencia"));
if (g_hash_table_contains (modifiers_map, modifier))
retval = g_strdup (g_hash_table_lookup (modifiers_map, modifier));
@@ -1407,10 +1396,7 @@ gnome_get_translated_modifier (const char *modifier,
g_hash_table_destroy (modifiers_map);
- if (translation != NULL) {
- uselocale (old_locale);
- freelocale (loc);
- }
+ freelocale (loc);
return retval;
}
diff --git a/libgnome-desktop/gnome-wall-clock.c b/libgnome-desktop/gnome-wall-clock.c
index caede60d..b4d72b87 100644
--- a/libgnome-desktop/gnome-wall-clock.c
+++ b/libgnome-desktop/gnome-wall-clock.c
@@ -24,8 +24,8 @@
#include "config.h"
-#include <locale.h>
#include <glib/gi18n-lib.h>
+#include "gnome-gettext-portable.h"
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include "gnome-wall-clock.h"
@@ -289,18 +289,13 @@ translate_time_format_string (const char *str)
const char *locale = g_getenv ("LC_TIME");
const char *res;
char *sep;
- locale_t old_loc;
locale_t loc = (locale_t)0;
if (locale)
loc = newlocale (LC_MESSAGES_MASK, locale, (locale_t)0);
- old_loc = uselocale (loc);
-
sep = strchr (str, '\004');
- res = g_dpgettext (GETTEXT_PACKAGE, str, sep ? sep - str + 1 : 0);
-
- uselocale (old_loc);
+ res = g_dpgettext_l (loc, GETTEXT_PACKAGE, str, sep ? sep - str + 1 : 0);
if (loc != (locale_t)0)
freelocale (loc);
diff --git a/libgnome-desktop/meson.build b/libgnome-desktop/meson.build
index 483f1ff6..8c3a2dfd 100644
--- a/libgnome-desktop/meson.build
+++ b/libgnome-desktop/meson.build
@@ -48,7 +48,8 @@ libgnome_desktop_sources = [
'default-input-sources.h',
'meta-xrandr-shared.h',
'gnome-desktop-thumbnail-script.c',
- 'gnome-desktop-thumbnail-script.h'
+ 'gnome-desktop-thumbnail-script.h',
+ 'gnome-gettext-portable.c'
]
libgnome_desktop_headers = [
diff --git a/meson.build b/meson.build
index 3efd6773..490d43e6 100644
--- a/meson.build
+++ b/meson.build
@@ -94,6 +94,7 @@ conf.set('HAVE_XKBREGISTRY', xkbregistry_dep.found())
conf.set('HAVE_TIMERFD', cc.has_function('timerfd_create'))
conf.set('HAVE_OPENAT', cc.has_function('openat'))
+conf.set('HAVE_USELOCALE', cc.has_function('uselocale'))
config_h = declare_dependency(
sources: configure_file(
diff --git a/tests/languages.c b/tests/languages.c
new file mode 100644
index 00000000..34c1cc02
--- /dev/null
+++ b/tests/languages.c
@@ -0,0 +1,58 @@
+/* -*- mode: C; c-file-style: "linux"; indent-tabs-mode: t -*-
+ *
+ * Copyright (C) 2021 Dan Cîrnaț <dan@alt.md>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <gdesktop-enums.h>
+#include <glib.h>
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-languages.h>
+#include <locale.h>
+#include <string.h>
+
+static void
+test_using_null_locale (void)
+{
+ const char *translated_territory;
+ const char *translated_language;
+ const char *translated_modifier;
+
+ translated_territory = gnome_get_country_from_code("US", NULL);
+ g_assert (translated_territory != NULL);
+
+ translated_language = gnome_get_language_from_locale("ro", NULL);
+ g_assert (translated_language != NULL);
+
+ translated_modifier = gnome_get_translated_modifier("euro", NULL);
+ g_assert (translated_modifier != NULL);
+
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
+
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/languages/using-null-locale", test_using_null_locale);
+
+ return g_test_run ();
+}
diff --git a/tests/meson.build b/tests/meson.build
index 6ad97ebd..8333a810 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -13,7 +13,8 @@ test_env = [
test_programs = [
'wall-clock',
- 'wallclock-reftest'
+ 'wallclock-reftest',
+ 'languages'
]
test_metas = []
diff --git a/tests/wall-clock.c b/tests/wall-clock.c
index 486cfa38..0e8c49c9 100644
--- a/tests/wall-clock.c
+++ b/tests/wall-clock.c
@@ -36,8 +36,7 @@ test_utf8_character (const char *utf8_char,
{
GDateTime *datetime;
GnomeWallClock *clock;
- locale_t locale;
- locale_t save_locale;
+ const char *save_locale;
const char *str;
/* When testing that UTF8 locales don't use double spaces
@@ -47,9 +46,7 @@ test_utf8_character (const char *utf8_char,
/* In the C locale, make sure the time string is formatted with regular
* colons */
- locale = newlocale (LC_ALL_MASK, "C", (locale_t) 0);
- g_assert_true (locale != (locale_t)0);
- save_locale = uselocale (locale);
+ save_locale = setlocale (LC_ALL, NULL);
clock = gnome_wall_clock_new ();
str = gnome_wall_clock_string_for_datetime (clock,
datetime,
@@ -60,13 +57,7 @@ test_utf8_character (const char *utf8_char,
g_object_unref (clock);
/* In a UTF8 locale, we want ratio characters and no colons. */
- locale = newlocale (LC_ALL_MASK, "en_US.utf8", locale);
- if (locale == (locale_t)0) {
- g_test_message ("en_US.utf8 locale not found");
- g_test_fail ();
- return;
- }
- uselocale (locale);
+ setlocale (LC_ALL, "en_US.utf8");
clock = gnome_wall_clock_new ();
str = gnome_wall_clock_string_for_datetime (clock,
datetime,
@@ -78,13 +69,7 @@ test_utf8_character (const char *utf8_char,
/* ... and same thing with an RTL locale: should be formatted with
* ratio characters */
- locale = newlocale (LC_ALL_MASK, "he_IL.utf8", locale);
- if (locale == (locale_t)0) {
- g_test_message ("he_IL.utf8 locale not found");
- g_test_fail ();
- return;
- }
- uselocale (locale);
+ setlocale (LC_ALL, "he_IL.utf8");
clock = gnome_wall_clock_new ();
str = gnome_wall_clock_string_for_datetime (clock,
datetime,
@@ -97,8 +82,7 @@ test_utf8_character (const char *utf8_char,
g_date_time_unref (datetime);
/* Restore previous locale */
- uselocale (save_locale);
- freelocale (locale);
+ setlocale (LC_ALL, save_locale);
}
static void
@@ -118,17 +102,11 @@ test_clock_format_setting (void)
{
GnomeWallClock *clock;
GSettings *settings;
- locale_t locale;
- locale_t save_locale;
+ const char *save_locale;
const char *str;
- locale = newlocale (LC_ALL_MASK, "en_US.utf8", (locale_t) 0);
- if (locale == (locale_t)0) {
- g_test_message ("en_US.utf8 locale not found");
- g_test_fail ();
- return;
- }
- save_locale = uselocale (locale);
+ save_locale = setlocale (LC_ALL, NULL);
+ setlocale (LC_ALL, "en_US.utf8");
settings = g_settings_new ("org.gnome.desktop.interface");
@@ -149,8 +127,7 @@ test_clock_format_setting (void)
g_object_unref (settings);
/* Restore previous locale */
- uselocale (save_locale);
- freelocale (locale);
+ setlocale (LC_ALL, save_locale);
}
static gboolean
@@ -202,14 +179,12 @@ test_weekday_setting (void)
{
GnomeWallClock *clock;
GSettings *settings;
- locale_t locale;
- locale_t save_locale;
+ const char *save_locale;
const char *str, *ptr, *s;
/* Save current locale */
- locale = newlocale (LC_ALL_MASK, "C", (locale_t) 0);
- g_assert_true (locale != (locale_t)0);
- save_locale = uselocale (locale);
+ save_locale = setlocale (LC_ALL, NULL);
+ setlocale (LC_ALL, "C");
settings = g_settings_new ("org.gnome.desktop.interface");
/* Set 24h format, so that the only alphabetical part will be the weekday */
@@ -245,8 +220,7 @@ test_weekday_setting (void)
g_object_unref (settings);
/* Restore previous locale */
- uselocale (save_locale);
- freelocale (locale);
+ setlocale (LC_ALL, save_locale);
}
int
diff --git a/tests/wallclock-reftest.c b/tests/wallclock-reftest.c
index 1238ea89..e6026032 100644
--- a/tests/wallclock-reftest.c
+++ b/tests/wallclock-reftest.c
@@ -439,21 +439,15 @@ test_ui_file (GFile *file,
GnomeWallClock *clock;
GDateTime *datetime;
char *str;
- locale_t loc, previous_locale;
+ const char *previous_locale;
ui_file = g_file_get_path (file);
locale = get_locale_for_file (ui_file);
g_assert (locale);
- loc = newlocale (LC_ALL_MASK, locale, (locale_t) 0);
- if (loc == (locale_t)0)
- {
- g_test_message ("locale '%s' not found", locale);
- g_test_fail();
- return;
- }
- previous_locale = uselocale (loc);
- g_assert_true (previous_locale != (locale_t) 0);
+ previous_locale = setlocale (LC_ALL, NULL);
+ setlocale (LC_ALL, locale);
+ g_assert_true (previous_locale != NULL);
clock = gnome_wall_clock_new ();
datetime = g_date_time_new_local (2014, 5, 28, 23, 59, 59);
@@ -465,8 +459,7 @@ test_ui_file (GFile *file,
g_date_time_unref (datetime);
g_object_unref (clock);
- uselocale (previous_locale);
- freelocale (loc);
+ setlocale (LC_ALL, previous_locale);
provider = add_extra_css (ui_file, ".css");