diff options
author | Dan Cîrnaț <cirnatdan@NetBSD.org> | 2021-04-15 16:09:59 +0200 |
---|---|---|
committer | Dan Cîrnaț <cirnatdan@NetBSD.org> | 2021-04-15 17:43:04 +0200 |
commit | 856cc6c6820810f0de81e4249a6a60996e0b80c5 (patch) | |
tree | 03f592e7716b8b4ba6433fc45a76cff46323c8b3 | |
parent | 1b722ab622f3e0e8ad199e4f1db650416d198adb (diff) | |
download | gnome-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.meson | 6 | ||||
-rw-r--r-- | libgnome-desktop/gnome-gettext-portable.c | 72 | ||||
-rw-r--r-- | libgnome-desktop/gnome-gettext-portable.h | 42 | ||||
-rw-r--r-- | libgnome-desktop/gnome-languages.c | 76 | ||||
-rw-r--r-- | libgnome-desktop/gnome-wall-clock.c | 9 | ||||
-rw-r--r-- | libgnome-desktop/meson.build | 3 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | tests/languages.c | 58 | ||||
-rw-r--r-- | tests/meson.build | 3 | ||||
-rw-r--r-- | tests/wall-clock.c | 52 | ||||
-rw-r--r-- | tests/wallclock-reftest.c | 17 |
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"); |