summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2023-08-16 13:24:18 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2023-08-16 13:24:18 +0000
commit954b15218c9a104e12ea9878a0ef4723bf3a6c00 (patch)
tree76703b7da9f77dc3e7d74ec5b4f1e310c7580d17
parent4a60527f2e3f0224e7b7a6726893ec95a024ef1c (diff)
parent306d4567d2b055fef64fdc5e7119a36f205cc694 (diff)
downloadglib-954b15218c9a104e12ea9878a0ef4723bf3a6c00.tar.gz
Merge branch 'mcatanzaro/l10n-time' into 'main'
gsettingsschema: fix l10n=time attribute Closes #2575 See merge request GNOME/glib!2422
-rw-r--r--gio/gsettingsschema.c32
-rw-r--r--gio/tests/de.po3
-rw-r--r--gio/tests/gsettings.c168
-rw-r--r--gio/tests/org.gtk.test.gschema.xml.orig3
4 files changed, 178 insertions, 28 deletions
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index fb3bb7012..b3ac2f189 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -32,6 +32,11 @@
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_XLOCALE_H
+/* Needed on macOS and FreeBSD for uselocale() */
+#include <xlocale.h>
+#endif
+
/**
* SECTION:gsettingsschema
* @short_description: Introspecting and controlling the loading
@@ -1416,9 +1421,14 @@ g_settings_schema_key_range_fixup (GSettingsSchemaKey *key,
GVariant *
g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key)
{
- const gchar *translated;
+ const gchar *translated = NULL;
GError *error = NULL;
const gchar *domain;
+#ifdef HAVE_USELOCALE
+ const gchar *lc_time;
+ locale_t old_locale;
+ locale_t locale;
+#endif
GVariant *value;
domain = g_settings_schema_get_gettext_domain (key->schema);
@@ -1427,9 +1437,25 @@ g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key)
/* translation not requested for this key */
return NULL;
+#ifdef HAVE_USELOCALE
if (key->lc_char == 't')
- translated = g_dcgettext (domain, key->unparsed, LC_TIME);
- else
+ {
+ lc_time = setlocale (LC_TIME, NULL);
+ if (lc_time)
+ {
+ locale = newlocale (LC_MESSAGES_MASK, lc_time, (locale_t) 0);
+ if (locale != (locale_t) 0)
+ {
+ old_locale = uselocale (locale);
+ translated = g_dgettext (domain, key->unparsed);
+ uselocale (old_locale);
+ freelocale (locale);
+ }
+ }
+ }
+#endif
+
+ if (translated == NULL)
translated = g_dgettext (domain, key->unparsed);
if (translated == key->unparsed)
diff --git a/gio/tests/de.po b/gio/tests/de.po
index eed161c68..00531960b 100644
--- a/gio/tests/de.po
+++ b/gio/tests/de.po
@@ -15,3 +15,6 @@ msgstr "\"Unbenannt\""
msgctxt "keyboard label"
msgid "\"BackSpace\""
msgstr "\"Löschen\""
+
+msgid "\"12:00 AM\""
+msgstr "\"00:00\"" \ No newline at end of file
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index 182e79e0a..aa30140ae 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -1,3 +1,5 @@
+#include "config.h"
+
#include <stdlib.h>
#include <locale.h>
#include <libintl.h>
@@ -10,6 +12,11 @@
#include "testenum.h"
+#ifdef HAVE_XLOCALE_H
+/* Needed on macOS and FreeBSD for uselocale() */
+#include <xlocale.h>
+#endif
+
static const gchar *locale_dir = ".";
static gboolean backend_set;
@@ -747,7 +754,7 @@ test_atomic (void)
* 1) The C library doesn't use LC_MESSAGES, that is implemented only
* in libintl (defined in its <libintl.h>).
*
- * 2) The locale names that setlocale() accepts and returns aren't in
+ * 2) The locale names that uselocale() accepts and returns aren't in
* the "de_DE" style, but like "German_Germany".
*
* 3) libintl looks at the Win32 thread locale and not the C library
@@ -765,29 +772,46 @@ test_atomic (void)
static void
test_l10n (void)
{
+#ifndef HAVE_USELOCALE
+ g_test_skip ("Unsafe to change locale because platform does not support uselocale()");
+#else
GSettings *settings;
gchar *str;
- gchar *locale;
+ locale_t original_locale;
+ locale_t new_locale;
+ locale_t result;
bindtextdomain ("test", locale_dir);
bind_textdomain_codeset ("test", "UTF-8");
- locale = g_strdup (setlocale (LC_MESSAGES, NULL));
+ original_locale = uselocale ((locale_t) 0);
+ g_assert_true (original_locale != (locale_t) 0);
+ new_locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t) 0);
+ g_assert_true (new_locale != (locale_t) 0);
+ result = uselocale (new_locale);
+ g_assert_true (result == original_locale);
settings = g_settings_new ("org.gtk.test.localized");
-
- g_setenv ("LC_MESSAGES", "C", TRUE);
- setlocale (LC_MESSAGES, "C");
str = g_settings_get_string (settings, "error-message");
- g_setenv ("LC_MESSAGES", locale, TRUE);
- setlocale (LC_MESSAGES, locale);
+
+ result = uselocale (original_locale);
+ g_assert_true (result == new_locale);
+ freelocale (new_locale);
g_assert_cmpstr (str, ==, "Unnamed");
g_free (str);
str = NULL;
- g_setenv ("LC_MESSAGES", "de_DE.UTF-8", TRUE);
- setlocale (LC_MESSAGES, "de_DE.UTF-8");
+ new_locale = newlocale (LC_MESSAGES_MASK, "de_DE.UTF-8", (locale_t) 0);
+ if (new_locale == (locale_t) 0)
+ {
+ g_test_skip ("Cannot run test becaues de_DE.UTF-8 locale is not available");
+ g_object_unref (settings);
+ return;
+ }
+ result = uselocale (new_locale);
+ g_assert_true (result == original_locale);
+
/* Only do the test if translation is actually working... */
if (g_str_equal (dgettext ("test", "\"Unnamed\""), "\"Unbenannt\""))
{
@@ -802,10 +826,12 @@ test_l10n (void)
g_test_skip ("translation is not working");
}
- g_setenv ("LC_MESSAGES", locale, TRUE);
- setlocale (LC_MESSAGES, locale);
- g_free (locale);
+ result = uselocale (original_locale);
+ g_assert_true (result == new_locale);
+ freelocale (new_locale);
+
g_object_unref (settings);
+#endif
}
/* Test that message context works as expected with translated
@@ -818,39 +844,130 @@ test_l10n (void)
static void
test_l10n_context (void)
{
+#ifndef HAVE_USELOCALE
+ g_test_skip ("Unsafe to change locale because platform does not support uselocale()");
+#else
GSettings *settings;
gchar *str;
- gchar *locale;
+ locale_t original_locale;
+ locale_t new_locale;
+ locale_t result;
bindtextdomain ("test", locale_dir);
bind_textdomain_codeset ("test", "UTF-8");
- locale = g_strdup (setlocale (LC_MESSAGES, NULL));
-
settings = g_settings_new ("org.gtk.test.localized");
- g_setenv ("LC_MESSAGES", "C", TRUE);
- setlocale (LC_MESSAGES, "C");
+ original_locale = uselocale ((locale_t) 0);
+ g_assert_true (original_locale != (locale_t) 0);
+ new_locale = newlocale (LC_MESSAGES_MASK, "C", (locale_t) 0);
+ g_assert_true (new_locale != (locale_t) 0);
+ result = uselocale (new_locale);
+ g_assert_true (result == original_locale);
+
g_settings_get (settings, "backspace", "s", &str);
- g_setenv ("LC_MESSAGES", locale, TRUE);
- setlocale (LC_MESSAGES, locale);
+
+ result = uselocale (original_locale);
+ g_assert_true (result == new_locale);
+ freelocale (new_locale);
g_assert_cmpstr (str, ==, "BackSpace");
g_free (str);
str = NULL;
- g_setenv ("LC_MESSAGES", "de_DE.UTF-8", TRUE);
- setlocale (LC_MESSAGES, "de_DE.UTF-8");
+ new_locale = newlocale (LC_MESSAGES_MASK, "de_DE.UTF-8", (locale_t) 0);
+ if (new_locale == (locale_t) 0)
+ {
+ g_test_skip ("Cannot run test becaues de_DE.UTF-8 locale is not available");
+ g_object_unref (settings);
+ return;
+ }
+ result = uselocale (new_locale);
+ g_assert_true (result == original_locale);
+
/* Only do the test if translation is actually working... */
if (g_str_equal (dgettext ("test", "\"Unnamed\""), "\"Unbenannt\""))
settings_assert_cmpstr (settings, "backspace", ==, "Löschen");
else
g_test_skip ("translation is not working");
- g_setenv ("LC_MESSAGES", locale, TRUE);
- setlocale (LC_MESSAGES, locale);
- g_free (locale);
+ result = uselocale (original_locale);
+ g_assert_true (result == new_locale);
+ freelocale (new_locale);
+
+ g_object_unref (settings);
+#endif
+}
+
+/* Test use of l10n="time" and LC_TIME. */
+static void
+test_l10n_time (void)
+{
+#ifndef HAVE_USELOCALE
+ g_test_skip ("Unsafe to change locale because platform does not support uselocale()");
+#else
+ GSettings *settings;
+ gchar *str;
+ locale_t original_locale;
+ locale_t new_locale;
+ locale_t result;
+
+ g_test_summary ("Test that l10n='time' attribute uses the correct category for translations");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2575");
+
+ bindtextdomain ("test", locale_dir);
+ bind_textdomain_codeset ("test", "UTF-8");
+
+ settings = g_settings_new ("org.gtk.test.localized");
+
+ original_locale = uselocale ((locale_t) 0);
+ g_assert_true (original_locale != (locale_t) 0);
+ new_locale = duplocale (original_locale);
+ g_assert_true (new_locale != (locale_t) 0);
+ new_locale = newlocale (LC_TIME_MASK, "C", new_locale);
+ g_assert_true (new_locale != (locale_t) 0);
+ result = uselocale (new_locale);
+ g_assert_true (result == original_locale);
+
+ str = g_settings_get_string (settings, "midnight");
+
+ result = uselocale (original_locale);
+ g_assert_true (result == new_locale);
+
+ g_assert_cmpstr (str, ==, "12:00 AM");
+ g_free (str);
+ str = NULL;
+
+ new_locale = newlocale (LC_TIME_MASK, "de_DE.UTF-8", new_locale);
+ if (new_locale == (locale_t) 0)
+ {
+ g_test_skip ("Cannot run test becaues de_DE.UTF-8 locale is not available");
+ g_object_unref (settings);
+ return;
+ }
+ result = uselocale (new_locale);
+ g_assert_true (result != (locale_t) 0);
+
+ /* Only do the test if translation is actually working... */
+ if (g_str_equal (dgettext ("test", "\"12:00 AM\""), "\"00:00\""))
+ {
+ str = g_settings_get_string (settings, "midnight");
+
+ g_assert_cmpstr (str, ==, "00:00");
+ g_free (str);
+ str = NULL;
+ }
+ else
+ {
+ g_test_skip ("translation is not working");
+ }
+
+ result = uselocale (original_locale);
+ g_assert_true (result == new_locale);
+ freelocale (new_locale);
+
g_object_unref (settings);
+#endif
}
enum
@@ -3109,6 +3226,7 @@ main (int argc, char *argv[])
g_test_add_func ("/gsettings/l10n", test_l10n);
g_test_add_func ("/gsettings/l10n-context", test_l10n_context);
+ g_test_add_func ("/gsettings/l10n-time", test_l10n_time);
g_test_add_func ("/gsettings/delay-apply", test_delay_apply);
g_test_add_func ("/gsettings/delay-revert", test_delay_revert);
diff --git a/gio/tests/org.gtk.test.gschema.xml.orig b/gio/tests/org.gtk.test.gschema.xml.orig
index aad4e54df..e01183897 100644
--- a/gio/tests/org.gtk.test.gschema.xml.orig
+++ b/gio/tests/org.gtk.test.gschema.xml.orig
@@ -83,6 +83,9 @@
<key name="backspace" type="s">
<default l10n="messages" context="keyboard label">"BackSpace"</default>
</key>
+ <key name="midnight" type="s">
+ <default l10n="time">"12:00 AM"</default>
+ </key>
</schema>
<schema id="org.gtk.test.binding" path="/tests/binding/">