[anjuta] debugger: bgo #516112 - Debugger create too much variable objects



commit 0f128b9c7e9a3702f7c861ed15a8be621e360430
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Thu Jul 15 21:59:37 2010 +0200

    debugger: bgo #516112  - Debugger create too much variable objects

 plugins/debug-manager/debug_tree.c |  447 ++++++++++++++++++++----------------
 plugins/debug-manager/debug_tree.h |    5 +-
 plugins/debug-manager/locals.c     |   45 ++++-
 plugins/debug-manager/watch.c      |   10 +-
 plugins/gdb/debugger.c             |    4 +-
 5 files changed, 291 insertions(+), 220 deletions(-)
---
diff --git a/plugins/debug-manager/debug_tree.c b/plugins/debug-manager/debug_tree.c
index ed196df..a09438e 100644
--- a/plugins/debug-manager/debug_tree.c
+++ b/plugins/debug-manager/debug_tree.c
@@ -62,7 +62,7 @@ enum _DataType
 
 typedef enum _DataType DataType;
 
-enum {AUTO_UPDATE_WATCH = 1 << 0};	
+enum {AUTO_UPDATE_WATCH = 1 << 0};
 
 /* Common data */
 typedef struct _CommonDebugTree CommonDebugTree;
@@ -88,14 +88,15 @@ struct _DmaVariablePacket {
 	DmaVariableData *data;
 	GtkTreeModel *model;
 	GtkTreeRowReference* reference;
-	DebugTree *tree;
+	DmaDebuggerQueue *debugger;
 	DmaVariablePacket* next;
 };
 
 struct _DmaVariableData {
-	guchar modified;    /* Set by tree update */
-	guchar changed;     /* Set by global update */
-
+	gboolean modified;	/* Set by tree update */
+	
+	/* Value from debugger */
+	gboolean changed;	/* Set by global update */
 	gboolean exited;	/* variable outside scope */
 	gboolean deleted;	/* variable should be deleted */
 	
@@ -170,7 +171,6 @@ dma_variable_data_new(const gchar *const name, gboolean auto_update)
 		data->name = g_strdup (name);
 	}
 
-	data->changed = TRUE;
 	data->auto_update = auto_update;
 		
 	return data;
@@ -201,7 +201,7 @@ dma_variable_data_free(DmaVariableData * data)
 static DmaVariablePacket *
 dma_variable_packet_new(GtkTreeModel *model,
                      GtkTreeIter *iter,
-					 DebugTree *tree,					 
+					 DmaDebuggerQueue *debugger,
 					 DmaVariableData *data)
 {
 	GtkTreePath *path;
@@ -216,7 +216,7 @@ dma_variable_packet_new(GtkTreeModel *model,
 	path = gtk_tree_model_get_path(model, iter); 
 	pack->reference = gtk_tree_row_reference_new (model, path);
 	gtk_tree_path_free (path);
-	pack->tree = tree;
+	pack->debugger = debugger;
 	pack->next = data->packet;
 	data->packet = pack;
 
@@ -295,18 +295,18 @@ delete_child(GtkTreeModel *model, GtkTreePath* path,
 			GtkTreeIter* iter, gpointer user_data)
 {
 	DmaVariableData *data;
-	DebugTree* tree = (DebugTree *)user_data;
+	DmaDebuggerQueue *debugger = (DmaDebuggerQueue *)user_data;
 
 	g_return_val_if_fail (model,TRUE);
 	g_return_val_if_fail (iter,TRUE);
 
 	gtk_tree_model_get(model, iter, DTREE_ENTRY_COLUMN, &data, -1);	
 	
-	/* Dummy node (data == NULL) are used when child are not known */				
+	/* Dummy node (data == NULL) are used when child are not known */
 	if (data != NULL)
 	{
 		dma_variable_data_free(data);
-	  	my_gtk_tree_model_foreach_child (model, iter, delete_child, tree);
+	  	my_gtk_tree_model_foreach_child (model, iter, delete_child, debugger);
 	}
 	
 	return FALSE;
@@ -317,56 +317,37 @@ delete_parent(GtkTreeModel *model, GtkTreePath* path,
 			GtkTreeIter* iter, gpointer user_data)
 {
 	DmaVariableData *data;
-	DebugTree* tree = (DebugTree *)user_data;
+	DmaDebuggerQueue *debugger = (DmaDebuggerQueue *)user_data;
 
 	g_return_val_if_fail (model,TRUE);
 	g_return_val_if_fail (iter,TRUE);
 
-	gtk_tree_model_get(model, iter, DTREE_ENTRY_COLUMN, &data, -1);	
+	gtk_tree_model_get(model, iter, DTREE_ENTRY_COLUMN, &data, -1);
 
-	/* Dummy node (data == NULL) are used as a place holder in watch box */				
+	/* Dummy node (data == NULL) are used as a place holder in watch box */
 	if (data != NULL)
 	{
-		if (tree->debugger)
+		if (debugger)
 		{
 			if (data->name)
 			{
 				/* Object has been created in debugger and is not a child
 			 	* (destroyed with their parent) */
-				dma_queue_delete_variable (tree->debugger, data->name);
+				dma_queue_delete_variable (debugger, data->name);
 			}
 		}				
 
 		dma_variable_data_free(data);
 				
-  		my_gtk_tree_model_foreach_child (model, iter, delete_child, tree);
+  		my_gtk_tree_model_foreach_child (model, iter, delete_child, debugger);
 	}
 	
 	return FALSE;
 }
 
-
-static gboolean
-set_deleted(GtkTreeModel *model, GtkTreePath* path,
-				 GtkTreeIter* iter, gpointer user_data)
-{
-	DmaVariableData *data;
-
-	g_return_val_if_fail (model,TRUE);
-	g_return_val_if_fail (iter,TRUE);
-	
-	gtk_tree_model_get(model, iter, DTREE_ENTRY_COLUMN, &data, -1);
-	g_return_val_if_fail (data, TRUE);	/* Use on root node only, data != NULL */
-
-	data->deleted= TRUE;
-
-	return FALSE;	
-}
-
 static void
-debug_tree_remove_children (DebugTree *tree, GtkTreeIter* parent, GtkTreeIter* first)
+debug_tree_remove_children (GtkTreeModel *model, DmaDebuggerQueue *debugger, GtkTreeIter* parent, GtkTreeIter* first)
 {
-	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->view));
 	gboolean child;
  	GtkTreeIter iter;
 	
@@ -384,14 +365,28 @@ debug_tree_remove_children (DebugTree *tree, GtkTreeIter* parent, GtkTreeIter* f
 
 	while (child)
 	{
-		delete_child (model, NULL, &iter, tree);
+		delete_child (model, NULL, &iter, debugger);
 		
 		child = gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
 	}
 }
 
 static void
-debug_tree_add_children (DebugTree *tree, GtkTreeIter* parent, const GList *children)
+debug_tree_model_add_dummy (GtkTreeModel *model, GtkTreeIter *parent)
+{
+	GtkTreeIter iter;
+
+	gtk_tree_store_append(GTK_TREE_STORE(model), &iter, parent);
+	gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
+					   VARIABLE_COLUMN, "",
+					   VALUE_COLUMN, "",
+					   TYPE_COLUMN, "",
+					   ROOT_COLUMN, parent == NULL ? TRUE : FALSE,
+					   DTREE_ENTRY_COLUMN, NULL, -1);
+}
+
+static void
+debug_tree_add_children (GtkTreeModel *model, DmaDebuggerQueue *debugger, GtkTreeIter* parent, const GList *children)
 {
 	GList *child;
 	
@@ -400,11 +395,10 @@ debug_tree_add_children (DebugTree *tree, GtkTreeIter* parent, const GList *chil
 	if (child == NULL)
 	{
 		/* Clear all children if they exist */
-		debug_tree_remove_children (tree, parent, NULL);
+		debug_tree_remove_children (model, debugger, parent, NULL);
 	}
 	else
 	{
-		GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->view));
 		GtkTreeIter iter;
 		gboolean valid_iter;
 		
@@ -442,23 +436,19 @@ debug_tree_add_children (DebugTree *tree, GtkTreeIter* parent, const GList *chil
 			if (data == NULL)
 			{
 				/* Create new data */
-				data = dma_variable_data_new(var->name, FALSE);
+				data = dma_variable_data_new(var->name, TRUE);
 				gtk_tree_store_set(GTK_TREE_STORE(model), &iter, DTREE_ENTRY_COLUMN, data, -1);				
 			}
-			else
-			{
-				data->changed = TRUE;
-			}
 		
 			if (var->children == 0)
 			{
 				/* Clear all children if they exist */
-				debug_tree_remove_children (tree, &iter, NULL);
+				debug_tree_remove_children (model, debugger, &iter, NULL);
 			}
 			else
 			{
 				/* Add dummy children */
-				debug_tree_add_dummy (tree, &iter);
+				debug_tree_model_add_dummy (model, &iter);
 			}
 			
 			valid_iter = gtk_tree_model_iter_next (model, &iter); 
@@ -466,34 +456,11 @@ debug_tree_add_children (DebugTree *tree, GtkTreeIter* parent, const GList *chil
 		if (valid_iter)
 		{
 			/* Remove trailing children */
-			debug_tree_remove_children (tree, parent, &iter);
+			debug_tree_remove_children (model, debugger, parent, &iter);
 		}
 	}	
 }
 
-static void
-destroy_deleted (DebugTree *tree, GtkTreeModel* model)
-{
-	DmaVariableData *data;
-	GtkTreeIter iter;
-	gboolean success;
-	
-	g_return_if_fail (model);
-
-	for (success = gtk_tree_model_get_iter_first (model, &iter); success == TRUE; )
-	{
-		gtk_tree_model_get(model, &iter, DTREE_ENTRY_COLUMN, &data, -1);
-		if ((data != NULL) && (data->deleted == TRUE))
-		{
-			success = debug_tree_remove (tree, &iter);
-		}
-		else
-		{
-			success = gtk_tree_model_iter_next (model, &iter);
-		}
-	};
-}
-
 /*---------------------------------------------------------------------------*/
 
 static void
@@ -538,7 +505,7 @@ gdb_var_list_children (const GList *children, gpointer user_data, GError *err)
 		return;
 	}
 
-	debug_tree_add_children (pack->tree, &iter, children);
+	debug_tree_add_children (pack->model, pack->debugger, &iter, children);
 		  
 	dma_variable_packet_free (pack);
 }
@@ -563,9 +530,9 @@ gdb_var_create (IAnjutaDebuggerVariableObject *variable, gpointer user_data, GEr
 	{
 		/* Item has been deleted, but not removed from debugger as it was not
 		 * created at this time, so remove it now */
-		if ((pack->tree->debugger) && (variable->name))
+		if ((pack->debugger) && (variable->name))
 		{
-			dma_queue_delete_variable (pack->tree->debugger, variable->name);
+			dma_queue_delete_variable (pack->debugger, variable->name);
 		}
 		dma_variable_packet_free (pack);
 		
@@ -578,7 +545,9 @@ gdb_var_create (IAnjutaDebuggerVariableObject *variable, gpointer user_data, GEr
 	{
 		data->name = strdup (variable->name);
 	}
-    data->changed = TRUE;
+	data->changed = TRUE;
+	data->deleted = FALSE;
+	data->exited = FALSE;
 	
 	gtk_tree_store_set(GTK_TREE_STORE(pack->model), &iter,
 					   TYPE_COLUMN, variable->type,
@@ -589,21 +558,21 @@ gdb_var_create (IAnjutaDebuggerVariableObject *variable, gpointer user_data, GEr
 	{
 		/* Find the number of children */
 		DmaVariablePacket *pack_child =
-                  dma_variable_packet_new(pack->model, &iter, pack->tree, data);
+                  dma_variable_packet_new(pack->model, &iter, pack->debugger, data);
 
 		dma_queue_list_children (
-				pack_child->tree->debugger,
+				pack_child->debugger,
 				variable->name,
 				(IAnjutaDebuggerCallback)gdb_var_list_children,
 				pack_child);
 	}
 	else if (variable->children > 0)
 	{
-		debug_tree_add_dummy (pack->tree, &iter);
+		debug_tree_model_add_dummy (pack->model, &iter);
 	}
 	else
 	{
-		debug_tree_remove_children (pack->tree, &iter, NULL);
+		debug_tree_remove_children (pack->model, pack->debugger, &iter, NULL);
 	}
 	
 	
@@ -612,7 +581,7 @@ gdb_var_create (IAnjutaDebuggerVariableObject *variable, gpointer user_data, GEr
 	if (variable->value == NULL)
 	{
 		dma_queue_evaluate_variable (
-				pack->tree->debugger,
+				pack->debugger,
 				variable->name,
 				(IAnjutaDebuggerCallback)gdb_var_evaluate_expression,
 				pack);
@@ -641,7 +610,7 @@ on_treeview_row_expanded       (GtkTreeView     *treeview,
 	{
 		DmaVariablePacket *pack;
 					
-		pack = dma_variable_packet_new(model, iter, tree, data);
+		pack = dma_variable_packet_new(model, iter, tree->debugger, data);
 		dma_queue_list_children (
 						tree->debugger,
 						data->name,
@@ -699,7 +668,7 @@ on_debug_tree_value_changed (GtkCellRendererText *cell,
 		{
 			/* Variable is valid */
 			dma_queue_assign_variable (tree->debugger, item->name, text);
-			tran = dma_variable_packet_new(model, &iter, tree, item);
+			tran = dma_variable_packet_new(model, &iter, tree->debugger, item);
 			dma_queue_evaluate_variable (
 					tree->debugger,
 					item->name,
@@ -727,8 +696,8 @@ debug_tree_create (DebugTree *tree, GtkTreeView *view)
 		view = GTK_TREE_VIEW (gtk_tree_view_new ());
 	}
 	
-    gtk_tree_view_set_model (view, GTK_TREE_MODEL (model));
-  
+	gtk_tree_view_set_model (view, GTK_TREE_MODEL (model));
+
 	GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
 	g_object_unref (G_OBJECT (model));
@@ -851,85 +820,63 @@ debug_tree_find_name (const GtkTreeModel *model, GtkTreeIter *iter, const gchar
 	}
 }
 
-static gboolean
-debug_tree_find_expression (const GtkTreeModel *model, GtkTreeIter *iter, const gchar *expression, const gchar *type)
+void
+debug_tree_replace_list (DebugTree *tree, const GList *expressions)
 {
-	gboolean search;
-	
-	for (search = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), iter);
-		search;
-	    search = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), iter))
+	GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW(tree->view));
+	GtkTreeIter iter;
+	gboolean valid;
+	GList *list = g_list_copy ((GList *)expressions);
+
+	/* Keep in the tree only the variable in the list */
+	valid = gtk_tree_model_get_iter_first (model, &iter);
+	while (valid)
 	{
+		GList *find = NULL;
 		gchar *exp;
-		gchar *typ;
 		DmaVariableData *node;
-		gboolean found;
 		
-        gtk_tree_model_get (GTK_TREE_MODEL (model), iter, TYPE_COLUMN, &typ,
+		gtk_tree_model_get (model, &iter,
 							VARIABLE_COLUMN, &exp,
 							DTREE_ENTRY_COLUMN, &node, -1);
 
-		found = ((type == NULL) || (strcmp (typ, type) == 0))
-			&& ((expression == NULL) || (strcmp (exp, expression) == 0))
-			&& (node->exited == FALSE);
-		if (typ != NULL) g_free (typ);
-		if (exp != NULL) g_free (exp);
+		if ((node->deleted == FALSE) && (node->exited == FALSE) && (exp != NULL))
+		{
+			find = g_list_find_custom (list, exp, (GCompareFunc)strcmp);
+		}
 		
-		if (found) return TRUE;
+		if (find)
+		{
+			/* Keep variable in tree, remove in add list */
+			list = g_list_delete_link (list, find);
+			valid = gtk_tree_model_iter_next (model, &iter);
+		}
+		else
+		{
+			/* Remove variable from the tree */
+			delete_parent(model, NULL, &iter, tree->debugger);
+			valid = gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+		}
 	}
 	
-	return FALSE;
-}
-
-static void
-on_replace_watch (gpointer data, gpointer user_data)
-{
-	DebugTree* tree = (DebugTree *)user_data;
-	const gchar *expression = (const gchar *)data;
-	GtkTreeModel*const model = gtk_tree_view_get_model (GTK_TREE_VIEW(tree->view));
-	IAnjutaDebuggerVariableObject var = {NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, -1};
-	GtkTreeIter iter;
-
-	if (debug_tree_find_expression (model, &iter, expression, NULL))
-	{
-		DmaVariableData *data;
-
-        	gtk_tree_model_get (model, &iter, DTREE_ENTRY_COLUMN, &data, -1);
-		if (data != NULL) data->deleted = FALSE;
-	}
-	else
+	/* Create new variable */
+	while (list)
 	{
-		var.expression = (gchar *)expression;
+		IAnjutaDebuggerVariableObject var = {NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, -1};
+		
+		var.expression = (gchar *)(list->data);
 		debug_tree_add_watch (tree, &var, TRUE);
+		
+		list = g_list_delete_link (list, list);
 	}
 }
 
 void
-debug_tree_replace_list (DebugTree *tree, const GList *expressions)
-{
-	GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW(tree->view));
-	
-	/* Mark variables as deleted */
-	my_gtk_tree_model_foreach_child(model, NULL, set_deleted, NULL);	
-
-	g_list_foreach ((GList *)expressions, on_replace_watch, tree);	
-
-	destroy_deleted (tree, model);	
-}
-
-void
 debug_tree_add_dummy (DebugTree *tree, GtkTreeIter *parent)
 {
-	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->view));
-	GtkTreeIter iter;
+	GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW(tree->view));
 
-	gtk_tree_store_append(GTK_TREE_STORE(model), &iter, parent);
-	gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
-					   VARIABLE_COLUMN, "",
-					   VALUE_COLUMN, "",
-					   TYPE_COLUMN, "",
-					   ROOT_COLUMN, parent == NULL ? TRUE : FALSE,
-					   DTREE_ENTRY_COLUMN, NULL, -1);
+	debug_tree_model_add_dummy (model, parent);
 }
 
 /* Get a IAnjutaVariable as argument in order to use the same function without
@@ -963,7 +910,7 @@ debug_tree_add_watch (DebugTree *tree, const IAnjutaDebuggerVariableObject* var,
 				/* Need to create variable before to get value */
 				DmaVariablePacket *pack;
 		
-				pack = dma_variable_packet_new(model, &iter, tree, data);
+				pack = dma_variable_packet_new(model, &iter, tree->debugger, data);
 				dma_queue_create_variable (
 						tree->debugger,
 						var->expression,
@@ -978,7 +925,7 @@ debug_tree_add_watch (DebugTree *tree, const IAnjutaDebuggerVariableObject* var,
 					/* Get value */
 					DmaVariablePacket *pack =
 					
-					pack = dma_variable_packet_new(model, &iter, tree, data);
+					pack = dma_variable_packet_new(model, &iter, tree->debugger, data);
 					dma_queue_evaluate_variable (
 							tree->debugger,
 							var->name,
@@ -990,7 +937,7 @@ debug_tree_add_watch (DebugTree *tree, const IAnjutaDebuggerVariableObject* var,
 					/* Get number of children */
 					DmaVariablePacket *pack =
 					
-					pack = dma_variable_packet_new(model, &iter, tree, data);
+					pack = dma_variable_packet_new(model, &iter, tree->debugger, data);
 					dma_queue_list_children (
 							tree->debugger,
 							var->name,
@@ -1066,7 +1013,7 @@ on_debug_tree_changed (gpointer data, gpointer user_data)
 			{
 				DmaVariableData *data;
 				gtk_tree_model_get (model, &iter, DTREE_ENTRY_COLUMN, &data, -1);
-		
+
 				if (data != NULL)
 				{	
 					data->changed = var->changed;
@@ -1081,30 +1028,9 @@ on_debug_tree_changed (gpointer data, gpointer user_data)
 }
 
 static gboolean
-on_debug_tree_modified (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
+debug_tree_update_real (GtkTreeModel *model, DmaDebuggerQueue *debugger, GtkTreeIter* iter, gboolean force)
 {
 	DmaVariableData *data = NULL;
-	
-	gtk_tree_model_get (model, iter, DTREE_ENTRY_COLUMN, &data, -1);
-	
-	if (data != NULL)	/* Avoid dummy node */
-	{
-		if (data->modified != data->changed)
-		{
-			data->modified = data->changed;
-			gtk_tree_model_row_changed (model, path, iter);
-		}
-		data->changed = FALSE;
-	}
-
-	return FALSE;
-}
-
-static gboolean
-debug_tree_update_real (DebugTree* tree, GtkTreeIter* iter, gboolean force)
-{
-	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->view));
-	DmaVariableData *data = NULL;
 	GtkTreeIter child;
 	gboolean search;
 	gboolean refresh = TRUE;
@@ -1112,6 +1038,15 @@ debug_tree_update_real (DebugTree* tree, GtkTreeIter* iter, gboolean force)
 	gtk_tree_model_get (model, iter, DTREE_ENTRY_COLUMN, &data, -1);
 	if (data == NULL) return FALSE;
 
+	
+	if ((data->deleted) && (data->name != NULL) && (force || data->auto_update))
+	{
+		/* Variable deleted (by example if type change), try to recreate it */
+		dma_queue_delete_variable (debugger, data->name);
+		g_free (data->name);
+		data->name = NULL;
+	}
+	
 	if (data->name == NULL)
 	{
 		/* Check is the variable creation is not pending */
@@ -1122,10 +1057,9 @@ debug_tree_update_real (DebugTree* tree, GtkTreeIter* iter, gboolean force)
 			DmaVariablePacket *pack;
 		
 			gtk_tree_model_get (model, iter, VARIABLE_COLUMN, &exp, -1);
-			pack = dma_variable_packet_new(model, iter, tree, data);
-			data->modified = TRUE;
+			pack = dma_variable_packet_new(model, iter, debugger, data);
 			dma_queue_create_variable (
-					tree->debugger,
+					debugger,
 					exp,
 					(IAnjutaDebuggerCallback)gdb_var_create,
 					pack);
@@ -1136,14 +1070,15 @@ debug_tree_update_real (DebugTree* tree, GtkTreeIter* iter, gboolean force)
 	}	
 	else if (force || (data->auto_update && data->changed))
 	{
-		DmaVariablePacket *pack = dma_variable_packet_new(model, iter, tree, data);
+		DmaVariablePacket *pack = dma_variable_packet_new(model, iter, debugger, data);
 		refresh = data->modified != (data->changed != FALSE);
 		data->modified = (data->changed != FALSE);
 		dma_queue_evaluate_variable (
-				tree->debugger,
+				debugger,
 				data->name,
 				(IAnjutaDebuggerCallback)gdb_var_evaluate_expression,
 				pack);
+		data->changed = FALSE;
 	}
 	else
 	{
@@ -1156,7 +1091,7 @@ debug_tree_update_real (DebugTree* tree, GtkTreeIter* iter, gboolean force)
 		search == TRUE;
 	    search = gtk_tree_model_iter_next (model, &child))
 	{
-		if (debug_tree_update_real (tree, &child, force))
+		if (debug_tree_update_real (model, debugger, &child, force))
 		{
 			refresh = data->modified == TRUE;
 			data->modified = TRUE;
@@ -1174,46 +1109,60 @@ debug_tree_update_real (DebugTree* tree, GtkTreeIter* iter, gboolean force)
 	return data->modified;
 }
 
+
+/* Get information from debugger and update variable with automatic update */
 static void
 on_debug_tree_update_all (const GList *change, gpointer user_data, GError* err)
 {
-	DebugTree *tree = (DebugTree *)user_data;
-	GtkTreeModel *model;
-	GtkTreeIter iter;
+	DmaDebuggerQueue *debugger = (DmaDebuggerQueue *)user_data;
+	GList *list;
 
 	if (err != NULL) return;
 
-	// Mark all modified variables
+	// Update all variables information from debugger data
 	g_list_foreach ((GList *)change, on_debug_tree_changed, NULL);
 
-	// Update this tree
-	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->view));
-	if (gtk_tree_model_get_iter_first (model, &iter) == TRUE)
+	// Update all tree models
+	for (list = g_list_first (gTreeList); list != NULL; list = g_list_next (list))
 	{
-		do
+		GtkTreeModel* model = GTK_TREE_MODEL (list->data);
+		GtkTreeIter iter;
+		gboolean valid;
+
+		// Update this tree
+		for (valid = gtk_tree_model_get_iter_first (model, &iter);
+			valid;
+			valid = gtk_tree_model_iter_next (model, &iter))
 		{
-			DmaVariableData *data = NULL;
-			
-			gtk_tree_model_get (model, &iter, DTREE_ENTRY_COLUMN, &data, -1);
-	
-			debug_tree_update_real (tree, &iter, FALSE);
-		} while (gtk_tree_model_iter_next (model, &iter) == TRUE);
+			debug_tree_update_real (model, debugger, &iter, FALSE);
+		}
 	}
-	
-	// Update modified mark
-	gtk_tree_model_foreach (model, on_debug_tree_modified, NULL);
 }
 
 void
-debug_tree_update_all (DebugTree* tree)
+debug_tree_update_all (DmaDebuggerQueue *debugger)
 {
-	if (tree->debugger != NULL)
+	dma_queue_update_variable (debugger,
+			(IAnjutaDebuggerCallback)on_debug_tree_update_all,
+			debugger);
+}
+
+/* Update all variables in the specified tree */
+void
+debug_tree_update_tree (DebugTree *this)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean valid;
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (this->view));
+
+	// Update this tree
+	for (valid = gtk_tree_model_get_iter_first (model, &iter);
+		valid;
+		valid = gtk_tree_model_iter_next (model, &iter))
 	{
-		/* Update if debugger is connected */
-		dma_queue_update_variable (
-				tree->debugger,
-				(IAnjutaDebuggerCallback)on_debug_tree_update_all,
-				tree);
+		debug_tree_update_real (model, this->debugger, &iter, TRUE);
 	}
 }
 
@@ -1277,7 +1226,7 @@ debug_tree_remove (DebugTree *tree, GtkTreeIter* iter)
 
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->view));
 	
-	delete_parent (model, NULL, iter, tree);
+	delete_parent (model, NULL, iter, tree->debugger);
 	return gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
 }
 
@@ -1286,7 +1235,10 @@ debug_tree_update (DebugTree* tree, GtkTreeIter* iter, gboolean force)
 {
 	if (tree->debugger != NULL)
 	{
-		return debug_tree_update_real (tree, iter, force);
+		GtkTreeModel *model;
+
+		model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree->view));
+		return debug_tree_update_real (model, tree->debugger, iter, force);
 	}
 	else
 	{
@@ -1333,10 +1285,35 @@ debug_tree_connect (DebugTree *this, DmaDebuggerQueue* debugger)
 	this->debugger = debugger;
 }
 
+static gboolean
+on_disconnect_variable (GtkTreeModel *model,
+						GtkTreePath *path,
+						GtkTreeIter *iter,
+						gpointer user_data)
+{
+	DmaVariableData *data;
+									 
+	gtk_tree_model_get (model, iter, DTREE_ENTRY_COLUMN, &data, -1);
+
+	if (data != NULL)
+	{
+		g_free (data->name);
+		data->name = NULL;
+	}
+
+	return FALSE;
+}
+
 void
 debug_tree_disconnect (DebugTree *this)
 {
+	GtkTreeModel *model;
+	
 	this->debugger = NULL;
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (this->view));
+
+	/* Remove all variable name */
+	gtk_tree_model_foreach (model, on_disconnect_variable, NULL);
 }
 
 GtkTreeModel *
@@ -1368,7 +1345,7 @@ debug_tree_new_model (DebugTree *tree)
 void
 debug_tree_remove_model (DebugTree *tree, GtkTreeModel *model)
 {
-	my_gtk_tree_model_foreach_child (model, NULL, delete_parent, tree);
+	my_gtk_tree_model_foreach_child (model, NULL, delete_parent, tree->debugger);
 	gtk_tree_store_clear (GTK_TREE_STORE (model));
 }
 
@@ -1438,6 +1415,70 @@ debug_tree_find_variable_value (DebugTree *tree, const gchar *name)
 	return NULL;
 }
 
+/* Debugging functions
+ *---------------------------------------------------------------------------*/
+
+static void
+debug_tree_dump_iter (GtkTreeModel *model, GtkTreeIter *iter, guint indent)
+{
+	gchar *expression;
+	gchar *value;
+	gchar *type;
+	DmaVariableData *node;
+	GtkTreeIter child;
+	gboolean valid;
+
+	gtk_tree_model_get (model, iter,
+						VARIABLE_COLUMN, &expression,
+						VALUE_COLUMN, &value,
+						TYPE_COLUMN, &type,
+						DTREE_ENTRY_COLUMN, &node,
+						-1);
+	if (node != NULL)
+	{
+		g_message ("%*s %s | %s | %s | %s | %d%d%d%d%d", indent, "",
+					expression, value, type, node->name,
+					node->modified, node->changed, node->exited, node->deleted, node->auto_update);
+	}
+	else
+	{
+		g_message ("%*s %s | %s | %s | %s | %c%c%c%c%c", indent, "",
+					expression, value, type, "???",
+					'?','?','?','?','?');
+	}
+	g_free (expression);
+	g_free (value);
+	g_free (type);
+
+	for (valid = gtk_tree_model_iter_children (model, &child, iter);
+		valid;
+		valid = gtk_tree_model_iter_next (model, &child))
+	{
+		debug_tree_dump_iter (model, &child, indent + 4);
+	}
+}
+
+void
+debug_tree_dump (void)
+{
+	GList *tree;
+	
+	for (tree = g_list_first (gTreeList); tree != NULL; tree = g_list_next (tree))
+	{
+		GtkTreeModel *model = (GtkTreeModel *)tree->data;
+		GtkTreeIter iter;
+		gboolean valid;
+
+		g_message ("Tree model %p   MCEDU", model);
+		for (valid = gtk_tree_model_get_iter_first (model, &iter);
+			valid;
+			valid = gtk_tree_model_iter_next (model, &iter))
+		{
+			debug_tree_dump_iter (model, &iter, 4);
+		}
+	}
+}
+
 /* Constructor & Destructor
  *---------------------------------------------------------------------------*/
 
diff --git a/plugins/debug-manager/debug_tree.h b/plugins/debug-manager/debug_tree.h
index 74b1e08..436fba0 100644
--- a/plugins/debug-manager/debug_tree.h
+++ b/plugins/debug-manager/debug_tree.h
@@ -37,6 +37,8 @@ DebugTree* debug_tree_new (AnjutaPlugin* plugin);
 DebugTree* debug_tree_new_with_view (AnjutaPlugin *plugin, GtkTreeView *view);
 void debug_tree_free (DebugTree *tree);
 
+void debug_tree_dump (void);
+
 void debug_tree_connect (DebugTree *tree, DmaDebuggerQueue *debugger);
 void debug_tree_disconnect (DebugTree *tree);
 
@@ -46,7 +48,8 @@ void debug_tree_add_watch (DebugTree *tree, const IAnjutaDebuggerVariableObject*
 void debug_tree_add_dummy (DebugTree *tree, GtkTreeIter *parent);
 void debug_tree_add_full_watch_list (DebugTree *tree, GList *expressions);
 void debug_tree_add_watch_list (DebugTree *tree, GList *expressions, gboolean auto_update);
-void debug_tree_update_all (DebugTree *tree);
+void debug_tree_update_tree (DebugTree *tree);
+void debug_tree_update_all (DmaDebuggerQueue *debugger);
 
 GList* debug_tree_get_full_watch_list (DebugTree *tree);
 
diff --git a/plugins/debug-manager/locals.c b/plugins/debug-manager/locals.c
index 29f7106..d333eeb 100644
--- a/plugins/debug-manager/locals.c
+++ b/plugins/debug-manager/locals.c
@@ -70,9 +70,7 @@ locals_updated (const gpointer data, gpointer user_data, GError *error)
 	if (g_list_length ((GList*)list) < 1)
 		return;
 
-	debug_tree_update_all(self->debug_tree);
 	debug_tree_replace_list (self->debug_tree, list);
-	debug_tree_update_all(self->debug_tree);
 }
 
 /* Private functions
@@ -187,10 +185,45 @@ dma_thread_add_local (Locals *self, GtkTreeModel *model, gint thread, guint fram
 
 static void locals_update (Locals *self, gint thread)
 {
-	dma_thread_clear_all_locals (self);
-
-	dma_thread_add_local (self, debug_tree_get_model (self->debug_tree), thread, 0);
+	GList *list;
+	DmaThreadLocal *frame;
 	
+	/* Delete all local tree except the main one. It allow to keep the selected
+	 * and the expanded item in the common case. */
+	self->current = NULL;
+	for (list = g_list_first (self->list); list != NULL;)
+	{
+		frame = (DmaThreadLocal *)list->data;
+		
+		if ((frame->thread == thread) && (frame->frame == 0))
+		{
+			self->current = frame;
+			debug_tree_set_model (self->debug_tree, frame->model);
+			list = g_list_next (list);
+		}
+		else
+		{
+			GList *next;
+			
+			debug_tree_remove_model (self->debug_tree, frame->model);
+			g_object_unref (G_OBJECT (frame->model));
+			g_free (frame);
+			next = g_list_next (list);
+			self->list = g_list_delete_link (self->list, list);
+			list = next;
+		}
+	}
+	
+	/* Add new frame if needed */
+	if (self->current == NULL)
+	{
+		dma_thread_add_local (self, debug_tree_get_model (self->debug_tree), thread, 0);
+	}
+	
+	/* Update all variables in all tree, so including watches */
+	debug_tree_update_all (self->debugger);
+	
+	/* List new local variables and display them in local window */
 	dma_queue_list_local (self->debugger, locals_updated, self);
 }
 
@@ -214,6 +247,8 @@ locals_change_frame (Locals *self, guint frame, gint thread)
 	
 	debug_tree_new_model (self->debug_tree);
 	dma_thread_add_local (self, debug_tree_get_model (self->debug_tree), thread, frame);
+	
+	/* List new local variables and display them in local window */
 	dma_queue_list_local (self->debugger, locals_updated, self);
 }
 
diff --git a/plugins/debug-manager/watch.c b/plugins/debug-manager/watch.c
index ac515f1..7453dfc 100644
--- a/plugins/debug-manager/watch.c
+++ b/plugins/debug-manager/watch.c
@@ -200,19 +200,12 @@ debug_tree_change_watch_dialog (ExprWatch *ew, GtkTreeIter* iter)
 }
 
 static void
-on_program_stopped (ExprWatch *ew)
-{
-	debug_tree_update_all (ew->debug_tree);
-}
-
-static void
 on_program_exited (ExprWatch *ew)
 {
 	debug_tree_disconnect (ew->debug_tree);
 
 	/* Disconnect to other debugger signal */
 	g_signal_handlers_disconnect_by_func (ew->plugin, G_CALLBACK (on_program_exited), ew);
-	g_signal_handlers_disconnect_by_func (ew->plugin, G_CALLBACK (on_program_stopped), ew);
 }
 
 static void
@@ -224,7 +217,6 @@ on_program_started (ExprWatch *ew)
 	
 	/* Connect to other debugger signal */
 	g_signal_connect_swapped (ew->plugin, "program-exited", G_CALLBACK (on_program_exited), ew);
-	g_signal_connect_swapped (ew->plugin, "program-stopped", G_CALLBACK (on_program_stopped), ew);
 }
 
 /* Menu call backs
@@ -315,7 +307,7 @@ on_debug_tree_update_all_watch (GtkAction *action, gpointer user_data)
 {
 	ExprWatch * ew = (ExprWatch *)user_data;
 	
-	debug_tree_update_all (ew->debug_tree);
+	debug_tree_update_tree (ew->debug_tree);
 }
 
 static void
diff --git a/plugins/gdb/debugger.c b/plugins/gdb/debugger.c
index 36c94cc..78aa581 100644
--- a/plugins/gdb/debugger.c
+++ b/plugins/gdb/debugger.c
@@ -4047,7 +4047,7 @@ void debugger_create_variable (Debugger *debugger, const gchar* name, IAnjutaDeb
 
 	g_return_if_fail (IS_DEBUGGER (debugger));
 
-	buff = g_strdup_printf ("-var-create - * %s", name);
+	buff = g_strdup_printf ("-var-create - @ %s", name);
 	debugger_queue_command (debugger, buff, 0, gdb_var_create, callback, user_data);
 	g_free (buff);
 }
@@ -4086,7 +4086,7 @@ gdb_var_update (Debugger *debugger,
 			{
 				const gchar *type_changed = gdbmi_value_literal_get (value);
 				
-				if (strcmp (type_changed, "true"))
+				if (strcmp (type_changed, "true") == 0)
 				{
 					var->deleted = TRUE;
 				}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]