/** * gnome_normalize_locale: * @locale: a locale string * * Gets the normalized locale string in the form * [language[_country][.codeset][@modifier]] for @name. * * Return value: (transfer full): normalized locale string. Caller * takes ownership. * * Since: 3.8 */ char * gnome_normalize_locale (const char *locale) { char *normalized_name; gboolean valid; g_autofree char *language_code = NULL; g_autofree char *territory_code = NULL; g_autofree char *codeset = NULL; g_autofree char *modifier = NULL; if (locale[0] == '\0') { return NULL; } valid = gnome_parse_locale (locale, &language_code, &territory_code, &codeset, &modifier); if (!valid) return NULL; normalized_name = construct_language_name (language_code, territory_code, codeset, modifier); return normalized_name; }
char * gdm_normalize_language_name (const char *name) { char *normalized_name; char *language_code; char *territory_code; char *codeset; char *modifier; if (name[0] == '\0') { return NULL; } gdm_parse_language_name (name, &language_code, &territory_code, &codeset, &modifier); normalized_name = construct_language_name (language_code, territory_code, codeset, modifier); g_free (language_code); g_free (territory_code); g_free (codeset); g_free (modifier); return normalized_name; }
static gboolean add_locale (const char *language_name, gboolean utf8_only) { GnomeLocale *locale; GnomeLocale *old_locale; g_autofree char *name = NULL; gboolean is_utf8 = FALSE; gboolean valid = FALSE; g_return_val_if_fail (language_name != NULL, FALSE); g_return_val_if_fail (*language_name != '\0', FALSE); language_name_get_codeset_details (language_name, NULL, &is_utf8); if (is_utf8) { name = g_strdup (language_name); } else if (utf8_only) { if (strchr (language_name, '.')) return FALSE; /* If the locale name has no dot, assume that its * encoding part is missing and try again after adding * ".UTF-8". This catches locale names like "de_DE". */ name = g_strdup_printf ("%s.UTF-8", language_name); language_name_get_codeset_details (name, NULL, &is_utf8); if (!is_utf8) return FALSE; } else { name = g_strdup (language_name); } if (!language_name_is_valid (name)) { g_debug ("Ignoring '%s' as a locale, since it's invalid", name); return FALSE; } locale = g_new0 (GnomeLocale, 1); valid = gnome_parse_locale (name, &locale->language_code, &locale->territory_code, &locale->codeset, &locale->modifier); if (!valid) { gnome_locale_free (locale); return FALSE; } locale->id = construct_language_name (locale->language_code, locale->territory_code, NULL, locale->modifier); locale->name = construct_language_name (locale->language_code, locale->territory_code, locale->codeset, locale->modifier); if (!gnome_language_has_translations (locale->name) && !gnome_language_has_translations (locale->id) && !gnome_language_has_translations (locale->language_code) && utf8_only) { g_debug ("Ignoring '%s' as a locale, since it lacks translations", locale->name); gnome_locale_free (locale); return FALSE; } if (!utf8_only) { g_free (locale->id); locale->id = g_strdup (locale->name); } old_locale = g_hash_table_lookup (gnome_available_locales_map, locale->id); if (old_locale != NULL) { if (strlen (old_locale->name) > strlen (locale->name)) { gnome_locale_free (locale); return FALSE; } } g_hash_table_insert (gnome_available_locales_map, g_strdup (locale->id), locale); return TRUE; }
/** * gnome_parse_locale: * @locale: a locale string * @language_codep: (out) (allow-none) (transfer full): location to * store the language code, or %NULL * @country_codep: (out) (allow-none) (transfer full): location to * store the country code, or %NULL * @codesetp: (out) (allow-none) (transfer full): location to * store the codeset, or %NULL * @modifierp: (out) (allow-none) (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 * http://en.wikipedia.org/wiki/Locale. * * Return value: %TRUE if parsing was successful. * * Since: 3.8 */ gboolean gnome_parse_locale (const char *locale, char **language_codep, char **country_codep, 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; }
static gboolean add_locale (const char *language_name, gboolean utf8_only) { GdmLocale *locale; GdmLocale *old_locale; char *name; gboolean is_utf8 = FALSE; g_return_val_if_fail (language_name != NULL, FALSE); g_return_val_if_fail (*language_name != '\0', FALSE); language_name_get_codeset_details (language_name, NULL, &is_utf8); if (is_utf8) { name = g_strdup (language_name); } else if (utf8_only) { name = g_strdup_printf ("%s.utf8", language_name); language_name_get_codeset_details (name, NULL, &is_utf8); if (!is_utf8) { g_free (name); return FALSE; } } else { name = g_strdup (language_name); } if (!language_name_is_valid (name)) { g_debug ("Ignoring '%s' as a locale, since it's invalid", name); g_free (name); return FALSE; } locale = g_new0 (GdmLocale, 1); gdm_parse_language_name (name, &locale->language_code, &locale->territory_code, &locale->codeset, &locale->modifier); g_free (name); name = NULL; #ifdef WITH_INCOMPLETE_LOCALES if (utf8_only) { if (locale->territory_code == NULL || locale->modifier) { g_debug ("Ignoring '%s' as a locale, since it lacks territory code or modifier", name); gdm_locale_free (locale); return FALSE; } } #endif locale->id = construct_language_name (locale->language_code, locale->territory_code, NULL, locale->modifier); locale->name = construct_language_name (locale->language_code, locale->territory_code, locale->codeset, locale->modifier); #ifndef WITH_INCOMPLETE_LOCALES if (!gdm_language_has_translations (locale->name) && !gdm_language_has_translations (locale->id) && !gdm_language_has_translations (locale->language_code) && utf8_only) { g_debug ("Ignoring '%s' as a locale, since it lacks translations", locale->name); gdm_locale_free (locale); return FALSE; } #endif if (!utf8_only) { g_free (locale->id); locale->id = g_strdup (locale->name); } old_locale = g_hash_table_lookup (gdm_available_locales_map, locale->id); if (old_locale != NULL) { if (strlen (old_locale->name) > strlen (locale->name)) { gdm_locale_free (locale); return FALSE; } } g_hash_table_insert (gdm_available_locales_map, g_strdup (locale->id), locale); return TRUE; }