aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ephy-langs.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ephy-langs.c')
-rw-r--r--lib/ephy-langs.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/ephy-langs.c b/lib/ephy-langs.c
index ff05c34e1..bf86010bf 100644
--- a/lib/ephy-langs.c
+++ b/lib/ephy-langs.c
@@ -24,6 +24,8 @@
#include <glib/gi18n.h>
+#include <string.h>
+
static const EphyFontsLanguageInfo font_languages [] =
{
{ N_("Arabic"), "ar" },
@@ -57,3 +59,139 @@ ephy_font_n_languages (void)
{
return n_font_languages;
}
+
+/* sanitise the languages list according to the rules for HTTP accept-language
+ * in RFC 2616, Sect. 14.4
+ */
+void
+ephy_langs_sanitise (GArray *array)
+{
+ char *lang1, *lang2;
+ int i, j;
+
+ /* if we have 'xy-ab' in list but not 'xy', append 'xy' */
+ for (i = 0; i < array->len; i++)
+ {
+ gboolean found = FALSE;
+ char *dash, *prefix;
+
+ lang1 = (char *) g_array_index (array,char *, i);
+
+ dash = strchr (lang1, '-');
+ if (dash == NULL) continue;
+
+ for (j = i + 1; j < array->len; j++)
+ {
+ lang2 = (char *) g_array_index (array, char *, j);
+ if (strchr (lang2, '-') == NULL &&
+ g_str_has_prefix (lang1, lang2))
+ {
+ found = TRUE;
+ }
+ }
+
+ if (found == FALSE)
+ {
+ prefix = g_strndup (lang1, dash - lang1);
+ g_array_append_val (array, prefix);
+ }
+ }
+
+ /* uniquify */
+ for (i = 0; i < array->len - 1; i++)
+ {
+ for (j = array->len - 1; j > i; j--)
+ {
+ lang1 = (char *) g_array_index (array,char *, i);
+ lang2 = (char *) g_array_index (array, char *, j);
+
+ if (strcmp (lang1, lang2) == 0)
+ {
+ g_array_remove_index (array, j);
+ g_free (lang2);
+ }
+ }
+ }
+
+ /* move 'xy' code behind all 'xy-ab' codes */
+ for (i = array->len - 2; i >= 0; i--)
+ {
+ for (j = array->len - 1; j > i; j--)
+ {
+ lang1 = (char *) g_array_index (array, char *, i);
+ lang2 = (char *) g_array_index (array, char *, j);
+
+ if (strchr (lang1, '-') == NULL &&
+ strchr (lang2, '-') != NULL &&
+ g_str_has_prefix (lang2, lang1))
+ {
+ g_array_insert_val (array, j + 1, lang1);
+ g_array_remove_index (array, i);
+ break;
+ }
+ }
+ }
+}
+
+void
+ephy_langs_append_languages (GArray *array)
+{
+ const char * const * languages;
+ const char *system_lang;
+ char *lang;
+ int i;
+
+ /**
+ * This is a comma separated list of language ranges, as specified
+ * by RFC 2616, 14.4.
+ * Always include the basic language code last.
+ *
+ * Examples:
+ * "pt" translation: "pt"
+ * "pt_BR" translation: "pt-br,pt"
+ * "zh_CN" translation: "zh-cn,zh"
+ * "zh_HK" translation: "zh-hk,zh" or maybe "zh-hk,zh-tw,zh"
+ */
+ system_lang = _("system-language");
+
+ /* FIXME: use system_language when given, instead of g_get_language_names () ? */
+ languages = g_get_language_names ();
+ g_return_if_fail (languages != NULL);
+
+ /* FIXME: maybe just use the first, instead of all of them? */
+ for (i = 0; languages[i] != NULL; i++)
+ {
+
+ if (strstr (languages[i], ".") == 0 &&
+ strstr (languages[i], "@") == 0 &&
+ strcmp (languages[i], "C") != 0)
+ {
+ /* change to lowercase and '_' to '-' */
+ lang = g_strdelimit (g_ascii_strdown
+ (languages[i], -1), "_", '-');
+
+ g_array_append_val (array, lang);
+ }
+ }
+
+ /* Fallback: add "en" if list is empty */
+ if (array->len == 0)
+ {
+ lang = g_strdup ("en");
+ g_array_append_val (array, lang);
+ }
+}
+
+char **
+ephy_langs_get_languages (void)
+{
+ GArray *array;
+
+ array = g_array_new (TRUE, FALSE, sizeof (char *));
+
+ ephy_langs_append_languages (array);
+
+ ephy_langs_sanitise (array);
+
+ return (char **) g_array_free (array, FALSE);
+}