[libvirt] [libvirt-glib 1/4] Refactor gvir_config_object_delete_child

Christophe Fergeau cfergeau at redhat.com
Wed Jan 18 15:50:41 UTC 2012


By changing gvir_config_xml_foreach_child to make it robust against
current node deletion in the "foreach" callback, we can use
gvir_config_object_foreach_child to implement
gvir_config_object_delete_child
---
 libvirt-gconfig/libvirt-gconfig-helpers.c |    5 +++-
 libvirt-gconfig/libvirt-gconfig-object.c  |   32 ++++++++++++++++++----------
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c
index cc2e5cc..c406a49 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers.c
+++ b/libvirt-gconfig/libvirt-gconfig-helpers.c
@@ -169,14 +169,17 @@ void gvir_config_xml_foreach_child(xmlNodePtr node,
 
     g_return_if_fail(iter_func != NULL);
 
-    for (it = node->children; it != NULL; it = it->next) {
+    it = node->children;
+    while (it != NULL) {
         gboolean cont;
+        xmlNodePtr next = it->next;
 
         if (xmlIsBlankNode(it))
             continue;
         cont = iter_func(it, opaque);
         if (!cont)
             break;
+        it = next;
     }
 }
 
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index 5645490..7fb8b69 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -465,27 +465,35 @@ gvir_config_object_replace_child_with_attribute(GVirConfigObject *object,
     g_object_unref(G_OBJECT(child));
 }
 
+static gboolean maybe_unlink_node(xmlNodePtr node, const char *name)
+{
+    if (g_strcmp0((char *)node->name, name) == 0) {
+        xmlUnlinkNode(node);
+        xmlFreeNode(node);
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static gboolean remove_oneshot(xmlNodePtr node, gpointer opaque)
+{
+    return !maybe_unlink_node(node, opaque);
+}
+
 G_GNUC_INTERNAL void
 gvir_config_object_delete_child(GVirConfigObject *object,
                                 const char *child_name)
 {
-    xmlNodePtr parent_node;
-    xmlNodePtr old_node;
-
     g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object));
     g_return_if_fail(child_name != NULL);
 
-    parent_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(object));
-    g_return_if_fail(parent_node != NULL);
+    gvir_config_object_foreach_child(object, NULL, remove_oneshot,
+                                     (gpointer)child_name);
+}
 
-    if (!(old_node = gvir_config_xml_get_element(parent_node, child_name, NULL)))
-        return;
 
-    /* FIXME: should we make sure there are no multiple occurrences
-     * of this node?
-     */
-    xmlUnlinkNode(old_node);
-    xmlFreeNode(old_node);
 }
 
 
-- 
1.7.7.5




More information about the libvir-list mailing list