/*< 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; }