Example #1
0
/**
 * 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;
}
Example #2
0
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;
}
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;
}