summaryrefslogtreecommitdiff
path: root/libgnome-desktop
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2022-07-21 20:44:48 +0200
committerBastien Nocera <hadess@hadess.net>2022-07-23 12:51:17 +0200
commit8af09a3ed803df5d57656c6395cdefd076c6a6c6 (patch)
tree4a509bd00137c26f371ad637d57cc076f876ccef /libgnome-desktop
parent2c5aae5234b32ec8616e2c93516815440253fd5e (diff)
downloadgnome-desktop-8af09a3ed803df5d57656c6395cdefd076c6a6c6.tar.gz
gnome-languages: Simplify XPG language parsing
Adapted from new code in accountsservice. This new code does not accept locale aliases, locale names with just numbers, or spaces.
Diffstat (limited to 'libgnome-desktop')
-rw-r--r--libgnome-desktop/gnome-languages.c135
1 files changed, 43 insertions, 92 deletions
diff --git a/libgnome-desktop/gnome-languages.c b/libgnome-desktop/gnome-languages.c
index 7a0ef6ba..065b2135 100644
--- a/libgnome-desktop/gnome-languages.c
+++ b/libgnome-desktop/gnome-languages.c
@@ -105,6 +105,23 @@ normalize_codeset (const char *codeset)
return g_strdup (codeset);
}
+/* Returns TRUE if value was non-empty */
+
+static gboolean
+match_info_fetch_named_non_empty (GMatchInfo *match_info,
+ const char *match_name,
+ char **variable)
+{
+ g_autofree char *value = NULL;
+
+ value = g_match_info_fetch_named (match_info, match_name);
+ if (!value || *value == '\0')
+ return FALSE;
+ if (variable)
+ *variable = g_steal_pointer (&value);
+ return TRUE;
+}
+
/**
* gnome_parse_locale:
* @locale: a locale string
@@ -117,8 +134,8 @@ normalize_codeset (const char *codeset)
* @modifierp: (out) (optional) (nullable) (transfer full): location to
* store the modifier, or %NULL
*
- * Extracts the various components of a locale string of the form
- * [language[_country][.codeset][@modifier]]. See
+ * Extracts the various components of a locale string in XPG format.
+ * ([language[_country][.codeset][@modifier]]). See
* http://en.wikipedia.org/wiki/Locale.
*
* Return value: %TRUE if parsing was successful.
@@ -132,96 +149,30 @@ gnome_parse_locale (const char *locale,
char **codesetp,
char **modifierp)
{
- static GRegex *re = NULL;
- GMatchInfo *match_info;
- gboolean res;
- gboolean retval;
-
- match_info = NULL;
- retval = FALSE;
-
- if (re == NULL) {
- GError *error = NULL;
- re = g_regex_new ("^(?P<language>[^_.@[:space:]]+)"
- "(_(?P<territory>[[:upper:]]+))?"
- "(\\.(?P<codeset>[-_0-9a-zA-Z]+))?"
- "(@(?P<modifier>[[:ascii:]]+))?$",
- 0, 0, &error);
- if (re == NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- goto out;
- }
- }
-
- if (!g_regex_match (re, locale, 0, &match_info) ||
- g_match_info_is_partial_match (match_info)) {
- g_warning ("locale '%s' isn't valid\n", locale);
- goto out;
- }
-
- res = g_match_info_matches (match_info);
- if (! res) {
- g_warning ("Unable to parse locale: %s", locale);
- goto out;
- }
-
- retval = TRUE;
-
- if (language_codep != NULL) {
- *language_codep = g_match_info_fetch_named (match_info, "language");
- }
-
- if (country_codep != NULL) {
- *country_codep = g_match_info_fetch_named (match_info, "territory");
-
- if (*country_codep != NULL &&
- *country_codep[0] == '\0') {
- g_free (*country_codep);
- *country_codep = NULL;
- }
- }
-
- if (codesetp != NULL) {
- *codesetp = g_match_info_fetch_named (match_info, "codeset");
-
- if (*codesetp != NULL &&
- *codesetp[0] == '\0') {
- g_free (*codesetp);
- *codesetp = NULL;
- }
- }
-
- if (modifierp != NULL) {
- *modifierp = g_match_info_fetch_named (match_info, "modifier");
-
- if (*modifierp != NULL &&
- *modifierp[0] == '\0') {
- g_free (*modifierp);
- *modifierp = NULL;
- }
- }
-
- if (codesetp != NULL && *codesetp != NULL) {
- g_autofree gchar *normalized_codeset = NULL;
- g_autofree gchar *normalized_name = NULL;
-
- normalized_codeset = normalize_codeset (*codesetp);
- normalized_name = construct_language_name (language_codep ? *language_codep : NULL,
- country_codep ? *country_codep : NULL,
- normalized_codeset,
- modifierp ? *modifierp : NULL);
-
- if (language_name_is_valid (normalized_name)) {
- g_free (*codesetp);
- *codesetp = g_steal_pointer (&normalized_codeset);
- }
- }
-
- out:
- g_match_info_free (match_info);
-
- return retval;
+ g_autoptr(GRegex) regex = NULL;
+ g_autoptr(GMatchInfo) match_info = NULL;
+ gboolean ret = FALSE;
+
+ if (locale == NULL)
+ return ret;
+
+ regex = g_regex_new ("^(?P<language>[a-z][a-z][a-z]?)"
+ "(_(?P<territory>[A-Z][A-Z]))?"
+ "(\\.(?P<codeset>[A-Za-z0-9][A-Za-z-0-9]*))?"
+ "(@(?P<modifier>[a-z]*))?$",
+ 0, 0, NULL);
+ g_assert (regex);
+
+ if (!g_regex_match (regex, locale, 0, &match_info))
+ return ret;
+
+ if (match_info_fetch_named_non_empty (match_info, "language", language_codep))
+ ret = TRUE;
+ match_info_fetch_named_non_empty (match_info, "territory", country_codep);
+ match_info_fetch_named_non_empty (match_info, "codeset", codesetp);
+ match_info_fetch_named_non_empty (match_info, "modifier", modifierp);
+
+ return ret;
}
static char *