From a816dd7fdf727819dac895f6e97b9a440f86cb91 Mon Sep 17 00:00:00 2001 From: Koos Vriezen Date: Fri, 25 Apr 2008 20:31:12 +0200 Subject: [PATCH] Fix the memory management with set attribute With exception of the initial attribute setting, we must duplicate the attribute value. Implement the missing undo table cleanup --- src/laugh-dom.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/laugh-dom.c b/src/laugh-dom.c index 1676391..ae93dd3 100644 --- a/src/laugh-dom.c +++ b/src/laugh-dom.c @@ -85,13 +85,23 @@ static void laugh_node_finalize (GObject *object) G_OBJECT_CLASS (laugh_node_parent_class)->finalize (object); } -static void _laugh_hash_key_free (gpointer key, gpointer value, gpointer data) +static void _laugh_node_attr_free (gpointer key, gpointer value, gpointer data) { (void) key; (void) data; g_free (value); } +static void _laugh_node_undo_free (gpointer key, gpointer value, gpointer data) +{ + GSList *list; + (void) key; (void) data; + + for (list = (GSList *) value; list; list = list->next) + g_free (list->data); + g_slist_free (list); +} + static void laugh_node_dispose (GObject *object) { LaughNode *node = LAUGH_NODE(object); @@ -99,13 +109,14 @@ static void laugh_node_dispose (GObject *object) LaughNode *child; if (node->attributes) { - g_hash_table_foreach (node->attributes, _laugh_hash_key_free, NULL); + g_hash_table_foreach (node->attributes, _laugh_node_attr_free, NULL); g_hash_table_destroy (node->attributes); } - if (priv->attribute_undo) - /*TODO empty hash table first*/ + if (priv->attribute_undo) { + g_hash_table_foreach (priv->attribute_undo, _laugh_node_undo_free,NULL); g_hash_table_destroy (priv->attribute_undo); + } for (child = node->first_child; child; ) { LaughNode *tmp = child->next_sibling; @@ -126,6 +137,7 @@ void laugh_node_base_set_attribute (LaughNode *node, if (node->state > LaughStateInit) { LaughNodePrivate *priv = node->priv; gchar *cur = NULL; + gchar *new_cur = NULL; if (node->attributes) cur = g_hash_table_lookup (node->attributes, (gpointer)(long) attr); @@ -135,17 +147,19 @@ void laugh_node_base_set_attribute (LaughNode *node, if (cur == val) return; - if (val) + if (val) { + new_cur = g_strdup (val); g_hash_table_replace (node->attributes, - (gpointer) (long) attr, (gpointer) val); - else + (gpointer) (long) attr, new_cur); + } else { g_hash_table_remove (node->attributes, (gpointer) (long) attr); + } if (undo) { if (val) { /*set*/ - *(const gchar **)undo = val; - g_printf ("set undo to %s\n", val); + *(const gchar **)undo = new_cur; + g_printf ("set undo to %s\n", new_cur); if (cur) { GSList *ol = NULL; @@ -169,12 +183,13 @@ void laugh_node_base_set_attribute (LaughNode *node, if (ol) { if (undo_val == cur) { - cur = ol->data; + new_cur = ol->data; g_hash_table_replace (node->attributes, - (gpointer) (long) attr, cur); + (gpointer) (long) attr, new_cur); ol = ol->next; } else { ol = g_slist_remove (ol, undo_val); + g_free (undo_val); } if (!ol) @@ -184,11 +199,13 @@ void laugh_node_base_set_attribute (LaughNode *node, g_hash_table_replace (priv->attribute_undo, (gpointer) (long) attr, ol); } - } else { - cur = NULL; } - g_printf ("set undo to %s\n", cur ? cur : "-"); - *(gchar **)undo = cur; + + if (cur) + g_free (cur); + + g_printf ("set undo to %s\n", new_cur ? new_cur : "-"); + *(gchar **)undo = new_cur; } } else if (cur) { g_free (cur); -- 2.11.4.GIT