summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2015-12-01 13:09:26 +0900
committerAkira TAGOH <akira@tagoh.org>2015-12-01 13:09:48 +0900
commit28caed6dd1440f19f7c8b4122ca55d1323bc82c7 (patch)
treebcd34540a121e96deef5070c4075842f8c9bb1a2
parent284f3c271e37145eb94cb1d0b5b205aaddb50dcc (diff)
Add a lookup table to catch up a script/language from language/script
-rw-r--r--data/Makefile.am5
-rw-r--r--liblangtag-gobject/Makefile.am2
-rw-r--r--liblangtag/Makefile.am2
-rw-r--r--liblangtag/lt-database.c16
-rw-r--r--liblangtag/lt-database.h4
-rw-r--r--liblangtag/lt-macros.h26
-rw-r--r--liblangtag/lt-relation-db.c283
-rw-r--r--liblangtag/lt-relation-db.h43
-rw-r--r--liblangtag/lt-xml.c41
-rw-r--r--liblangtag/lt-xml.h5
-rw-r--r--tests/tag.c16
11 files changed, 414 insertions, 29 deletions
diff --git a/data/Makefile.am b/data/Makefile.am
index 84b9c5b..9ec3d34 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -42,8 +42,9 @@ bcp47_xml_files = \
common/bcp47/transform_private_use.xml \
common/bcp47/variant.xml \
$(NULL)
-supplemental_xml_files = \
- common/supplemental/likelySubtags.xml \
+supplemental_xml_files = \
+ common/supplemental/likelySubtags.xml \
+ common/supplemental/supplementalData.xml \
$(NULL)
stamp_files = \
stamp-core-zip \
diff --git a/liblangtag-gobject/Makefile.am b/liblangtag-gobject/Makefile.am
index 0bc0dea..d932a0f 100644
--- a/liblangtag-gobject/Makefile.am
+++ b/liblangtag-gobject/Makefile.am
@@ -82,6 +82,7 @@ liblangtag_gobject_built_private_headers = \
lt-redundant.gir.h \
lt-region-db.gir.h \
lt-region.gir.h \
+ lt-relation-db.gir.h \
lt-script-db.gir.h \
lt-script.gir.h \
lt-string.gir.h \
@@ -107,6 +108,7 @@ liblangtag_gobject_built_sources = \
lt-redundant.gir.c \
lt-region-db.gir.c \
lt-region.gir.c \
+ lt-relation-db.gir.c \
lt-script-db.gir.c \
lt-script.gir.c \
lt-string.gir.c \
diff --git a/liblangtag/Makefile.am b/liblangtag/Makefile.am
index 8bc788b..5431c8b 100644
--- a/liblangtag/Makefile.am
+++ b/liblangtag/Makefile.am
@@ -70,6 +70,7 @@ liblangtag_public_headers = \
lt-redundant-db.h \
lt-region.h \
lt-region-db.h \
+ lt-relation-db.h \
lt-script.h \
lt-script-db.h \
lt-string.h \
@@ -127,6 +128,7 @@ liblangtag_sources = \
lt-redundant-db.c \
lt-region.c \
lt-region-db.c \
+ lt-relation-db.c \
lt-script.c \
lt-script-db.c \
lt-string.c \
diff --git a/liblangtag/lt-database.c b/liblangtag/lt-database.c
index 6dfd992..7f944ec 100644
--- a/liblangtag/lt-database.c
+++ b/liblangtag/lt-database.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* lt-database.c
- * Copyright (C) 2011-2012 Akira TAGOH
+ * Copyright (C) 2011-2015 Akira TAGOH
*
* Authors:
* Akira TAGOH <akira@tagoh.org>
@@ -36,6 +36,7 @@ static lt_region_db_t *__db_region = NULL;
static lt_variant_db_t *__db_variant = NULL;
static lt_grandfathered_db_t *__db_grandfathered = NULL;
static lt_redundant_db_t *__db_redundant = NULL;
+static lt_relation_db_t *__db_relation = NULL;
static char __lt_db_datadir[LT_PATH_MAX] = { 0 };
@@ -103,6 +104,8 @@ lt_db_initialize(void)
lt_db_get_grandfathered();
if (!__db_redundant)
lt_db_get_redundant();
+ if (!__db_relation)
+ lt_db_get_relation();
lt_ext_modules_load();
}
@@ -122,6 +125,7 @@ lt_db_finalize(void)
lt_variant_db_unref(__db_variant);
lt_grandfathered_db_unref(__db_grandfathered);
lt_redundant_db_unref(__db_redundant);
+ lt_relation_db_unref(__db_relation);
lt_ext_modules_unload();
}
@@ -210,3 +214,13 @@ DEFUNC_GET_INSTANCE(script)
* Returns: The instance of #lt_variant_db_t.
*/
DEFUNC_GET_INSTANCE(variant)
+/**
+ * lt_db_get_relation:
+ *
+ * Obtains the instance of #lt_relation_db_t. This still allows to use without
+ * lt_db_initialize(). but it will takes some time to load the database on
+ * the memory every time.
+ *
+ * Returns: The instance of #lt_relation_db_t.
+ */
+DEFUNC_GET_INSTANCE(relation)
diff --git a/liblangtag/lt-database.h b/liblangtag/lt-database.h
index 5c45368..310814b 100644
--- a/liblangtag/lt-database.h
+++ b/liblangtag/lt-database.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* lt-database.h
- * Copyright (C) 2011-2012 Akira TAGOH
+ * Copyright (C) 2011-2015 Akira TAGOH
*
* Authors:
* Akira TAGOH <akira@tagoh.org>
@@ -25,6 +25,7 @@
#include <liblangtag/lt-region-db.h>
#include <liblangtag/lt-script-db.h>
#include <liblangtag/lt-variant-db.h>
+#include <liblangtag/lt-relation-db.h>
LT_BEGIN_DECLS
@@ -39,6 +40,7 @@ lt_region_db_t *lt_db_get_region (void);
lt_variant_db_t *lt_db_get_variant (void);
lt_grandfathered_db_t *lt_db_get_grandfathered(void);
lt_redundant_db_t *lt_db_get_redundant (void);
+lt_relation_db_t *lt_db_get_relation (void);
LT_END_DECLS
diff --git a/liblangtag/lt-macros.h b/liblangtag/lt-macros.h
index 83bbe31..8c25915 100644
--- a/liblangtag/lt-macros.h
+++ b/liblangtag/lt-macros.h
@@ -120,11 +120,32 @@
* It allows the compiler to type-check the arguments passed to the function.
* See the GNU C documentation for details.
*/
+/**
+ * LT_GNUC_UNUSED:
+ *
+ * Expands to the GNU C unused function attribute if the compiler is gcc.
+ * It is used for declaring functions and arguments which may never be used.
+ * It avoids possible compiler warnings.
+ *
+ * For functions, place the attribute after the declaration, just before the
+ * semicolon. For arguments, place the attribute at the beginning of the
+ * argument declaration.
+ *
+ * |[<!-- language="C" -->
+ * void my_unused_function (LT_GNUC_UNUSED int unused_argument,
+ * int other argument) LT_GNUC_UNUSED;
+ * ]|
+ *
+ * See the GNU C documentation for more details.
+ */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
# define LT_GNUC_PRINTF(format_idx, arg_idx) \
__attribute__((__format__ (__printf__, format_idx, arg_idx)))
+# define LT_GNUC_UNUSED \
+ __attribute__((__unused__))
#else /* !__GNUC__ */
# define LT_GNUC_PRINTF(format_idx, arg_idx)
+# define LT_GNUC_UNUSED
#endif
/**
* LT_GNUC_NULL_TERMINATED:
@@ -304,6 +325,11 @@
LT_STMT_START {raise(SIGTRAP);} LT_STMT_END
#endif
+/* assertion */
+#define _LT_ASSERT_STATIC1(_l_,_x_) typedef int _static_assert_on_line_##_l_##_failed[(_x_)?1:-1] LT_GNUC_UNUSED
+#define _LT_ASSERT_STATIC0(_l_,_x_) _LT_ASSERT_STATIC1 (_l_, (_x_))
+#define LT_ASSERT_STATIC(_x_) _LT_ASSERT_STATIC0 (__LINE__, (_x_))
+
LT_BEGIN_DECLS
#if defined(_MSC_VER) && !defined(ssize_t)
diff --git a/liblangtag/lt-relation-db.c b/liblangtag/lt-relation-db.c
new file mode 100644
index 0000000..3451032
--- /dev/null
+++ b/liblangtag/lt-relation-db.c
@@ -0,0 +1,283 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * lt-relation-db.c
+ * Copyright (C) 2015 Akira TAGOH
+ *
+ * Authors:
+ * Akira TAGOH <akira@tagoh.org>
+ *
+ * You may distribute under the terms of either the GNU
+ * Lesser General Public License or the Mozilla Public
+ * License, as specified in the README file.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/xpath.h>
+#include "lt-database.h"
+#include "lt-error.h"
+#include "lt-list.h"
+#include "lt-mem.h"
+#include "lt-messages.h"
+#include "lt-trie.h"
+#include "lt-utils.h"
+#include "lt-xml.h"
+#include "lt-relation-db.h"
+
+/**
+ * SECTION:lt-relation-db
+ * @Short_Description: An interface to access relation database
+ * @Title: Database - Relation
+ *
+ * This class providdes an interface to access Relation database.
+ */
+struct _lt_relation_db_t {
+ lt_mem_t parent;
+ lt_xml_t *xml;
+ lt_trie_t *relation_l_s_entries;
+ lt_trie_t *relation_s_l_entries;
+};
+
+/*< private >*/
+static lt_bool_t
+lt_relation_db_parse(lt_relation_db_t *relationdb,
+ lt_error_t **error)
+{
+ lt_bool_t retval = TRUE;
+ xmlDocPtr doc = NULL;
+ xmlXPathContextPtr xctxt = NULL;
+ xmlXPathObjectPtr xobj = NULL;
+ lt_error_t *err = NULL;
+ int i, n;
+ lt_lang_db_t *langdb;
+ lt_script_db_t *scriptdb;
+
+ lt_return_val_if_fail (relationdb != NULL, FALSE);
+
+ doc = lt_xml_get_cldr(relationdb->xml, LT_XML_CLDR_SUPPLEMENTAL_SUPPLEMENTAL_DATA);
+ xctxt = xmlXPathNewContext(doc);
+ if (!xctxt) {
+ lt_error_set(&err, LT_ERR_OOM,
+ "Unable to create an instance of xmlXPathContextPtr.");
+ goto bail;
+ }
+ xobj = xmlXPathEvalExpression((const xmlChar *)"/supplementalData/languageData/language[@scripts]", xctxt);
+ if (!xobj) {
+ lt_error_set(&err, LT_ERR_FAIL_ON_XML,
+ "No valid elements for %s",
+ doc->name);
+ goto bail;
+ }
+ n = xmlXPathNodeSetGetLength(xobj->nodesetval);
+
+ langdb = lt_db_get_lang();
+ scriptdb = lt_db_get_script();
+ for (i = 0; i < n; i++) {
+ xmlNodePtr ent = xmlXPathNodeSetItem(xobj->nodesetval, i);
+ xmlChar *type, *scripts;
+ char *p, *pp;
+ lt_list_t *l;
+ lt_lang_t *ol;
+ lt_script_t *os;
+ lt_bool_t alloced;
+
+ type = xmlGetProp(ent, (const xmlChar *)"type");
+ scripts = xmlGetProp(ent, (const xmlChar *)"scripts");
+ p = (char *)scripts;
+ do {
+ pp = strchr(p, ' ');
+ if (pp) {
+ *pp = 0;
+ pp++;
+ }
+ ol = lt_lang_db_lookup(langdb, (const char *)type);
+ os = lt_script_db_lookup(scriptdb, p);
+ if (!ol || !os) {
+ if (!ol)
+ lt_warning("Unknown lang tag: %s", type);
+ else
+ lt_lang_unref(ol);
+ if (!os)
+ lt_warning("Unknown script tag: %s", p);
+ else
+ lt_script_unref(os);
+ goto bail1;
+ }
+ alloced = FALSE;
+ l = lt_trie_lookup(relationdb->relation_l_s_entries,
+ (const char *)type);
+ if (!l)
+ alloced = TRUE;
+ l = lt_list_append(l, lt_script_ref(os), (lt_destroy_func_t)lt_script_unref);
+ if (alloced) {
+ lt_mem_add_ref((lt_mem_t *)relationdb->relation_l_s_entries,
+ l, (lt_destroy_func_t)lt_list_free);
+ }
+ lt_trie_replace(relationdb->relation_l_s_entries,
+ (const char *)type, l, NULL);
+ alloced = FALSE;
+ l = lt_trie_lookup(relationdb->relation_s_l_entries, p);
+ if (!l)
+ alloced = TRUE;
+ l = lt_list_append(l, lt_lang_ref(ol), (lt_destroy_func_t)lt_lang_unref);
+ if (alloced) {
+ lt_mem_add_ref((lt_mem_t *)relationdb->relation_s_l_entries,
+ l, (lt_destroy_func_t)lt_list_free);
+ }
+ lt_trie_replace(relationdb->relation_s_l_entries, p, l, NULL);
+ bail1:
+ p = pp;
+ } while (p);
+
+ xmlFree(type);
+ xmlFree(scripts);
+ }
+
+ bail:
+ if (lt_error_is_set(err, LT_ERR_ANY)) {
+ if (error)
+ *error = lt_error_ref(err);
+ else
+ lt_error_print(err, LT_ERR_ANY);
+ lt_error_unref(err);
+ retval = FALSE;
+ }
+ if (xobj)
+ xmlXPathFreeObject(xobj);
+ if (xctxt)
+ xmlXPathFreeContext(xctxt);
+
+ return retval;
+}
+
+/*< public >*/
+/**
+ * lt_relation_db_new:
+ *
+ * Create a new instance of a #lt_relation_db_t.
+ *
+ * Returns: (transfer full): a new instance of #lt_relation_db_t.
+ */
+lt_relation_db_t *
+lt_relation_db_new(void)
+{
+ lt_relation_db_t *retval = lt_mem_alloc_object(sizeof (lt_relation_db_t));
+
+ if (retval) {
+ lt_error_t *err = NULL;
+
+ retval->relation_l_s_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)retval, retval->relation_l_s_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ retval->relation_s_l_entries = lt_trie_new();
+ lt_mem_add_ref((lt_mem_t *)retval, retval->relation_s_l_entries,
+ (lt_destroy_func_t)lt_trie_unref);
+ retval->xml = lt_xml_new();
+ if (!retval->xml) {
+ lt_relation_db_unref(retval);
+ retval = NULL;
+ goto bail;
+ }
+ lt_mem_add_ref((lt_mem_t *)retval, retval->xml,
+ (lt_destroy_func_t)lt_xml_unref);
+
+ lt_relation_db_parse(retval, &err);
+ if (lt_error_is_set(err, LT_ERR_ANY)) {
+ lt_error_print(err, LT_ERR_ANY);
+ lt_relation_db_unref(retval);
+ retval = NULL;
+ lt_error_unref(err);
+ }
+ }
+ bail:
+ return retval;
+}
+
+/**
+ * lt_relation_db_ref:
+ * @relationdb: a #lt_relation_db_t.
+ *
+ * Increases the reference count of @relationdb.
+ *
+ * Returns: (transfer none): the same @relationddb object.
+ */
+lt_relation_db_t *
+lt_relation_db_ref(lt_relation_db_t *relationdb)
+{
+ lt_return_val_if_fail (relationdb != NULL, NULL);
+
+ return lt_mem_ref((lt_mem_t *)relationdb);
+}
+
+/**
+ * lt_relation_db_unref:
+ * @relationdb: a #lt_relation_db_t.
+ *
+ * Decreases the reference count of @relationdb. when its reference count
+ * drops to 0, the object is finalized (i.e. its memory is freed).
+ */
+void
+lt_relation_db_unref(lt_relation_db_t *relationdb)
+{
+ if (relationdb)
+ lt_mem_unref((lt_mem_t *)relationdb);
+}
+
+/**
+ * lt_relation_db_lookup_lang_from_script:
+ *
+ */
+lt_list_t *
+lt_relation_db_lookup_lang_from_script(lt_relation_db_t *relationdb,
+ const lt_script_t *script)
+{
+ lt_list_t *l, *ll, *retval = NULL;
+ char *key;
+
+ lt_return_val_if_fail (relationdb != NULL, NULL);
+ lt_return_val_if_fail (script != NULL, NULL);
+
+ key = strdup(lt_script_get_name(script));
+ l = lt_trie_lookup(relationdb->relation_s_l_entries,
+ lt_strlower(key));
+ free(key);
+
+ for (ll = l; ll; ll = lt_list_next(ll)) {
+ retval = lt_list_append(retval,
+ lt_lang_ref(lt_list_value(ll)),
+ (lt_destroy_func_t)lt_lang_unref);
+ }
+
+ return retval;
+}
+
+/**
+ * lt_relation_db_lookup_script_from_lang:
+ *
+ */
+lt_list_t *
+lt_relation_db_lookup_script_from_lang(lt_relation_db_t *relationdb,
+ const lt_lang_t *lang)
+{
+ lt_list_t *l, *ll, *retval = NULL;
+ char *key;
+
+ lt_return_val_if_fail (relationdb != NULL, NULL);
+ lt_return_val_if_fail (lang != NULL, NULL);
+
+ key = strdup(lt_lang_get_tag(lang));
+ l = lt_trie_lookup(relationdb->relation_l_s_entries,
+ lt_strlower(key));
+ free(key);
+
+ for (ll = l; ll; ll = lt_list_next(ll)) {
+ retval = lt_list_append(retval,
+ lt_lang_ref(lt_list_value(ll)),
+ (lt_destroy_func_t)lt_lang_unref);
+ }
+
+ return retval;
+}
diff --git a/liblangtag/lt-relation-db.h b/liblangtag/lt-relation-db.h
new file mode 100644
index 0000000..d85bf84
--- /dev/null
+++ b/liblangtag/lt-relation-db.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * lt-relation-db.h
+ * Copyright (C) 2015 Akira TAGOH
+ *
+ * Authors:
+ * Akira TAGOH <akira@tagoh.org>
+ *
+ * You may distribute under the terms of either the GNU
+ * Lesser General Public License or the Mozilla Public
+ * License, as specified in the README file.
+ */
+#if !defined (__LANGTAG_H__INSIDE) && !defined (__LANGTAG_COMPILATION)
+#error "Only <liblangtag/langtag.h> can be included directly."
+#endif
+
+#ifndef __LT_RELATION_DB_H__
+#define __LT_RELATION_DB_H__
+
+#include <liblangtag/lt-macros.h>
+
+LT_BEGIN_DECLS
+
+/**
+ * lt_relation_db_t:
+ *
+ * All the fields in the <structname>lt_relation_db_t</structname>
+ * structure are private to the #lt_relation_db_t implementation.
+ */
+typedef struct _lt_relation_db_t lt_relation_db_t;
+
+
+lt_relation_db_t *lt_relation_db_new (void);
+lt_relation_db_t *lt_relation_db_ref (lt_relation_db_t *relationdb);
+void lt_relation_db_unref (lt_relation_db_t *relationdb);
+lt_list_t *lt_relation_db_lookup_lang_from_script(lt_relation_db_t *relationdb,
+ const lt_script_t *script);
+lt_list_t *lt_relation_db_lookup_script_from_lang(lt_relation_db_t *relationdb,
+ const lt_lang_t *lang);
+
+LT_END_DECLS
+
+#endif /* __LT_RELATION_DB_H__ */
diff --git a/liblangtag/lt-xml.c b/liblangtag/lt-xml.c
index d337204..0ee34a0 100644
--- a/liblangtag/lt-xml.c
+++ b/liblangtag/lt-xml.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* lt-xml.c
- * Copyright (C) 2011-2012 Akira TAGOH
+ * Copyright (C) 2011-2015 Akira TAGOH
*
* Authors:
* Akira TAGOH <akira@tagoh.org>
@@ -14,6 +14,7 @@
#include "config.h"
#endif
+#include <stddef.h>
#include <sys/stat.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
@@ -37,6 +38,7 @@ struct _lt_xml_t {
xmlDocPtr cldr_bcp47_transform;
xmlDocPtr cldr_bcp47_variant;
xmlDocPtr cldr_supplemental_likelysubtags;
+ xmlDocPtr cldr_supplemental_supplementaldata;
};
static lt_xml_t *__xml = NULL;
@@ -393,6 +395,10 @@ lt_xml_new(void)
&__xml->cldr_supplemental_likelysubtags,
&err))
goto bail;
+ if (!lt_xml_read_cldr_supplemental(__xml, "supplementalData.xml",
+ &__xml->cldr_supplemental_supplementaldata,
+ &err))
+ goto bail;
}
bail:
@@ -434,28 +440,19 @@ xmlDocPtr
lt_xml_get_cldr(lt_xml_t *xml,
lt_xml_cldr_t type)
{
+ xmlDocPtr *pref;
+ int idx;
+
+ LT_ASSERT_STATIC ((sizeof (lt_xml_t) - offsetof (lt_xml_t, cldr_bcp47_calendar)) == (sizeof (lt_pointer_t) * ((LT_XML_CLDR_BCP47_END - LT_XML_CLDR_BCP47_BEGIN + 1) + (LT_XML_CLDR_SUPPLEMENTAL_END - LT_XML_CLDR_SUPPLEMENTAL_BEGIN + 1))));
+
lt_return_val_if_fail (xml != NULL, NULL);
+ lt_return_val_if_fail (type > LT_XML_CLDR_BEGIN && type < LT_XML_CLDR_END, NULL);
- switch (type) {
- case LT_XML_CLDR_BCP47_CALENDAR:
- return xml->cldr_bcp47_calendar;
- case LT_XML_CLDR_BCP47_COLLATION:
- return xml->cldr_bcp47_collation;
- case LT_XML_CLDR_BCP47_CURRENCY:
- return xml->cldr_bcp47_currency;
- case LT_XML_CLDR_BCP47_NUMBER:
- return xml->cldr_bcp47_number;
- case LT_XML_CLDR_BCP47_TIMEZONE:
- return xml->cldr_bcp47_timezone;
- case LT_XML_CLDR_BCP47_TRANSFORM:
- return xml->cldr_bcp47_transform;
- case LT_XML_CLDR_BCP47_VARIANT:
- return xml->cldr_bcp47_variant;
- case LT_XML_CLDR_SUPPLEMENTAL_LIKELY_SUBTAGS:
- return xml->cldr_supplemental_likelysubtags;
- default:
- break;
- }
+ pref = &xml->cldr_bcp47_calendar;
+ if (type >= LT_XML_CLDR_DUMMY1)
+ idx = type - LT_XML_CLDR_DUMMY1 + LT_XML_CLDR_BCP47_END;
+ else
+ idx = type;
- return NULL;
+ return pref[idx - 1];
}
diff --git a/liblangtag/lt-xml.h b/liblangtag/lt-xml.h
index 856d6c6..917806a 100644
--- a/liblangtag/lt-xml.h
+++ b/liblangtag/lt-xml.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* lt-xml.h
- * Copyright (C) 2011-2012 Akira TAGOH
+ * Copyright (C) 2011-2015 Akira TAGOH
*
* Authors:
* Akira TAGOH <akira@tagoh.org>
@@ -32,8 +32,9 @@ typedef enum _lt_xml_cldr_t {
LT_XML_CLDR_BCP47_END = LT_XML_CLDR_BCP47_VARIANT,
LT_XML_CLDR_DUMMY1 = 100,
LT_XML_CLDR_SUPPLEMENTAL_LIKELY_SUBTAGS,
+ LT_XML_CLDR_SUPPLEMENTAL_SUPPLEMENTAL_DATA,
LT_XML_CLDR_SUPPLEMENTAL_BEGIN = LT_XML_CLDR_SUPPLEMENTAL_LIKELY_SUBTAGS,
- LT_XML_CLDR_SUPPLEMENTAL_END = LT_XML_CLDR_SUPPLEMENTAL_LIKELY_SUBTAGS,
+ LT_XML_CLDR_SUPPLEMENTAL_END = LT_XML_CLDR_SUPPLEMENTAL_SUPPLEMENTAL_DATA,
LT_XML_CLDR_END
} lt_xml_cldr_t;
diff --git a/tests/tag.c b/tests/tag.c
index aa8c109..30fba88 100644
--- a/tests/tag.c
+++ b/tests/tag.c
@@ -34,7 +34,7 @@ main(int argc,
if (lt_strcmp0(argv[1], "help") == 0) {
help:
printf("Usage: %s <command> ...\n"
- "commands: canonicalize, ecanonicalize, dump, from_locale, from_locale_s, lookup, match, to_locale, transform\n",
+ "commands: canonicalize, ecanonicalize, dump, from_locale, from_locale_s, lookup, match, script, to_locale, transform\n",
argv[0]);
} else if (lt_strcmp0(argv[1], "canonicalize") == 0) {
char *s;
@@ -105,6 +105,20 @@ main(int argc,
printf("%s -> %s\n", argv[2], r);
free(r);
}
+ } else if (lt_strcmp0(argv[1], "script") == 0) {
+ if (lt_tag_parse(tag, argv[2], NULL)) {
+ lt_relation_db_t *db = lt_db_get_relation();
+ const lt_lang_t *lang = lt_tag_get_language(tag);
+ lt_list_t *l, *ll = lt_relation_db_lookup_script_from_lang(db, lang);
+
+ printf("%s: ", lt_lang_get_tag(lang));
+ for (l = ll; l; l = lt_list_next(l)) {
+ lt_script_t *script = lt_list_value(l);
+
+ printf("%s ", lt_script_get_tag(script));
+ }
+ printf("\n");
+ }
} else {
goto help;
}