static gchar * _lt_ext_ldml_u_get_tag(lt_ext_module_data_t *data) { lt_ext_ldml_u_data_t *d = (lt_ext_ldml_u_data_t *)data; GString *s = g_string_new(NULL); GList *l; if (d->attributes) { d->attributes = g_list_sort(d->attributes, _lt_ext_ldml_u_sort_attributes); for (l = d->attributes; l != NULL; l = g_list_next(l)) { const gchar *a = l->data; if (s->len > 0) g_string_append_c(s, '-'); g_string_append(s, a); } } if (d->tags) { d->tags = g_list_sort(d->tags, _lt_ext_ldml_u_sort_tags); for (l = d->tags; l != NULL; l = g_list_next(l)) { const GString *t = l->data; gchar *ts = g_strdup(t->str); if (s->len > 0) g_string_append_c(s, '-'); if (t->len == 2) { /* XXX: do we need to auto-complete the clipped type here? */ } g_string_append(s, lt_strlower(ts)); g_free(ts); } } return g_string_free(s, FALSE); }
/** * lt_region_db_lookup: * @regiondb: a #lt_region_db_t. * @language_or_code: a region code to lookup. * * Lookup @lt_region_t if @language_or_code is valid and registered into * the database. * * Returns: (transfer full): a #lt_region_t that meets with @language_or_code. * otherwise %NULL. */ lt_region_t * lt_region_db_lookup(lt_region_db_t *regiondb, const gchar *language_or_code) { lt_region_t *retval; gchar *s; g_return_val_if_fail (regiondb != NULL, NULL); g_return_val_if_fail (language_or_code != NULL, NULL); s = g_strdup(language_or_code); retval = g_hash_table_lookup(regiondb->region_entries, lt_strlower(s)); g_free(s); if (retval) return lt_region_ref(retval); return NULL; }
/** * lt_script_db_lookup: * @scriptdb: a #lt_script_db_t. * @subtag: a subtag name to lookup. * * Lookup @lt_script_t if @subtag is valid and registered into the database. * * Returns: (transfer full): a #lt_script_t that meets with @subtag. * otherwise %NULL. */ lt_script_t * lt_script_db_lookup(lt_script_db_t *scriptdb, const char *subtag) { lt_script_t *retval; char *s; lt_return_val_if_fail (scriptdb != NULL, NULL); lt_return_val_if_fail (subtag != NULL, NULL); s = strdup(subtag); retval = lt_trie_lookup(scriptdb->script_entries, lt_strlower(s)); free(s); if (retval) return lt_script_ref(retval); return NULL; }
/** * lt_extlang_db_lookup: * @extlangdb: a #lt_extlang_db_t. * @subtag: a subtag name to lookup. * * Lookup @lt_extlang_t if @subtag is valid and registered into the database. * * Returns: (transfer full): a #lt_extlang_t that meets with @subtag. * otherwise %NULL. */ lt_extlang_t * lt_extlang_db_lookup(lt_extlang_db_t *extlangdb, const gchar *subtag) { lt_extlang_t *retval; gchar *s; g_return_val_if_fail (extlangdb != NULL, NULL); g_return_val_if_fail (subtag != NULL, NULL); s = g_strdup(subtag); retval = g_hash_table_lookup(extlangdb->extlang_entries, lt_strlower(s)); g_free(s); if (retval) return lt_extlang_ref(retval); return NULL; }
/*< private >*/ static gboolean lt_region_db_parse(lt_region_db_t *regiondb, GError **error) { gboolean retval = TRUE; xmlDocPtr doc = NULL; xmlXPathContextPtr xctxt = NULL; xmlXPathObjectPtr xobj = NULL; GError *err = NULL; int i, n; g_return_val_if_fail (regiondb != NULL, FALSE); doc = lt_xml_get_subtag_registry(regiondb->xml); xctxt = xmlXPathNewContext(doc); if (!xctxt) { g_set_error(&err, LT_ERROR, LT_ERR_OOM, "Unable to create an instance of xmlXPathContextPtr."); goto bail; } xobj = xmlXPathEvalExpression((const xmlChar *)"/registry/region", xctxt); if (!xobj) { g_set_error(&err, LT_ERROR, LT_ERR_FAIL_ON_XML, "No valid elements for %s", doc->name); goto bail; } n = xmlXPathNodeSetGetLength(xobj->nodesetval); for (i = 0; i < n; i++) { xmlNodePtr ent = xmlXPathNodeSetItem(xobj->nodesetval, i); xmlNodePtr cnode; xmlChar *subtag = NULL, *desc = NULL, *preferred = NULL; lt_region_t *le = NULL; gchar *s; if (!ent) { g_set_error(&err, LT_ERROR, LT_ERR_FAIL_ON_XML, "Unable to obtain the xml node via XPath."); goto bail; } cnode = ent->children; while (cnode != NULL) { if (xmlStrcmp(cnode->name, (const xmlChar *)"subtag") == 0) { if (subtag) { g_warning("Duplicate subtag element in region: previous value was '%s'", subtag); } else { subtag = xmlNodeGetContent(cnode); } } else if (xmlStrcmp(cnode->name, (const xmlChar *)"added") == 0 || xmlStrcmp(cnode->name, (const xmlChar *)"text") == 0 || xmlStrcmp(cnode->name, (const xmlChar *)"deprecated") == 0 || xmlStrcmp(cnode->name, (const xmlChar *)"comments") == 0) { /* ignore it */ } else if (xmlStrcmp(cnode->name, (const xmlChar *)"description") == 0) { /* wonder if many descriptions helps something. or is it a bug? */ if (!desc) desc = xmlNodeGetContent(cnode); } else if (xmlStrcmp(cnode->name, (const xmlChar *)"preferred-value") == 0) { if (preferred) { g_warning("Duplicate preferred-value element in region: previous value was '%s'", preferred); } else { preferred = xmlNodeGetContent(cnode); } } else { g_warning("Unknown node under /registry/region: %s", cnode->name); } cnode = cnode->next; } if (!subtag) { g_warning("No subtag node: description = '%s', preferred-value = '%s'", desc, preferred); goto bail1; } if (!desc) { g_warning("No description node: subtag = '%s', preferred-value = '%s'", subtag, preferred); goto bail1; } le = lt_region_create(); if (!le) { g_set_error(&err, LT_ERROR, LT_ERR_OOM, "Unable to create an instance of lt_region_t."); goto bail1; } lt_region_set_tag(le, (const gchar *)subtag); lt_region_set_name(le, (const gchar *)desc); if (preferred) lt_region_set_preferred_tag(le, (const gchar *)preferred); s = g_strdup(lt_region_get_tag(le)); g_hash_table_replace(regiondb->region_entries, lt_strlower(s), lt_region_ref(le)); bail1: if (subtag) xmlFree(subtag); if (desc) xmlFree(desc); if (preferred) xmlFree(preferred); lt_region_unref(le); } bail: if (err) { if (error) *error = g_error_copy(err); else g_warning(err->message); g_error_free(err); retval = FALSE; } if (xobj) xmlXPathFreeObject(xobj); if (xctxt) xmlXPathFreeContext(xctxt); return retval; }
/*< private >*/ static lt_bool_t lt_script_db_parse(lt_script_db_t *scriptdb, 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_return_val_if_fail (scriptdb != NULL, FALSE); doc = lt_xml_get_subtag_registry(scriptdb->xml); 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 *)"/registry/script", 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); for (i = 0; i < n; i++) { xmlNodePtr ent = xmlXPathNodeSetItem(xobj->nodesetval, i); xmlNodePtr cnode; xmlChar *subtag = NULL, *desc = NULL; lt_script_t *le = NULL; char *s; if (!ent) { lt_error_set(&err, LT_ERR_FAIL_ON_XML, "Unable to obtain the xml node via XPath."); goto bail; } cnode = ent->children; while (cnode != NULL) { if (xmlStrcmp(cnode->name, (const xmlChar *)"subtag") == 0) { if (subtag) { lt_warning("Duplicate subtag element in script: previous value was '%s'", subtag); } else { subtag = xmlNodeGetContent(cnode); } } else if (xmlStrcmp(cnode->name, (const xmlChar *)"added") == 0 || xmlStrcmp(cnode->name, (const xmlChar *)"text") == 0 || xmlStrcmp(cnode->name, (const xmlChar *)"comments") == 0) { /* ignore it */ } else if (xmlStrcmp(cnode->name, (const xmlChar *)"description") == 0) { /* wonder if many descriptions helps something. or is it a bug? */ if (!desc) desc = xmlNodeGetContent(cnode); } else { lt_warning("Unknown node under /registry/script: %s", cnode->name); } cnode = cnode->next; } if (!subtag) { lt_warning("No subtag node: description = '%s'", desc); goto bail1; } if (!desc) { lt_warning("No description node: subtag = '%s'", subtag); goto bail1; } le = lt_script_create(); if (!le) { lt_error_set(&err, LT_ERR_OOM, "Unable to create an instance of lt_script_t."); goto bail1; } lt_script_set_tag(le, (const char *)subtag); lt_script_set_name(le, (const char *)desc); s = strdup(lt_script_get_tag(le)); lt_trie_replace(scriptdb->script_entries, lt_strlower(s), lt_script_ref(le), (lt_destroy_func_t)lt_script_unref); free(s); bail1: if (subtag) xmlFree(subtag); if (desc) xmlFree(desc); lt_script_unref(le); } 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; }