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.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/lib/ephy-langs.c b/lib/ephy-langs.c
index 129ab525d..793f179ce 100644
--- a/lib/ephy-langs.c
+++ b/lib/ephy-langs.c
@@ -22,10 +22,16 @@
#include "ephy-langs.h"
+#include "ephy-debug.h"
+
#include <glib/gi18n.h>
#include <string.h>
+#ifdef HAVE_ISO_CODES
+#include <libxml/xmlreader.h>
+#endif
+
static const EphyFontsLanguageInfo font_languages [] =
{
{ N_("Arabic"), "ar" },
@@ -195,3 +201,201 @@ ephy_langs_get_languages (void)
return (char **) g_array_free (array, FALSE);
}
+
+#ifdef HAVE_ISO_CODES
+
+#define ISOCODESLOCALEDIR ISO_CODES_PREFIX "/share/locale"
+
+static void
+ephy_langs_bind_iso_domains (void)
+{
+#ifdef ENABLE_NLS
+ static gboolean bound = FALSE;
+
+ if (bound == FALSE)
+ {
+ bindtextdomain (ISO_639_DOMAIN, ISOCODESLOCALEDIR);
+ bind_textdomain_codeset (ISO_639_DOMAIN, "UTF-8");
+
+ bindtextdomain(ISO_3166_DOMAIN, ISOCODESLOCALEDIR);
+ bind_textdomain_codeset (ISO_3166_DOMAIN, "UTF-8");
+
+ bound = TRUE;
+ }
+#endif
+}
+
+static void
+read_iso_639_entry (xmlTextReaderPtr reader,
+ GHashTable *table)
+{
+ xmlChar *code, *name;
+
+ code = xmlTextReaderGetAttribute (reader, (const xmlChar *) "iso_639_1_code");
+ name = xmlTextReaderGetAttribute (reader, (const xmlChar *) "name");
+
+ /* Get iso-639-2 code */
+ if (code == NULL || code[0] == '\0')
+ {
+ xmlFree (code);
+ /* FIXME: use the 2T or 2B code? */
+ code = xmlTextReaderGetAttribute (reader, (const xmlChar *) "iso_639_2T_code");
+ }
+
+ if (code != NULL && code[0] != '\0' && name != NULL && name[0] != '\0')
+ {
+ g_hash_table_insert (table, code, name);
+ }
+ else
+ {
+ xmlFree (code);
+ xmlFree (name);
+ }
+}
+
+static void
+read_iso_3166_entry (xmlTextReaderPtr reader,
+ GHashTable *table)
+{
+ xmlChar *code, *name;
+
+ code = xmlTextReaderGetAttribute (reader, (const xmlChar *) "alpha_2_code");
+ name = xmlTextReaderGetAttribute (reader, (const xmlChar *) "name");
+
+ if (code != NULL && code[0] != '\0' && name != NULL && name[0] != '\0')
+ {
+ char *lcode;
+
+ lcode = g_ascii_strdown ((char *) code, -1);
+ xmlFree (code);
+
+ g_hash_table_insert (table, lcode, name);
+ }
+ else
+ {
+ xmlFree (code);
+ xmlFree (name);
+ }
+
+}
+
+typedef enum
+{
+ STATE_START,
+ STATE_STOP,
+ STATE_ENTRIES,
+} ParserState;
+
+static gboolean
+load_iso_entries (int iso,
+ GFunc read_entry_func,
+ gpointer user_data)
+{
+ xmlTextReaderPtr reader;
+ ParserState state = STATE_START;
+ xmlChar iso_entries[32], iso_entry[32];
+ char *filename;
+ int ret = -1;
+
+ LOG ("Loading ISO-%d codes", iso)
+
+ START_PROFILER ("Loading ISO codes")
+
+ filename = g_strdup_printf (ISO_CODES_PREFIX "/share/xml/iso-codes/iso_%d.xml", iso);
+ reader = xmlNewTextReaderFilename (filename);
+ if (reader == NULL) goto out;
+
+ xmlStrPrintf (iso_entries, sizeof (iso_entries), "iso_%d_entries", iso);
+ xmlStrPrintf (iso_entry, sizeof (iso_entry), "iso_%d_entry", iso);
+
+ ret = xmlTextReaderRead (reader);
+
+ while (ret == 1)
+ {
+ const xmlChar *tag;
+ xmlReaderTypes type;
+
+ tag = xmlTextReaderConstName (reader);
+ type = xmlTextReaderNodeType (reader);
+
+ if (state == STATE_ENTRIES &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, iso_entry))
+ {
+ read_entry_func (reader, user_data);
+ }
+ else if (state == STATE_START &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, iso_entries))
+ {
+ state = STATE_ENTRIES;
+ }
+ else if (state == STATE_ENTRIES &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, iso_entries))
+ {
+ state = STATE_STOP;
+ }
+ else if (type == XML_READER_TYPE_SIGNIFICANT_WHITESPACE ||
+ type == XML_READER_TYPE_WHITESPACE ||
+ type == XML_READER_TYPE_TEXT ||
+ type == XML_READER_TYPE_COMMENT)
+ {
+ /* eat it */
+ }
+ else
+ {
+ /* ignore it */
+ }
+
+ ret = xmlTextReaderRead (reader);
+ }
+
+ xmlFreeTextReader (reader);
+
+out:
+ if (ret < 0 || state != STATE_STOP)
+ {
+ g_warning ("Failed to load ISO-%d codes from %s!\n",
+ iso, filename);
+ return FALSE;
+ }
+
+ g_free (filename);
+
+ STOP_PROFILER ("Loading ISO codes")
+
+ return TRUE;
+}
+
+GHashTable *
+ephy_langs_iso_639_table (void)
+{
+ GHashTable *table;
+
+ ephy_langs_bind_iso_domains ();
+ table = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) xmlFree,
+ (GDestroyNotify) xmlFree);
+
+ load_iso_entries (639, (GFunc) read_iso_639_entry, table);
+
+ return table;
+}
+
+GHashTable *
+ephy_langs_iso_3166_table (void)
+{
+ GHashTable *table;
+
+ ephy_langs_bind_iso_domains ();
+ table = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) xmlFree);
+
+ load_iso_entries (3166, (GFunc) read_iso_3166_entry, table);
+
+ return table;
+}
+
+#endif /* HAVE_ISO_CODES */