diff options
author | Akira TAGOH <akira@tagoh.org> | 2016-02-24 19:57:18 +0900 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2016-02-24 20:00:50 +0900 |
commit | 417a24859a29c7b0e8f2062e480a995171b8747f (patch) | |
tree | da1ded6011bbfabaea8787ad746f540002c9ace8 | |
parent | feb0c1f5f0610b39668baff4978a6a926af78965 (diff) |
Improve the bootup time
Delay-loading the database when it is needed.
-rw-r--r-- | liblangtag/lt-database.c | 10 | ||||
-rw-r--r-- | liblangtag/lt-extlang-db.c | 89 | ||||
-rw-r--r-- | liblangtag/lt-grandfathered-db.c | 59 | ||||
-rw-r--r-- | liblangtag/lt-lang-db.c | 76 | ||||
-rw-r--r-- | liblangtag/lt-redundant-db.c | 59 | ||||
-rw-r--r-- | liblangtag/lt-region-db.c | 90 | ||||
-rw-r--r-- | liblangtag/lt-relation-db.c | 64 | ||||
-rw-r--r-- | liblangtag/lt-script-db.c | 90 | ||||
-rw-r--r-- | liblangtag/lt-variant-db.c | 90 | ||||
-rw-r--r-- | liblangtag/lt-xml.c | 154 |
10 files changed, 394 insertions, 387 deletions
diff --git a/liblangtag/lt-database.c b/liblangtag/lt-database.c index 424f309..6532c6b 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-2015 Akira TAGOH + * Copyright (C) 2011-2016 Akira TAGOH * * Authors: * Akira TAGOH <akira@tagoh.org> @@ -18,6 +18,7 @@ #include "lt-mem.h" #include "lt-ext-module.h" #include "lt-utils.h" +#include "lt-xml.h" #include "lt-database.h" @@ -31,6 +32,7 @@ static lt_db_val_t __dbval; static lt_db_val_t *__db_master = &__dbval; +static lt_xml_t *__db_xml = NULL; static char __lt_db_datadir[LT_PATH_MAX] = { 0 }; @@ -114,6 +116,11 @@ lt_db_initialize(void) lt_db_get_redundant(); if (!__db_master->relation) lt_db_get_relation(); + if (!__db_xml) { + __db_xml = lt_xml_new(); + lt_mem_add_weak_pointer((lt_mem_t *)__db_xml, + (lt_pointer_t *)&__db_xml); + } lt_ext_modules_load(); } @@ -134,6 +141,7 @@ lt_db_finalize(void) lt_grandfathered_db_unref(__db_master->grandfathered); lt_redundant_db_unref(__db_master->redundant); lt_relation_db_unref(__db_master->relation); + lt_xml_unref(__db_xml); lt_ext_modules_unload(); } diff --git a/liblangtag/lt-extlang-db.c b/liblangtag/lt-extlang-db.c index 3905757..b50d92f 100644 --- a/liblangtag/lt-extlang-db.c +++ b/liblangtag/lt-extlang-db.c @@ -20,6 +20,7 @@ #include "lt-extlang.h" #include "lt-extlang-private.h" #include "lt-iter-private.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -38,7 +39,6 @@ */ struct _lt_extlang_db_t { lt_iter_tmpl_t parent; - lt_xml_t *xml; lt_trie_t *extlang_entries; }; typedef struct _lt_extlang_db_iter_t { @@ -46,21 +46,44 @@ typedef struct _lt_extlang_db_iter_t { lt_iter_t *iter; } lt_extlang_db_iter_t; +LT_LOCK_DEFINE_STATIC (edb); + /*< private >*/ static lt_bool_t lt_extlang_db_parse(lt_extlang_db_t *extlangdb, lt_error_t **error) { + lt_xml_t *xml; lt_bool_t retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; xmlXPathObjectPtr xobj = NULL; lt_error_t *err = NULL; int i, n; + lt_extlang_t *le; lt_return_val_if_fail (extlangdb != NULL, FALSE); - doc = lt_xml_get_subtag_registry(extlangdb->xml); + extlangdb->extlang_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)extlangdb, extlangdb->extlang_entries, + (lt_destroy_func_t)lt_trie_unref); + le = lt_extlang_create(); + lt_extlang_set_tag(le, "*"); + lt_extlang_set_name(le, "Wildcard entry"); + lt_trie_replace(extlangdb->extlang_entries, + lt_extlang_get_tag(le), + le, + (lt_destroy_func_t)lt_extlang_unref); + le = lt_extlang_create(); + lt_extlang_set_tag(le, ""); + lt_extlang_set_name(le, "Empty entry"); + lt_trie_replace(extlangdb->extlang_entries, + lt_extlang_get_tag(le), + le, + (lt_destroy_func_t)lt_extlang_unref); + + xml = lt_xml_new(); + doc = lt_xml_get_subtag_registry(xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -189,6 +212,8 @@ lt_extlang_db_parse(lt_extlang_db_t *extlangdb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -199,6 +224,15 @@ _lt_extlang_db_iter_init(lt_iter_tmpl_t *tmpl) lt_extlang_db_iter_t *retval; lt_extlang_db_t *extlangdb = (lt_extlang_db_t *)tmpl; + LT_LOCK (edb); + if (!extlangdb->extlang_entries) { + if (!lt_extlang_db_parse(extlangdb, NULL)) { + LT_UNLOCK (edb); + return NULL; + } + } + LT_UNLOCK (edb); + retval = malloc(sizeof (lt_extlang_db_iter_t)); if (!retval) return NULL; @@ -242,49 +276,9 @@ lt_extlang_db_new(void) { lt_extlang_db_t *retval = lt_mem_alloc_object(sizeof (lt_extlang_db_t)); - if (retval) { - lt_error_t *err = NULL; - lt_extlang_t *le; - + if (retval) LT_ITER_TMPL_INIT (&retval->parent, _lt_extlang_db); - retval->extlang_entries = lt_trie_new(); - lt_mem_add_ref((lt_mem_t *)retval, retval->extlang_entries, - (lt_destroy_func_t)lt_trie_unref); - - le = lt_extlang_create(); - lt_extlang_set_tag(le, "*"); - lt_extlang_set_name(le, "Wildcard entry"); - lt_trie_replace(retval->extlang_entries, - lt_extlang_get_tag(le), - le, - (lt_destroy_func_t)lt_extlang_unref); - le = lt_extlang_create(); - lt_extlang_set_tag(le, ""); - lt_extlang_set_name(le, "Empty entry"); - lt_trie_replace(retval->extlang_entries, - lt_extlang_get_tag(le), - le, - (lt_destroy_func_t)lt_extlang_unref); - - retval->xml = lt_xml_new(); - if (!retval->xml) { - lt_extlang_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_extlang_db_parse(retval, &err); - if (err) { - lt_error_print(err, LT_ERR_ANY); - lt_extlang_db_unref(retval); - retval = NULL; - lt_error_unref(err); - } - } - bail: - return retval; } @@ -338,6 +332,15 @@ lt_extlang_db_lookup(lt_extlang_db_t *extlangdb, lt_return_val_if_fail (extlangdb != NULL, NULL); lt_return_val_if_fail (subtag != NULL, NULL); + LT_LOCK (edb); + if (!extlangdb->extlang_entries) { + if (!lt_extlang_db_parse(extlangdb, NULL)) { + LT_UNLOCK (edb); + return NULL; + } + } + LT_UNLOCK (edb); + s = strdup(subtag); retval = lt_trie_lookup(extlangdb->extlang_entries, lt_strlower(s)); diff --git a/liblangtag/lt-grandfathered-db.c b/liblangtag/lt-grandfathered-db.c index 03cae56..494f641 100644 --- a/liblangtag/lt-grandfathered-db.c +++ b/liblangtag/lt-grandfathered-db.c @@ -20,6 +20,7 @@ #include "lt-grandfathered.h" #include "lt-grandfathered-private.h" #include "lt-iter-private.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -38,7 +39,6 @@ */ struct _lt_grandfathered_db_t { lt_iter_tmpl_t parent; - lt_xml_t *xml; lt_trie_t *grandfathered_entries; }; typedef struct _lt_grandfathered_db_iter_t { @@ -46,11 +46,14 @@ typedef struct _lt_grandfathered_db_iter_t { lt_iter_t *iter; } lt_grandfathered_db_iter_t; +LT_LOCK_DEFINE_STATIC (gdb); + /*< private >*/ static lt_bool_t lt_grandfathered_db_parse(lt_grandfathered_db_t *grandfathereddb, lt_error_t **error) { + lt_xml_t *xml; lt_bool_t retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; @@ -60,7 +63,12 @@ lt_grandfathered_db_parse(lt_grandfathered_db_t *grandfathereddb, lt_return_val_if_fail (grandfathereddb != NULL, FALSE); - doc = lt_xml_get_subtag_registry(grandfathereddb->xml); + xml = lt_xml_new(); + grandfathereddb->grandfathered_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)grandfathereddb, grandfathereddb->grandfathered_entries, + (lt_destroy_func_t)lt_trie_unref); + + doc = lt_xml_get_subtag_registry(xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -168,6 +176,8 @@ lt_grandfathered_db_parse(lt_grandfathered_db_t *grandfathereddb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -178,6 +188,15 @@ _lt_grandfathered_db_iter_init(lt_iter_tmpl_t *tmpl) lt_grandfathered_db_iter_t *retval; lt_grandfathered_db_t *db = (lt_grandfathered_db_t *)tmpl; + LT_LOCK (gdb); + if (!db->grandfathered_entries) { + if (!lt_grandfathered_db_parse(db, NULL)) { + LT_UNLOCK (gdb); + return NULL; + } + } + LT_UNLOCK (gdb); + retval = malloc(sizeof (lt_grandfathered_db_iter_t)); if (!retval) return NULL; @@ -221,34 +240,9 @@ lt_grandfathered_db_new(void) { lt_grandfathered_db_t *retval = lt_mem_alloc_object(sizeof (lt_grandfathered_db_t)); - if (retval) { - lt_error_t *err = NULL; - + if (retval) LT_ITER_TMPL_INIT (&retval->parent, _lt_grandfathered_db); - retval->grandfathered_entries = lt_trie_new(); - lt_mem_add_ref((lt_mem_t *)retval, retval->grandfathered_entries, - (lt_destroy_func_t)lt_trie_unref); - - retval->xml = lt_xml_new(); - if (!retval->xml) { - lt_grandfathered_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_grandfathered_db_parse(retval, &err); - if (lt_error_is_set(err, LT_ERR_ANY)) { - lt_error_print(err, LT_ERR_ANY); - lt_grandfathered_db_unref(retval); - retval = NULL; - lt_error_unref(err); - } - } - bail: - return retval; } @@ -302,6 +296,15 @@ lt_grandfathered_db_lookup(lt_grandfathered_db_t *grandfathereddb, lt_return_val_if_fail (grandfathereddb != NULL, NULL); lt_return_val_if_fail (tag != NULL, NULL); + LT_LOCK (gdb); + if (!grandfathereddb->grandfathered_entries) { + if (!lt_grandfathered_db_parse(grandfathereddb, NULL)) { + LT_UNLOCK (gdb); + return NULL; + } + } + LT_UNLOCK (gdb); + s = strdup(tag); retval = lt_trie_lookup(grandfathereddb->grandfathered_entries, lt_strlower(s)); diff --git a/liblangtag/lt-lang-db.c b/liblangtag/lt-lang-db.c index 37b59ab..43391ed 100644 --- a/liblangtag/lt-lang-db.c +++ b/liblangtag/lt-lang-db.c @@ -18,6 +18,7 @@ #include <libxml/xpath.h> #include "lt-error.h" #include "lt-iter-private.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -37,7 +38,6 @@ */ struct _lt_lang_db_t { lt_iter_tmpl_t parent; - lt_xml_t *xml; lt_trie_t *lang_entries; }; typedef struct _lt_lang_db_iter_t { @@ -45,11 +45,15 @@ typedef struct _lt_lang_db_iter_t { lt_iter_t *iter; } lt_lang_db_iter_t; +LT_LOCK_DEFINE_STATIC (ldb); + /*< private >*/ static lt_bool_t lt_lang_db_parse(lt_lang_db_t *langdb, lt_error_t **error) { + lt_xml_t *xml; + lt_lang_t *le; lt_bool_t retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; @@ -59,7 +63,19 @@ lt_lang_db_parse(lt_lang_db_t *langdb, lt_return_val_if_fail (langdb != NULL, FALSE); - doc = lt_xml_get_subtag_registry(langdb->xml); + langdb->lang_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)langdb, langdb->lang_entries, + (lt_destroy_func_t)lt_trie_unref); + le = lt_lang_create(); + lt_lang_set_tag(le, "*"); + lt_lang_set_name(le, "Wildcard entry"); + lt_trie_replace(langdb->lang_entries, + lt_lang_get_tag(le), + le, + (lt_destroy_func_t)lt_lang_unref); + + xml = lt_xml_new(); + doc = lt_xml_get_subtag_registry(xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -201,6 +217,8 @@ lt_lang_db_parse(lt_lang_db_t *langdb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -211,6 +229,15 @@ _lt_lang_db_iter_init(lt_iter_tmpl_t *tmpl) lt_lang_db_iter_t *retval; lt_lang_db_t *langdb = (lt_lang_db_t *)tmpl; + LT_LOCK (ldb); + if (!langdb->lang_entries) { + if (!lt_lang_db_parse(langdb, NULL)) { + LT_UNLOCK (ldb); + return NULL; + } + } + LT_UNLOCK (ldb); + retval = malloc(sizeof (lt_lang_db_iter_t)); if (!retval) return NULL; @@ -254,43 +281,9 @@ lt_lang_db_new(void) { lt_lang_db_t *retval = lt_mem_alloc_object(sizeof (lt_lang_db_t)); - if (retval) { - lt_error_t *err = NULL; - lt_lang_t *le; - + if (retval) LT_ITER_TMPL_INIT (&retval->parent, _lt_lang_db); - retval->lang_entries = lt_trie_new(); - lt_mem_add_ref((lt_mem_t *)retval, retval->lang_entries, - (lt_destroy_func_t)lt_trie_unref); - - le = lt_lang_create(); - lt_lang_set_tag(le, "*"); - lt_lang_set_name(le, "Wildcard entry"); - lt_trie_replace(retval->lang_entries, - lt_lang_get_tag(le), - le, - (lt_destroy_func_t)lt_lang_unref); - - retval->xml = lt_xml_new(); - if (!retval->xml) { - lt_lang_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_lang_db_parse(retval, &err); - if (lt_error_is_set(err, LT_ERR_ANY)) { - lt_error_print(err, LT_ERR_ANY); - lt_lang_db_unref(retval); - retval = NULL; - lt_error_unref(err); - } - } - bail: - return retval; } @@ -344,6 +337,15 @@ lt_lang_db_lookup(lt_lang_db_t *langdb, lt_return_val_if_fail (langdb != NULL, NULL); lt_return_val_if_fail (subtag != NULL, NULL); + LT_LOCK (ldb); + if (!langdb->lang_entries) { + if (!lt_lang_db_parse(langdb, NULL)) { + LT_UNLOCK (ldb); + return NULL; + } + } + LT_UNLOCK (ldb); + s = strdup(subtag); retval = lt_trie_lookup(langdb->lang_entries, lt_strlower(s)); free(s); diff --git a/liblangtag/lt-redundant-db.c b/liblangtag/lt-redundant-db.c index 7fe7b92..3cfcb4a 100644 --- a/liblangtag/lt-redundant-db.c +++ b/liblangtag/lt-redundant-db.c @@ -21,6 +21,7 @@ #include "lt-error.h" #include "lt-redundant.h" #include "lt-redundant-private.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -40,7 +41,6 @@ */ struct _lt_redundant_db_t { lt_iter_tmpl_t parent; - lt_xml_t *xml; lt_trie_t *redundant_entries; }; typedef struct _lt_redundant_db_iter_t { @@ -48,11 +48,14 @@ typedef struct _lt_redundant_db_iter_t { lt_iter_t *iter; } lt_redundant_db_iter_t; +LT_LOCK_DEFINE_STATIC (rdb); + /*< private >*/ static lt_bool_t lt_redundant_db_parse(lt_redundant_db_t *redundantdb, lt_error_t **error) { + lt_xml_t *xml; lt_bool_t retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; @@ -62,7 +65,12 @@ lt_redundant_db_parse(lt_redundant_db_t *redundantdb, lt_return_val_if_fail (redundantdb != NULL, FALSE); - doc = lt_xml_get_subtag_registry(redundantdb->xml); + redundantdb->redundant_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)redundantdb, redundantdb->redundant_entries, + (lt_destroy_func_t)lt_trie_unref); + + xml = lt_xml_new(); + doc = lt_xml_get_subtag_registry(xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -169,6 +177,8 @@ lt_redundant_db_parse(lt_redundant_db_t *redundantdb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -179,6 +189,15 @@ _lt_redundant_db_iter_init(lt_iter_tmpl_t *tmpl) lt_redundant_db_iter_t *retval; lt_redundant_db_t *db = (lt_redundant_db_t *)tmpl; + LT_LOCK (rdb); + if (!db->redundant_entries) { + if (!lt_redundant_db_parse(db, NULL)) { + LT_UNLOCK (rdb); + return NULL; + } + } + LT_UNLOCK (rdb); + retval = malloc(sizeof (lt_redundant_db_iter_t)); if (!retval) return NULL; @@ -222,34 +241,9 @@ lt_redundant_db_new(void) { lt_redundant_db_t *retval = lt_mem_alloc_object(sizeof (lt_redundant_db_t)); - if (retval) { - lt_error_t *err = NULL; - + if (retval) LT_ITER_TMPL_INIT (&retval->parent, _lt_redundant_db); - retval->redundant_entries = lt_trie_new(); - lt_mem_add_ref((lt_mem_t *)retval, retval->redundant_entries, - (lt_destroy_func_t)lt_trie_unref); - - retval->xml = lt_xml_new(); - if (!retval->xml) { - lt_redundant_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_redundant_db_parse(retval, &err); - if (lt_error_is_set(err, LT_ERR_ANY)) { - lt_error_print(err, LT_ERR_ANY); - lt_redundant_db_unref(retval); - retval = NULL; - lt_error_unref(err); - } - } - bail: - return retval; } @@ -303,6 +297,15 @@ lt_redundant_db_lookup(lt_redundant_db_t *redundantdb, lt_return_val_if_fail (redundantdb != NULL, NULL); lt_return_val_if_fail (tag != NULL, NULL); + LT_LOCK (rdb); + if (!redundantdb->redundant_entries) { + if (!lt_redundant_db_parse(redundantdb, NULL)) { + LT_UNLOCK (rdb); + return NULL; + } + } + LT_UNLOCK (rdb); + s = strdup(tag); retval = lt_trie_lookup(redundantdb->redundant_entries, lt_strlower(s)); diff --git a/liblangtag/lt-region-db.c b/liblangtag/lt-region-db.c index 44b4558..9faae42 100644 --- a/liblangtag/lt-region-db.c +++ b/liblangtag/lt-region-db.c @@ -19,6 +19,7 @@ #include <libxml/xpath.h> #include "lt-error.h" #include "lt-iter-private.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -39,7 +40,6 @@ */ struct _lt_region_db_t { lt_iter_tmpl_t parent; - lt_xml_t *xml; lt_trie_t *region_entries; }; typedef struct _lt_region_db_iter_t { @@ -47,11 +47,15 @@ typedef struct _lt_region_db_iter_t { lt_iter_t *iter; } lt_region_db_iter_t; +LT_LOCK_DEFINE_STATIC (rdb); + /*< private >*/ static lt_bool_t lt_region_db_parse(lt_region_db_t *regiondb, lt_error_t **error) { + lt_xml_t *xml; + lt_region_t *le; lt_bool_t retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; @@ -61,7 +65,26 @@ lt_region_db_parse(lt_region_db_t *regiondb, lt_return_val_if_fail (regiondb != NULL, FALSE); - doc = lt_xml_get_subtag_registry(regiondb->xml); + regiondb->region_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)regiondb, regiondb->region_entries, + (lt_destroy_func_t)lt_trie_unref); + le = lt_region_create(); + lt_region_set_tag(le, "*"); + lt_region_set_name(le, "Wildcard entry"); + lt_trie_replace(regiondb->region_entries, + lt_region_get_tag(le), + le, + (lt_destroy_func_t)lt_region_unref); + le = lt_region_create(); + lt_region_set_tag(le, ""); + lt_region_set_name(le, "Empty entry"); + lt_trie_replace(regiondb->region_entries, + lt_region_get_tag(le), + le, + (lt_destroy_func_t)lt_region_unref); + + xml = lt_xml_new(); + doc = lt_xml_get_subtag_registry(xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -169,6 +192,8 @@ lt_region_db_parse(lt_region_db_t *regiondb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -179,6 +204,15 @@ _lt_region_db_iter_init(lt_iter_tmpl_t *tmpl) lt_region_db_iter_t *retval; lt_region_db_t *db = (lt_region_db_t *)tmpl; + LT_LOCK (rdb); + if (!db->region_entries) { + if (!lt_region_db_parse(db, NULL)) { + LT_UNLOCK (rdb); + return NULL; + } + } + LT_UNLOCK (rdb); + retval = malloc(sizeof (lt_region_db_iter_t)); if (!retval) return NULL; @@ -222,50 +256,9 @@ lt_region_db_new(void) { lt_region_db_t *retval = lt_mem_alloc_object(sizeof (lt_region_db_t)); - if (retval) { - lt_error_t *err = NULL; - lt_region_t *le; - + if (retval) LT_ITER_TMPL_INIT (&retval->parent, _lt_region_db); - retval->region_entries = lt_trie_new(); - lt_mem_add_ref((lt_mem_t *)retval, retval->region_entries, - (lt_destroy_func_t)lt_trie_unref); - - le = lt_region_create(); - lt_region_set_tag(le, "*"); - lt_region_set_name(le, "Wildcard entry"); - lt_trie_replace(retval->region_entries, - lt_region_get_tag(le), - le, - (lt_destroy_func_t)lt_region_unref); - le = lt_region_create(); - lt_region_set_tag(le, ""); - lt_region_set_name(le, "Empty entry"); - lt_trie_replace(retval->region_entries, - lt_region_get_tag(le), - le, - (lt_destroy_func_t)lt_region_unref); - - retval->xml = lt_xml_new(); - if (!retval->xml) { - lt_region_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_region_db_parse(retval, &err); - if (lt_error_is_set(err, LT_ERR_ANY)) { - lt_error_print(err, LT_ERR_ANY); - lt_region_db_unref(retval); - retval = NULL; - lt_error_unref(err); - } - } - bail: - return retval; } @@ -320,6 +313,15 @@ lt_region_db_lookup(lt_region_db_t *regiondb, lt_return_val_if_fail (regiondb != NULL, NULL); lt_return_val_if_fail (language_or_code != NULL, NULL); + LT_LOCK (rdb); + if (!regiondb->region_entries) { + if (!lt_region_db_parse(regiondb, NULL)) { + LT_UNLOCK (rdb); + return NULL; + } + } + LT_UNLOCK (rdb); + s = strdup(language_or_code); retval = lt_trie_lookup(regiondb->region_entries, lt_strlower(s)); diff --git a/liblangtag/lt-relation-db.c b/liblangtag/lt-relation-db.c index 8aa1b31..f3badfd 100644 --- a/liblangtag/lt-relation-db.c +++ b/liblangtag/lt-relation-db.c @@ -1,7 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * lt-relation-db.c - * Copyright (C) 2015 Akira TAGOH + * Copyright (C) 2015-2016 Akira TAGOH * * Authors: * Akira TAGOH <akira@tagoh.org> @@ -20,6 +20,7 @@ #include "lt-database.h" #include "lt-error.h" #include "lt-list.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -36,11 +37,12 @@ */ 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; }; +LT_LOCK_DEFINE_STATIC (rdb); + /*< private >*/ static lt_bool_t lt_relation_db_parse(lt_relation_db_t *relationdb, @@ -54,10 +56,19 @@ lt_relation_db_parse(lt_relation_db_t *relationdb, int i, n; lt_lang_db_t *langdb = NULL; lt_script_db_t *scriptdb = NULL; + lt_xml_t *xml; lt_return_val_if_fail (relationdb != NULL, FALSE); - doc = lt_xml_get_cldr(relationdb->xml, LT_XML_CLDR_SUPPLEMENTAL_SUPPLEMENTAL_DATA); + relationdb->relation_l_s_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)relationdb, relationdb->relation_l_s_entries, + (lt_destroy_func_t)lt_trie_unref); + relationdb->relation_s_l_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)relationdb, relationdb->relation_s_l_entries, + (lt_destroy_func_t)lt_trie_unref); + + xml = lt_xml_new(); + doc = lt_xml_get_cldr(xml, LT_XML_CLDR_SUPPLEMENTAL_SUPPLEMENTAL_DATA); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -153,6 +164,8 @@ lt_relation_db_parse(lt_relation_db_t *relationdb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -170,33 +183,6 @@ 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; } @@ -244,6 +230,15 @@ lt_relation_db_lookup_lang_from_script(lt_relation_db_t *relationdb, lt_return_val_if_fail (relationdb != NULL, NULL); lt_return_val_if_fail (script != NULL, NULL); + LT_LOCK (rdb); + if (!relationdb->relation_s_l_entries) { + if (!lt_relation_db_parse(relationdb, NULL)) { + LT_UNLOCK (rdb); + return NULL; + } + } + LT_UNLOCK (rdb); + key = strdup(lt_script_get_name(script)); l = lt_trie_lookup(relationdb->relation_s_l_entries, lt_strlower(key)); @@ -272,6 +267,15 @@ lt_relation_db_lookup_script_from_lang(lt_relation_db_t *relationdb, lt_return_val_if_fail (relationdb != NULL, NULL); lt_return_val_if_fail (lang != NULL, NULL); + LT_LOCK (rdb); + if (!relationdb->relation_l_s_entries) { + if (!lt_relation_db_parse(relationdb, NULL)) { + LT_UNLOCK (rdb); + return NULL; + } + } + LT_UNLOCK (rdb); + key = strdup(lt_lang_get_tag(lang)); l = lt_trie_lookup(relationdb->relation_l_s_entries, lt_strlower(key)); diff --git a/liblangtag/lt-script-db.c b/liblangtag/lt-script-db.c index 34b0c3b..8278078 100644 --- a/liblangtag/lt-script-db.c +++ b/liblangtag/lt-script-db.c @@ -19,6 +19,7 @@ #include <libxml/xpath.h> #include "lt-error.h" #include "lt-iter-private.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -38,7 +39,6 @@ */ struct _lt_script_db_t { lt_iter_tmpl_t parent; - lt_xml_t *xml; lt_trie_t *script_entries; }; typedef struct _lt_script_db_iter_t { @@ -46,11 +46,15 @@ typedef struct _lt_script_db_iter_t { lt_iter_t *iter; } lt_script_db_iter_t; +LT_LOCK_DEFINE_STATIC (sdb); + /*< private >*/ static lt_bool_t lt_script_db_parse(lt_script_db_t *scriptdb, lt_error_t **error) { + lt_xml_t *xml; + lt_script_t *le; lt_bool_t retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; @@ -60,7 +64,26 @@ lt_script_db_parse(lt_script_db_t *scriptdb, lt_return_val_if_fail (scriptdb != NULL, FALSE); - doc = lt_xml_get_subtag_registry(scriptdb->xml); + scriptdb->script_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)scriptdb, scriptdb->script_entries, + (lt_destroy_func_t)lt_trie_unref); + le = lt_script_create(); + lt_script_set_tag(le, "*"); + lt_script_set_name(le, "Wildcard entry"); + lt_trie_replace(scriptdb->script_entries, + lt_script_get_tag(le), + le, + (lt_destroy_func_t)lt_script_unref); + le = lt_script_create(); + lt_script_set_tag(le, ""); + lt_script_set_name(le, "Empty entry"); + lt_trie_replace(scriptdb->script_entries, + lt_script_get_tag(le), + le, + (lt_destroy_func_t)lt_script_unref); + + xml = lt_xml_new(); + doc = lt_xml_get_subtag_registry(xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -156,6 +179,8 @@ lt_script_db_parse(lt_script_db_t *scriptdb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -166,6 +191,15 @@ _lt_script_db_iter_init(lt_iter_tmpl_t *tmpl) lt_script_db_iter_t *retval; lt_script_db_t *db = (lt_script_db_t *)tmpl; + LT_LOCK (sdb); + if (!db->script_entries) { + if (!lt_script_db_parse(db, NULL)) { + LT_UNLOCK (sdb); + return NULL; + } + } + LT_UNLOCK (sdb); + retval = malloc(sizeof (lt_script_db_iter_t)); if (!retval) return NULL; @@ -209,50 +243,9 @@ lt_script_db_new(void) { lt_script_db_t *retval = lt_mem_alloc_object(sizeof (lt_script_db_t)); - if (retval) { - lt_error_t *err = NULL; - lt_script_t *le; - + if (retval) LT_ITER_TMPL_INIT (&retval->parent, _lt_script_db); - retval->script_entries = lt_trie_new(); - lt_mem_add_ref((lt_mem_t *)retval, retval->script_entries, - (lt_destroy_func_t)lt_trie_unref); - - le = lt_script_create(); - lt_script_set_tag(le, "*"); - lt_script_set_name(le, "Wildcard entry"); - lt_trie_replace(retval->script_entries, - lt_script_get_tag(le), - le, - (lt_destroy_func_t)lt_script_unref); - le = lt_script_create(); - lt_script_set_tag(le, ""); - lt_script_set_name(le, "Empty entry"); - lt_trie_replace(retval->script_entries, - lt_script_get_tag(le), - le, - (lt_destroy_func_t)lt_script_unref); - - retval->xml = lt_xml_new(); - if (!retval->xml) { - lt_script_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_script_db_parse(retval, &err); - if (lt_error_is_set(err, LT_ERR_ANY)) { - lt_error_print(err, LT_ERR_ANY); - lt_script_db_unref(retval); - retval = NULL; - lt_error_unref(err); - } - } - bail: - return retval; } @@ -306,6 +299,15 @@ lt_script_db_lookup(lt_script_db_t *scriptdb, lt_return_val_if_fail (scriptdb != NULL, NULL); lt_return_val_if_fail (subtag != NULL, NULL); + LT_LOCK (sdb); + if (!scriptdb->script_entries) { + if (!lt_script_db_parse(scriptdb, NULL)) { + LT_UNLOCK (sdb); + return NULL; + } + } + LT_UNLOCK (sdb); + s = strdup(subtag); retval = lt_trie_lookup(scriptdb->script_entries, lt_strlower(s)); diff --git a/liblangtag/lt-variant-db.c b/liblangtag/lt-variant-db.c index eb2e1ae..7717d66 100644 --- a/liblangtag/lt-variant-db.c +++ b/liblangtag/lt-variant-db.c @@ -22,6 +22,7 @@ #include "lt-variant.h" #include "lt-variant-private.h" #include "lt-list.h" +#include "lt-lock.h" #include "lt-mem.h" #include "lt-messages.h" #include "lt-trie.h" @@ -40,7 +41,6 @@ */ struct _lt_variant_db_t { lt_iter_tmpl_t parent; - lt_xml_t *xml; lt_trie_t *variant_entries; }; typedef struct _lt_variant_db_iter_t { @@ -48,11 +48,15 @@ typedef struct _lt_variant_db_iter_t { lt_iter_t *iter; } lt_variant_db_iter_t; +LT_LOCK_DEFINE_STATIC (vdb); + /*< private >*/ static lt_bool_t lt_variant_db_parse(lt_variant_db_t *variantdb, lt_error_t **error) { + lt_xml_t *xml; + lt_variant_t *le; lt_bool_t retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; @@ -62,7 +66,26 @@ lt_variant_db_parse(lt_variant_db_t *variantdb, lt_return_val_if_fail (variantdb != NULL, FALSE); - doc = lt_xml_get_subtag_registry(variantdb->xml); + variantdb->variant_entries = lt_trie_new(); + lt_mem_add_ref((lt_mem_t *)variantdb, variantdb->variant_entries, + (lt_destroy_func_t)lt_trie_unref); + le = lt_variant_create(); + lt_variant_set_tag(le, "*"); + lt_variant_set_name(le, "Wildcard entry"); + lt_trie_replace(variantdb->variant_entries, + lt_variant_get_tag(le), + le, + (lt_destroy_func_t)lt_variant_unref); + le = lt_variant_create(); + lt_variant_set_tag(le, ""); + lt_variant_set_name(le, "Empty entry"); + lt_trie_replace(variantdb->variant_entries, + lt_variant_get_tag(le), + le, + (lt_destroy_func_t)lt_variant_unref); + + xml = lt_xml_new(); + doc = lt_xml_get_subtag_registry(xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { lt_error_set(&err, LT_ERR_OOM, @@ -179,6 +202,8 @@ lt_variant_db_parse(lt_variant_db_t *variantdb, xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); + if (xml) + lt_xml_unref(xml); return retval; } @@ -189,6 +214,15 @@ _lt_variant_db_iter_init(lt_iter_tmpl_t *tmpl) lt_variant_db_iter_t *retval; lt_variant_db_t *db = (lt_variant_db_t *)tmpl; + LT_LOCK (vdb); + if (!db->variant_entries) { + if (!lt_variant_db_parse(db, NULL)) { + LT_UNLOCK (vdb); + return NULL; + } + } + LT_UNLOCK (vdb); + retval = malloc(sizeof (lt_variant_db_iter_t)); if (!retval) return NULL; @@ -232,50 +266,9 @@ lt_variant_db_new(void) { lt_variant_db_t *retval = lt_mem_alloc_object(sizeof (lt_variant_db_t)); - if (retval) { - lt_error_t *err = NULL; - lt_variant_t *le; - + if (retval) LT_ITER_TMPL_INIT (&retval->parent, _lt_variant_db); - retval->variant_entries = lt_trie_new(); - lt_mem_add_ref((lt_mem_t *)retval, retval->variant_entries, - (lt_destroy_func_t)lt_trie_unref); - - le = lt_variant_create(); - lt_variant_set_tag(le, "*"); - lt_variant_set_name(le, "Wildcard entry"); - lt_trie_replace(retval->variant_entries, - lt_variant_get_tag(le), - le, - (lt_destroy_func_t)lt_variant_unref); - le = lt_variant_create(); - lt_variant_set_tag(le, ""); - lt_variant_set_name(le, "Empty entry"); - lt_trie_replace(retval->variant_entries, - lt_variant_get_tag(le), - le, - (lt_destroy_func_t)lt_variant_unref); - - retval->xml = lt_xml_new(); - if (!retval->xml) { - lt_variant_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_variant_db_parse(retval, &err); - if (lt_error_is_set(err, LT_ERR_ANY)) { - lt_error_print(err, LT_ERR_ANY); - lt_error_unref(err); - lt_variant_db_unref(retval); - retval = NULL; - } - } - bail: - return retval; } @@ -329,6 +322,15 @@ lt_variant_db_lookup(lt_variant_db_t *variantdb, lt_return_val_if_fail (variantdb != NULL, NULL); lt_return_val_if_fail (subtag != NULL, NULL); + LT_LOCK (vdb); + if (!variantdb->variant_entries) { + if (!lt_variant_db_parse(variantdb, NULL)) { + LT_UNLOCK (vdb); + return NULL; + } + } + LT_UNLOCK (vdb); + s = strdup(subtag); retval = lt_trie_lookup(variantdb->variant_entries, lt_strlower(s)); diff --git a/liblangtag/lt-xml.c b/liblangtag/lt-xml.c index 3baab53..46f0ece 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-2015 Akira TAGOH + * Copyright (C) 2011-2016 Akira TAGOH * * Authors: * Akira TAGOH <akira@tagoh.org> @@ -15,6 +15,7 @@ #endif #include <stddef.h> +#include <string.h> #include <sys/stat.h> #include <libxml/parser.h> #include <libxml/xpath.h> @@ -24,6 +25,7 @@ #include "lt-messages.h" #include "lt-database.h" #include "lt-string.h" +#include "lt-utils.h" #include "lt-xml.h" @@ -323,97 +325,12 @@ _lt_xml_merge_keys(lt_xml_t *xml, lt_xml_t * lt_xml_new(void) { - lt_error_t *err = NULL; - - LT_LOCK (xml); - - if (__xml) { - LT_UNLOCK (xml); - + if (__xml) return lt_xml_ref(__xml); - } __xml = lt_mem_alloc_object(sizeof (lt_xml_t)); - if (__xml) { - xmlDocPtr doc = NULL; - + if (__xml) lt_mem_add_weak_pointer(&__xml->parent, (lt_pointer_t *)&__xml); - if (!lt_xml_read_subtag_registry(__xml, &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "calendar.xml", - &__xml->cldr_bcp47_calendar, - &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "collation.xml", - &__xml->cldr_bcp47_collation, - &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "currency.xml", - &__xml->cldr_bcp47_currency, - &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "number.xml", - &__xml->cldr_bcp47_number, - &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "timezone.xml", - &__xml->cldr_bcp47_timezone, - &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "transform.xml", - &__xml->cldr_bcp47_transform, - &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "transform_ime.xml", - &doc, - &err)) - goto bail; - if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "transform_keyboard.xml", - &doc, - &err)) - goto bail; - if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "transform_mt.xml", - &doc, - &err)) - goto bail; - if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "transform_private_use.xml", - &doc, - &err)) - goto bail; - if (!_lt_xml_merge_keys(__xml, __xml->cldr_bcp47_transform, doc, &err)) - goto bail; - if (!lt_xml_read_cldr_bcp47(__xml, "variant.xml", - &__xml->cldr_bcp47_variant, - &err)) - goto bail; - if (!lt_xml_read_cldr_supplemental(__xml, "likelySubtags.xml", - &__xml->cldr_supplemental_likelysubtags, - &err)) - goto bail; - if (!lt_xml_read_cldr_supplemental(__xml, "supplementalData.xml", - &__xml->cldr_supplemental_supplementaldata, - &err)) - goto bail; - if (!lt_xml_read_cldr_supplemental(__xml, "supplementalMetadata.xml", - &__xml->cldr_supplemental_supplementalmetadata, - &err)) - goto bail; - } - - bail: - if (lt_error_is_set(err, LT_ERR_ANY)) { - lt_error_print(err, LT_ERR_ANY); - lt_error_unref(err); - lt_xml_unref(__xml); - } - - LT_UNLOCK (xml); return __xml; } @@ -436,8 +353,21 @@ lt_xml_unref(lt_xml_t *xml) xmlDocPtr lt_xml_get_subtag_registry(lt_xml_t *xml) { + lt_error_t *err = NULL; + lt_return_val_if_fail (xml != NULL, NULL); + LT_LOCK (xml); + if (!xml->subtag_registry) { + if (!lt_xml_read_subtag_registry(xml, &err)) { + LT_UNLOCK (xml); + lt_error_print(err, LT_ERR_ANY); + lt_error_unref(err); + return NULL; + } + } + LT_UNLOCK (xml); + return xml->subtag_registry; } @@ -445,19 +375,67 @@ xmlDocPtr lt_xml_get_cldr(lt_xml_t *xml, lt_xml_cldr_t type) { + lt_error_t *err = NULL; + lt_bool_t ret = FALSE; xmlDocPtr *pref; int idx; + const char *xml_files[] = { + "calendar.xml", "collation.xml", "currency.xml", "number.xml", "timezone.xml", "transform.xml:transform_ime.xml:transform_keyboard.xml:transform_mt.xml:transform_private_use.xml", "variant.xml", + "likelySubtags.xml", "supplementalData.xml", "supplementalMetadata.xml", + NULL + }; 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); + LT_LOCK (xml); 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; + if (!pref[idx - 1]) { + if (type >= LT_XML_CLDR_DUMMY1) { + ret = lt_xml_read_cldr_supplemental(xml, xml_files[idx - 1], &pref[idx - 1], &err); + } else if (type == LT_XML_CLDR_BCP47_TRANSFORM) { + const char *pp = xml_files[idx - 1]; + char *p, *s; + xmlDocPtr *d = &pref[idx - 1], doc = NULL; + + do { + p = index(pp, ':'); + if (p) + s = lt_strndup(pp, p - pp); + else + s = strdup(pp); + if (!lt_xml_read_cldr_bcp47(xml, s, d, &err)) + goto bail; + if (d == &doc) { + if (!_lt_xml_merge_keys(xml, pref[idx - 1], doc, &err)) + goto bail; + } else { + d = &doc; + } + free(s); + if (p) + pp = ++p; + } while (p); + ret = TRUE; + } else { + ret = lt_xml_read_cldr_bcp47(xml, xml_files[idx - 1], &pref[idx - 1], &err); + } + bail: + if (!ret) { + LT_UNLOCK (xml); + lt_error_print(err, LT_ERR_ANY); + lt_error_unref(err); + return NULL; + } + } + LT_UNLOCK (xml); + return pref[idx - 1]; } |