When iterating over xmlNodePtr children to parse an XML document
describing a libvirt configuration item, we want to ignore blank
nodes that may have been added to make the initial XML document
"more human readable". Since this will be useful in several places,
move this code to a helper function.
---
libvirt-gconfig/libvirt-gconfig-domain.c | 28 +++++++++++---------
libvirt-gconfig/libvirt-gconfig-helpers-private.h | 4 +++
libvirt-gconfig/libvirt-gconfig-helpers.c | 18 +++++++++++++
libvirt-gconfig/libvirt-gconfig-object-private.h | 4 +++
libvirt-gconfig/libvirt-gconfig-object.c | 21 +++++++++++++++
5 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c
b/libvirt-gconfig/libvirt-gconfig-domain.c
index ed48d57..0d4cd8c 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -222,6 +222,18 @@ void gvir_config_domain_set_vcpus(GVirConfigDomain *domain, guint64
vcpu_count)
g_object_notify(G_OBJECT(domain), "vcpu");
}
+static gboolean add_one_feature(xmlNodePtr node, gpointer opaque)
+{
+ GPtrArray *features;
+ g_return_val_if_fail(opaque != NULL, FALSE);
+
+ features = (GPtrArray *)opaque;
+
+ g_ptr_array_add(features, g_strdup((char *)node->name));
+
+ return TRUE;
+}
+
/**
* gvir_config_domain_get_features:
* Returns: (transfer full):
@@ -229,22 +241,12 @@ void gvir_config_domain_set_vcpus(GVirConfigDomain *domain, guint64
vcpu_count)
GStrv gvir_config_domain_get_features(GVirConfigDomain *domain)
{
GPtrArray *features;
- xmlNodePtr parent_node;
- xmlNodePtr node;
- xmlNodePtr it;
- parent_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(domain));
- if (parent_node == NULL)
- return NULL;
-
- node = gvir_config_xml_get_element(parent_node, "features", NULL);
- if (node == NULL)
- return NULL;
+ g_return_val_if_fail(GVIR_IS_CONFIG_DOMAIN(domain), NULL);
features = g_ptr_array_new();
- for (it = node->children; it != NULL; it = it->next) {
- g_ptr_array_add(features, g_strdup((char *)it->name));
- }
+ gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "features",
+ add_one_feature, features);
g_ptr_array_add(features, NULL);
return (GStrv)g_ptr_array_free(features, FALSE);
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers-private.h
b/libvirt-gconfig/libvirt-gconfig-helpers-private.h
index de18f50..6067c76 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-helpers-private.h
@@ -45,6 +45,10 @@ void gvir_config_set_error_valist(GError **err,
xmlNodePtr gvir_config_xml_parse(const char *xml,
const char *root_node,
GError **err);
+typedef gboolean (*GVirConfigXmlNodeIterator)(xmlNodePtr node, gpointer opaque);
+void gvir_config_xml_foreach_child(xmlNodePtr node,
+ GVirConfigXmlNodeIterator it_func,
+ gpointer opaque);
xmlNode * gvir_config_xml_get_element (xmlNode *node, ...);
xmlChar * gvir_config_xml_get_child_element_content (xmlNode *node,
const char *child_name);
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c
b/libvirt-gconfig/libvirt-gconfig-helpers.c
index a8001ae..ebaf501 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers.c
+++ b/libvirt-gconfig/libvirt-gconfig-helpers.c
@@ -161,6 +161,24 @@ gvir_config_xml_parse(const char *xml, const char *root_node, GError
**err)
return doc->children;
}
+void gvir_config_xml_foreach_child(xmlNodePtr node,
+ GVirConfigXmlNodeIterator it_func,
+ gpointer opaque)
+{
+ xmlNodePtr it;
+
+ g_return_if_fail(it_func != NULL);
+
+ for (it = node->children; it != NULL; it = it->next) {
+ gboolean cont;
+
+ if (xmlIsBlankNode(it))
+ continue;
+ cont = it_func(it, opaque);
+ if (!cont)
+ break;
+ }
+}
/*
* gvir_config_xml_get_element, gvir_config_xml_get_child_element_content
diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h
b/libvirt-gconfig/libvirt-gconfig-object-private.h
index 38c129f..7c6575e 100644
--- a/libvirt-gconfig/libvirt-gconfig-object-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-object-private.h
@@ -66,6 +66,10 @@ void gvir_config_object_set_attribute_with_type(GVirConfigObject
*object,
...) G_GNUC_NULL_TERMINATED;
void gvir_config_object_remove_attribute(GVirConfigObject *object,
const char *attr_name);
+void gvir_config_object_foreach_child(GVirConfigObject *object,
+ const char *parent_name,
+ GVirConfigXmlNodeIterator it_func,
+ gpointer opaque);
G_END_DECLS
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c
b/libvirt-gconfig/libvirt-gconfig-object.c
index 7a6d062..5c7639f 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -336,6 +336,27 @@ gvir_config_object_set_child(GVirConfigObject *object, xmlNodePtr
child)
gvir_config_object_set_child_internal(object, child, TRUE);
}
+G_GNUC_INTERNAL void
+gvir_config_object_foreach_child(GVirConfigObject *object,
+ const char *parent_name,
+ GVirConfigXmlNodeIterator it_func,
+ gpointer opaque)
+{
+ xmlNodePtr root_node;
+ xmlNodePtr node;
+
+ g_return_if_fail(GVIR_IS_CONFIG_OBJECT(object));
+
+ root_node = gvir_config_object_get_xml_node(object);
+ g_return_if_fail(root_node != NULL);
+
+ node = gvir_config_xml_get_element(root_node, parent_name, NULL);
+ if (node == NULL)
+ return;
+
+ gvir_config_xml_foreach_child(node, it_func, opaque);
+}
+
G_GNUC_INTERNAL GVirConfigObject *
gvir_config_object_add_child(GVirConfigObject *object,
const char *child_name)
--
1.7.7.5