Merge pull request #3194 from pwithnall/what-is-a-locale

config: Rework handling of extra-languages to change locale format
This commit is contained in:
Matthias Clasen
2019-10-25 09:15:25 -04:00
committed by GitHub
5 changed files with 89 additions and 52 deletions

View File

@@ -51,7 +51,11 @@ looks_like_a_language (const char *s)
int len = strlen (s);
int i;
if (len < 2 || len > 3)
if (g_str_equal (s, "C") ||
g_str_equal (s, "POSIX"))
return TRUE;
if (len < 2)
return FALSE;
for (i = 0; i < len; i++)
@@ -64,49 +68,73 @@ looks_like_a_language (const char *s)
}
static gboolean
looks_like_a_region (const char *s)
looks_like_a_territory (const char *s)
{
g_auto(GStrv) locale = g_strsplit (s, "_", 3);
int i;
int len;
gsize len = strlen (s);
gsize i;
if (!looks_like_a_language(locale[0]))
if (len < 2)
return FALSE;
if (locale[1] != NULL)
for (i = 0; i < len; i++)
{
len = strlen (locale[1]);
// This can be either GB or Latn
if (len < 2 || len > 4)
if (!g_ascii_isalpha (s[i]) || !g_ascii_isupper (s[i]))
return FALSE;
for (i = 0; i < len; i++)
{
if ((locale[2] == NULL) && (!g_ascii_isalpha (locale[1][i]) || !g_ascii_isupper (locale[1][i])))
return FALSE;
else if (!g_ascii_isalpha (locale[1][i]))
return FALSE;
}
}
if (g_strv_length (locale) > 2)
return TRUE;
}
static gboolean
looks_like_a_codeset_or_modifier (const char *s)
{
gsize len = strlen (s);
gsize i;
if (len < 1)
return FALSE;
for (i = 0; i < len; i++)
{
len = strlen (locale[2]);
if (len < 2 || len > 3)
if (!g_ascii_isalnum (s[i]) && s[i] != '-')
return FALSE;
for (i = 0; i < len; i++)
{
if (!g_ascii_isalpha (locale[2][i]) || !g_ascii_isupper (locale[2][i]))
return FALSE;
}
}
return TRUE;
}
static gboolean
looks_like_a_locale (const char *s)
{
g_autofree gchar *locale = g_strdup (s);
gchar *language, *territory, *codeset, *modifier;
modifier = strchr (locale, '@');
if (modifier != NULL)
*modifier++ = '\0';
codeset = strchr (locale, '.');
if (codeset != NULL)
*codeset++ = '\0';
territory = strchr (locale, '_');
if (territory != NULL)
*territory++ = '\0';
language = locale;
if (!looks_like_a_language (language))
return FALSE;
if (territory != NULL && !looks_like_a_territory (territory))
return FALSE;
if (codeset != NULL && !looks_like_a_codeset_or_modifier (codeset))
return FALSE;
if (modifier != NULL && !looks_like_a_codeset_or_modifier (modifier))
return FALSE;
return TRUE;
}
static char *
parse_locale (const char *value, GError **error)
{
@@ -116,7 +144,7 @@ parse_locale (const char *value, GError **error)
strs = g_strsplit (value, ";", 0);
for (i = 0; strs[i]; i++)
{
if (!looks_like_a_language (strs[i]) && !looks_like_a_region (strs[i]))
if (!looks_like_a_language (strs[i]) && !looks_like_a_locale (strs[i]))
{
flatpak_fail (error, _("'%s' does not look like a language/locale code"), strs[i]);
return NULL;

View File

@@ -14607,9 +14607,10 @@ flatpak_dir_get_default_locale_languages (FlatpakDir *self)
extra_languages = flatpak_dir_get_config_strv (self, "xa.extra-languages");
for (i = 0; extra_languages != NULL && extra_languages[i] != NULL; i++)
{
g_auto(GStrv) locales = g_strsplit (extra_languages[i], "_", -1);
g_free (extra_languages[i]);
extra_languages[i] = g_strdup (locales[0]);
/* Strip the locale, modifier or codeset, if present. */
gchar *match = strpbrk (extra_languages[i], "._@");
if (match != NULL)
*match = '\0';
}
if (flatpak_dir_is_user (self))

View File

@@ -1687,12 +1687,15 @@ flatpak_installation_get_default_languages (FlatpakInstallation *self,
* @self: a #FlatpakInstallation
* @error: return location for a #GError
*
* Like flatpak_installation_get_default_languages() but includes region
* information (e.g. en_US rather than en) which may be included in the
* xa.extra-languages configuration.
* Like flatpak_installation_get_default_languages() but includes territory
* information (e.g. `en_US` rather than `en`) which may be included in the
* `xa.extra-languages` configuration.
*
* Strings returned by this function are in the format specified by
* [`setlocale()`](man:setlocale): `language[_territory][.codeset][@modifier]`.
*
* Returns: (array zero-terminated=1) (element-type utf8) (transfer full):
* A possibly empty array of language and locale strings, or %NULL on error.
* A possibly empty array of locale strings, or %NULL on error.
* Since: 1.5.1
*/
char **

View File

@@ -61,8 +61,8 @@
<listitem><para>
The languages that are included when installing Locale extensions.
The value is a semicolon-separated list of two-letter language codes,
or one of the special values * or all. If this key is unset, flatpak
defaults to including the extra-languages key and the current locale.
or one of the special values <literal>*</literal> or <literal>all</literal>. If this key is unset, flatpak
defaults to including the <varname>extra-languages</varname> key and the current locale.
</para></listitem>
</varlistentry>
<varlistentry>
@@ -70,8 +70,10 @@
<listitem><para>
This key is used when languages is not set, and it defines extra locale
extensions on top of the system configured languages. The value is a
semicolon-separated list of two-letter language codes or locale identifiers
(eg. en;en_DK;az_Latn_AZ).
semicolon-separated list of locale identifiers
(language, optional locale, optional codeset, optional modifier) as documented by
<citerefentry><refentrytitle>setlocale</refentrytitle><manvolnum>3</manvolnum></citerefentry>
(for example, <literal>en;en_DK;zh_HK.big5hkscs;uz_UZ.utf8@cyrillic</literal>).
</para></listitem>
</varlistentry>
</variablelist>

View File

@@ -291,27 +291,30 @@ test_languages_config (void)
g_assert_cmpstr (value[0], ==, "en");
g_assert_null (value[1]);
res = flatpak_installation_set_config_sync (inst, "extra-languages", "pt_BR;az_Latn_AZ;es", NULL, &error);
res = flatpak_installation_set_config_sync (inst, "extra-languages", "pt_BR;uz_UZ.utf8@cyrillic;es;zh_HK.big5hkscs;uz_UZ@cyrillic", NULL, &error);
g_assert_no_error (error);
g_assert_true (res);
value = flatpak_installation_get_default_languages (inst, &error);
g_assert_no_error (error);
g_assert_cmpstr (value[0], ==, "az");
g_assert_cmpstr (value[1], ==, "en");
g_assert_cmpstr (value[2], ==, "es");
g_assert_cmpstr (value[3], ==, "pt");
g_assert_null (value[4]);
g_assert_cmpstr (value[0], ==, "en");
g_assert_cmpstr (value[1], ==, "es");
g_assert_cmpstr (value[2], ==, "pt");
g_assert_cmpstr (value[3], ==, "uz");
g_assert_cmpstr (value[4], ==, "zh");
g_assert_null (value[5]);
g_clear_pointer (&value, g_strfreev);
value = flatpak_installation_get_default_locales (inst, &error);
g_assert_no_error (error);
g_assert_cmpstr (value[0], ==, "az_Latn_AZ");
g_assert_cmpstr (value[1], ==, "en");
g_assert_cmpstr (value[2], ==, "es");
g_assert_cmpstr (value[3], ==, "pt_BR");
g_assert_null (value[4]);
g_assert_cmpstr (value[0], ==, "en");
g_assert_cmpstr (value[1], ==, "es");
g_assert_cmpstr (value[2], ==, "pt_BR");
g_assert_cmpstr (value[3], ==, "uz_UZ.utf8@cyrillic");
g_assert_cmpstr (value[4], ==, "uz_UZ@cyrillic");
g_assert_cmpstr (value[5], ==, "zh_HK.big5hkscs");
g_assert_null (value[6]);
g_clear_pointer (&value, g_strfreev);