summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2010-09-16 15:12:39 +0100
committerDaniel P. Berrange <berrange@redhat.com>2011-04-19 16:13:30 +0100
commit04f595af1918e5026f59dfcf7f947e3b68da2f16 (patch)
tree52dc11cef01ea1805a3d2840ea76a928a1a6d221
parent81e4f0b62b1bfff128fea2b8e5bf32e92744be13 (diff)
Allow arbitrary custom xml attributes with an x- prefix
* data/libosinfo-dummy-data.xml: Some example custom attrs * osinfo/osinfo_entity.c, osinfo/osinfo_entity.h: Add a method for setting a parameter, rather than just adding to it * osinfo/osinfo_loader.c: Allow custom xml attrs with an 'x-' prefix * demo.js, demo.py: Update to demo new capabilities
-rw-r--r--data/libosinfo-dummy-data.xml3
-rwxr-xr-xexamples/demo.js10
-rwxr-xr-xexamples/demo.py13
-rw-r--r--osinfo/osinfo_entity.c24
-rw-r--r--osinfo/osinfo_entity.h1
-rw-r--r--osinfo/osinfo_loader.c46
6 files changed, 80 insertions, 17 deletions
diff --git a/data/libosinfo-dummy-data.xml b/data/libosinfo-dummy-data.xml
index 1287318..251df76 100644
--- a/data/libosinfo-dummy-data.xml
+++ b/data/libosinfo-dummy-data.xml
@@ -70,6 +70,9 @@
<name>Fedora 11</name>
<version>11</version>
<vendor>Fedora Project</vendor>
+ <x-fruit>apples</x-fruit>
+ <x-animal>marmot</x-animal>
+ <x-animal>aardvark</x-animal>
<!-- Device support for unspecified platform -->
<devices>
diff --git a/examples/demo.js b/examples/demo.js
index 1363337..1a76f7a 100755
--- a/examples/demo.js
+++ b/examples/demo.js
@@ -47,9 +47,11 @@ filter.add_constraint("class", drvclass)
var link = dep.get_preferred_device_link(new osinfo.DeviceLinkFilter({target_filter: filter}))
var dev = link.get_target()
var drv = link.get_param_value("driver")
-print ("For OS '" + os.get_param_value("name") + "' " +
- "with HV '" + hv.get_param_value("name") + "' " +
+print ("For OS '" + os.get_name() + "' " +
+ "fruit '" + os.get_param_value("x-fruit") + "' " +
+ "zoo '" + os.get_param_values("x-animal") + "' " +
+ "with HV '" + hv.get_name() + "' " +
"for class '" + drvclass + "' " +
- "use device '" + dev.get_param_value("name") + "' " +
- "with HV driver '" + drv + "'")
+ "use device '" + dev.get_name() + "' " +
+ "with HV driver '" + link.get_driver() + "'")
diff --git a/examples/demo.py b/examples/demo.py
index 6a60292..1fb1c07 100755
--- a/examples/demo.py
+++ b/examples/demo.py
@@ -42,9 +42,12 @@ fltr = osinfo.Filter()
fltr.add_constraint("class", drvclass)
link = dep.get_preferred_device_link(osinfo.DeviceLinkFilter(target_filter = fltr))
dev = link.get_target()
-drv = link.get_param_value("driver")
-print ("For OS '" + os.get_param_value("name") + "' " +
- "with HV '" + hv.get_param_value("name") + "' " +
+animals = os.get_param_value_list("x-animal")
+zoo = str.join(",", animals)
+print ("For OS '" + os.get_name() + "' " +
+ "fruit '" + os.get_param_value("x-fruit") + "' " +
+ "zoo '" + zoo + "' " +
+ "with HV '" + hv.get_name() + "' " +
"for class '" + drvclass + "' " +
- "use device '" + dev.get_param_value("name") + "' " +
- "with HV driver '" + drv + "'")
+ "use device '" + dev.get_name() + "' " +
+ "with HV driver '" + link.get_driver() + "'")
diff --git a/osinfo/osinfo_entity.c b/osinfo/osinfo_entity.c
index 439e3ee..d5406e8 100644
--- a/osinfo/osinfo_entity.c
+++ b/osinfo/osinfo_entity.c
@@ -171,6 +171,30 @@ osinfo_entity_init (OsinfoEntity *entity)
/**
+ * osinfo_entity_set_param:
+ * @entity: OsinfoEntity containing the parameters
+ * @key: the name of the key
+ * @value: the data to associated with that key
+ *
+ * Sets a new parameter against the entity. If the key already
+ * has a value associated with it, the existing value will be
+ * cleared.
+ */
+void osinfo_entity_set_param(OsinfoEntity *entity, const gchar *key, const gchar *value)
+{
+ g_return_if_fail(OSINFO_IS_ENTITY(entity));
+ g_return_if_fail(key != NULL);
+ g_return_if_fail(value != NULL);
+
+ GList *values = NULL;
+
+ g_hash_table_remove(entity->priv->params, key);
+ values = g_list_append(values, g_strdup(value));
+ g_hash_table_insert(entity->priv->params, g_strdup(key), values);
+}
+
+
+/**
* osinfo_entity_add_param:
* @entity: OsinfoEntity containing the parameters
* @key: the name of the key
diff --git a/osinfo/osinfo_entity.h b/osinfo/osinfo_entity.h
index 8dd1bcf..4d442e7 100644
--- a/osinfo/osinfo_entity.h
+++ b/osinfo/osinfo_entity.h
@@ -69,6 +69,7 @@ const gchar *osinfo_entity_get_id(OsinfoEntity *entity);
GList *osinfo_entity_get_param_keys(OsinfoEntity *entity);
const gchar *osinfo_entity_get_param_value(OsinfoEntity *entity, const gchar *key);
GList *osinfo_entity_get_param_value_list(OsinfoEntity *entity, const gchar *key);
+void osinfo_entity_set_param(OsinfoEntity *entity, const gchar *key, const gchar *value);
void osinfo_entity_add_param(OsinfoEntity *entity, const gchar *key, const gchar *value);
void osinfo_entity_clear_param(OsinfoEntity *entity, const gchar *key);
diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c
index 5e36ca4..e17dd31 100644
--- a/osinfo/osinfo_loader.c
+++ b/osinfo/osinfo_loader.c
@@ -180,6 +180,8 @@ static void osinfo_loader_entity(OsinfoLoader *loader,
GError **err)
{
int i = 0;
+
+ /* Standard well-known keys first, allow single value only */
for (i = 0 ; keys[i] != NULL ; i++) {
gchar *xpath = g_strdup_printf("string(./%s)", keys[i]);
gchar *value = osinfo_loader_string(xpath, ctxt, err);
@@ -188,10 +190,33 @@ static void osinfo_loader_entity(OsinfoLoader *loader,
return;
if (value) {
- osinfo_entity_add_param(entity, keys[i], value);
+ osinfo_entity_set_param(entity, keys[i], value);
g_free(value);
}
}
+
+ /* Then any site specific custom keys. x-... Can be repeated */
+ xmlNodePtr *custom = NULL;
+ int ncustom = osinfo_loader_nodeset("./*[substring(name(),1,2)='x-']", ctxt, &custom, err);
+ if (*err)
+ return;
+
+ for (i = 0 ; i < ncustom ; i++) {
+ xmlNodePtr param = custom[i];
+
+ if (!param->children ||
+ param->children->type != XML_TEXT_NODE) {
+ OSINFO_ERROR(err, "Expected a text node attribute value");
+ goto cleanup;
+ }
+
+ osinfo_entity_add_param(entity,
+ (const char *)custom[i]->name,
+ (const char *)custom[i]->children->content);
+ }
+
+ cleanup:
+ g_free(custom);
}
@@ -299,7 +324,8 @@ static void osinfo_loader_device_link(OsinfoLoader *loader,
ctxt->node = related[i];
osinfo_loader_entity(loader, OSINFO_ENTITY(link), keys, ctxt, root, err);
ctxt->node = saved;
-
+ if (*err)
+ goto cleanup;
}
cleanup:
@@ -597,11 +623,14 @@ catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
if (ctxt && ctxt->_private) {
- gchar *xmlmsg = g_strdup_printf("at line %d: %s",
- ctxt->lastError.line,
- ctxt->lastError.message);
- OSINFO_ERROR(ctxt->_private, xmlmsg);
- g_free(xmlmsg);
+ GError **err = ctxt->_private;
+ if (*err == NULL) {
+ gchar *xmlmsg = g_strdup_printf("at line %d: %s",
+ ctxt->lastError.line,
+ ctxt->lastError.message);
+ OSINFO_ERROR(ctxt->_private, xmlmsg);
+ g_free(xmlmsg);
+ }
}
}
@@ -697,7 +726,8 @@ osinfo_loader_process_file_dir(OsinfoLoader *loader,
const gchar *name = g_file_info_get_name(child);
GFile *ent = g_file_get_child(file, name);
- osinfo_loader_process_file(loader, ent, err);
+ if (strstr(name, ".xml") != NULL)
+ osinfo_loader_process_file(loader, ent, err);
g_object_unref(ent);
g_object_unref(child);