anjuta r3804 - in trunk: . libanjuta/interfaces plugins/debug-manager plugins/gdb



Author: sgranjoux
Date: Sun Mar 30 18:57:25 2008
New Revision: 3804
URL: http://svn.gnome.org/viewvc/anjuta?rev=3804&view=rev

Log:
	* plugins/debug-manager/anjuta-debug-manager.glade,
	plugins/debug-manager/command.c,
	plugins/debug-manager/command.h,
	plugins/debug-manager/start.c,
	plugins/gdb/plugin.c,
	plugins/gdb/debugger.c,
	plugins/gdb/debugger.h,
	libanjuta/interfaces/libanjuta.idl:
	Improve start program dialog, allowing to specify working
	directory and environment variables


Modified:
   trunk/ChangeLog
   trunk/libanjuta/interfaces/libanjuta.idl
   trunk/plugins/debug-manager/anjuta-debug-manager.glade
   trunk/plugins/debug-manager/command.c
   trunk/plugins/debug-manager/command.h
   trunk/plugins/debug-manager/start.c
   trunk/plugins/gdb/debugger.c
   trunk/plugins/gdb/debugger.h
   trunk/plugins/gdb/plugin.c

Modified: trunk/libanjuta/interfaces/libanjuta.idl
==============================================================================
--- trunk/libanjuta/interfaces/libanjuta.idl	(original)
+++ trunk/libanjuta/interfaces/libanjuta.idl	Sun Mar 30 18:57:25 2008
@@ -3108,7 +3108,31 @@
 	* Returns: TRUE if sucessful, other FALSE.
 	*/
 	gboolean attach (pid_t pid, const List<const gchar*> source_search_directories);
-	
+
+	/**
+	* ianjuta_debugger_set_working_directory:
+	* @obj: Self
+	* @dir: working program directory
+	* @err: Error propagation and reporting.
+	* 
+	* Set program working directory.
+	*
+	* Returns: TRUE if sucessful, other FALSE.
+	*/
+	gboolean set_working_directory (const gchar *dir);
+
+	/**
+	* ianjuta_debugger_set_environment:
+	* @obj: Self
+	* @env: List environment variable
+	* @err: Error propagation and reporting
+	*
+	* Set environment variable
+	*
+	* Returns: TRUE if sucessfull, other FALSE.
+	*/
+	gboolean set_environment (const List<const gchar*> env);
+
 	/**
 	* ianjuta_debugger_start:
 	* @obj: Self

Modified: trunk/plugins/debug-manager/anjuta-debug-manager.glade
==============================================================================
--- trunk/plugins/debug-manager/anjuta-debug-manager.glade	(original)
+++ trunk/plugins/debug-manager/anjuta-debug-manager.glade	Sun Mar 30 18:57:25 2008
@@ -1006,7 +1006,7 @@
           <widget class="GtkTable" id="table34">
             <property name="visible">True</property>
             <property name="border_width">5</property>
-            <property name="n_rows">4</property>
+            <property name="n_rows">6</property>
             <property name="n_columns">3</property>
             <property name="column_spacing">5</property>
             <property name="row_spacing">5</property>
@@ -1021,8 +1021,8 @@
               </widget>
               <packing>
                 <property name="right_attach">3</property>
-                <property name="top_attach">3</property>
-                <property name="bottom_attach">4</property>
+                <property name="top_attach">5</property>
+                <property name="bottom_attach">6</property>
                 <property name="x_options">GTK_FILL</property>
                 <property name="y_options"></property>
               </packing>
@@ -1038,8 +1038,8 @@
               </widget>
               <packing>
                 <property name="right_attach">3</property>
-                <property name="top_attach">2</property>
-                <property name="bottom_attach">3</property>
+                <property name="top_attach">4</property>
+                <property name="bottom_attach">5</property>
                 <property name="x_options">GTK_FILL</property>
                 <property name="y_options"></property>
               </packing>
@@ -1058,6 +1058,7 @@
                 <property name="top_attach">1</property>
                 <property name="bottom_attach">2</property>
                 <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
               </packing>
             </child>
             <child>
@@ -1084,7 +1085,7 @@
               <packing>
                 <property name="left_attach">1</property>
                 <property name="right_attach">2</property>
-                <property name="y_options">GTK_FILL</property>
+                <property name="y_options"></property>
                 <property name="y_padding">3</property>
               </packing>
             </child>
@@ -1115,10 +1116,121 @@
                 <property name="y_options"></property>
               </packing>
             </child>
+            <child>
+              <widget class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="events"></property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Working Directory:</property>
+              </widget>
+              <packing>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_FILL</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkFileChooserButton" id="working_dir_chooser">
+                <property name="visible">True</property>
+                <property name="events"></property>
+                <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
+                <property name="title" translatable="yes">Choose a working directory</property>
+              </widget>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="y_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkExpander" id="expander1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <child>
+                  <widget class="GtkHBox" id="hbox6">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="spacing">5</property>
+                    <child>
+                      <widget class="GtkScrolledWindow" id="scrolledwindow3">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                        <property name="shadow_type">GTK_SHADOW_OUT</property>
+                        <child>
+                          <widget class="GtkTreeView" id="environment_treeview">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkVButtonBox" id="vbuttonbox2">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="spacing">5</property>
+                        <property name="layout_style">GTK_BUTTONBOX_START</property>
+                        <child>
+                          <widget class="GtkButton" id="add_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">gtk-add</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                        </child>
+                        <child>
+                          <widget class="GtkButton" id="remove_button">
+                            <property name="visible">True</property>
+                            <property name="sensitive">False</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">gtk-remove</property>
+                            <property name="use_stock">True</property>
+                            <property name="response_id">0</property>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="label" translatable="yes">Environment Variables:</property>
+                  </widget>
+                  <packing>
+                    <property name="type">label_item</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="right_attach">3</property>
+                <property name="top_attach">3</property>
+                <property name="bottom_attach">4</property>
+              </packing>
+            </child>
           </widget>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
             <property name="padding">5</property>
             <property name="position">2</property>
           </packing>

Modified: trunk/plugins/debug-manager/command.c
==============================================================================
--- trunk/plugins/debug-manager/command.c	(original)
+++ trunk/plugins/debug-manager/command.c	Sun Mar 30 18:57:25 2008
@@ -56,13 +56,15 @@
 	INSPECT_MEMORY_COMMAND,
 	DISASSEMBLE_COMMAND,
 	LIST_REGISTER_COMMAND,
+	SET_WORKING_DIRECTORY_COMMAND,
+	SET_ENVIRONMENT_COMMAND,
 	UNLOAD_COMMAND,         /* Program loaded */
 	START_COMMAND,         
 	BREAK_LINE_COMMAND,		  /* Program loaded - Program stopped */
 	BREAK_FUNCTION_COMMAND,
-	BREAK_ADDRESS_COMMAND,
+	BREAK_ADDRESS_COMMAND,	/* 0x10 */
 	ENABLE_BREAK_COMMAND,
-	IGNORE_BREAK_COMMAND,	/* 0x10 */
+	IGNORE_BREAK_COMMAND,
 	CONDITION_BREAK_COMMAND,
 	REMOVE_BREAK_COMMAND,
 	LIST_BREAK_COMMAND,
@@ -76,9 +78,9 @@
 	RUN_COMMAND,		
 	RUN_TO_COMMAND,
 	STEPI_IN_COMMAND,
-	STEPI_OVER_COMMAND,
+	STEPI_OVER_COMMAND,			/* 0x20 */
 	RUN_TO_ADDRESS_COMMAND,
-	EXIT_COMMAND,				/* 0x20 */
+	EXIT_COMMAND,
 	HANDLE_SIGNAL_COMMAND,
 	LIST_LOCAL_COMMAND,
 	LIST_ARG_COMMAND,
@@ -92,9 +94,9 @@
 	SET_FRAME_COMMAND,
 	LIST_FRAME_COMMAND,
 	UPDATE_REGISTER_COMMAND,
-	WRITE_REGISTER_COMMAND,
+	WRITE_REGISTER_COMMAND,		/* 0x30 */
 	EVALUATE_COMMAND,
-	INSPECT_COMMAND,			/* 0x30 */
+	INSPECT_COMMAND,
 	PRINT_COMMAND,
 	CREATE_VARIABLE,
 	EVALUATE_VARIABLE,
@@ -134,6 +136,12 @@
 	DMA_LIST_REGISTER_COMMAND =
 		LIST_REGISTER_COMMAND |
 		NEED_DEBUGGER_STARTED | NEED_PROGRAM_LOADED | NEED_PROGRAM_STOPPED | NEED_PROGRAM_RUNNING,
+	DMA_SET_WORKING_DIRECTORY_COMMAND =
+		SET_WORKING_DIRECTORY_COMMAND |
+		NEED_DEBUGGER_STARTED | NEED_PROGRAM_LOADED,
+	DMA_SET_ENVIRONMENT_COMMAND =
+		SET_ENVIRONMENT_COMMAND |
+		NEED_DEBUGGER_STARTED | NEED_PROGRAM_LOADED,
 	DMA_UNLOAD_COMMAND =
 		UNLOAD_COMMAND | START_DEBUGGER |
 		NEED_PROGRAM_LOADED | NEED_PROGRAM_STOPPED,
@@ -341,6 +349,8 @@
 			gchar *name;
 			gchar *value;
 		} var;
+		GList *env;
+		gchar *dir;
 	} data;
 	struct _DmaQueueCommand *next;
 };
@@ -394,6 +404,16 @@
 		break;
 	case ABORT_COMMAND:
 		break;
+	case SET_WORKING_DIRECTORY_COMMAND:
+		cmd->data.dir = g_strdup (va_arg (args, gchar *));
+		break;
+	case SET_ENVIRONMENT_COMMAND:
+		for (list = va_arg (args, GList *); list != NULL; list = g_list_next (list))
+		{
+			cmd->data.env = g_list_prepend (cmd->data.env, g_strdup (list->data));
+		}
+		cmd->data.env = g_list_reverse (cmd->data.env);
+		break;
 	case START_COMMAND:
 		cmd->data.start.args = g_strdup (va_arg (args, gchar *));
 		cmd->data.start.terminal = va_arg (args, gboolean);
@@ -630,6 +650,18 @@
 }
 
 gboolean
+dma_queue_set_working_directory(DmaDebuggerQueue *self, const gchar *directory)
+{
+	return dma_debugger_queue_append (self, dma_command_new (DMA_SET_WORKING_DIRECTORY_COMMAND, directory));
+}
+
+gboolean
+dma_queue_set_environment(DmaDebuggerQueue *self, const GList *variables)
+{
+	return dma_debugger_queue_append (self, dma_command_new (DMA_SET_ENVIRONMENT_COMMAND, variables));
+}
+
+gboolean
 dma_queue_start (DmaDebuggerQueue *self, const gchar *args, gboolean terminal, gboolean stop)
 {
 	return dma_debugger_queue_append (self, dma_command_new (DMA_START_COMMAND, args, terminal, stop));
@@ -1015,6 +1047,13 @@
         g_list_foreach (cmd->data.load.dirs, (GFunc)g_free, NULL);
         g_list_free (cmd->data.load.dirs);
 		break;
+	case SET_WORKING_DIRECTORY_COMMAND:
+		if (cmd->data.dir) g_free (cmd->data.dir);
+		break;
+	case SET_ENVIRONMENT_COMMAND:
+        g_list_foreach (cmd->data.env, (GFunc)g_free, NULL);
+        g_list_free (cmd->data.env);
+		break;
 	case ATTACH_COMMAND:
         g_list_foreach (cmd->data.attach.dirs, (GFunc)g_free, NULL);
         g_list_free (cmd->data.attach.dirs);
@@ -1114,6 +1153,12 @@
 	case ATTACH_COMMAND:
 		ret = ianjuta_debugger_attach (debugger, cmd->data.attach.pid, cmd->data.load.dirs, err);	
 		break;
+	case SET_WORKING_DIRECTORY_COMMAND:
+		ret = ianjuta_debugger_set_working_directory (debugger, cmd->data.dir, err);	
+		break;
+	case SET_ENVIRONMENT_COMMAND:
+		ret = ianjuta_debugger_set_environment (debugger, cmd->data.env, err);	
+		break;
 	case UNLOAD_COMMAND:
 	    ret = ianjuta_debugger_unload (debugger, err);
 	    break;
@@ -1316,6 +1361,8 @@
 	case QUIT_COMMAND:
 	case ABORT_COMMAND:
 	case START_COMMAND:
+	case SET_WORKING_DIRECTORY_COMMAND:
+	case SET_ENVIRONMENT_COMMAND:	
 	case RUN_COMMAND:
 	case RUN_TO_COMMAND:
 	case STEP_IN_COMMAND:

Modified: trunk/plugins/debug-manager/command.h
==============================================================================
--- trunk/plugins/debug-manager/command.h	(original)
+++ trunk/plugins/debug-manager/command.h	Sun Mar 30 18:57:25 2008
@@ -59,6 +59,8 @@
 /* Create a new command structure and append to command queue */
 gboolean dma_queue_initialize (DmaDebuggerQueue *self);
 gboolean dma_queue_load (DmaDebuggerQueue *self, const gchar *file, const gchar* mime_type, const GList *search_dirs);
+gboolean dma_queue_set_working_directory (DmaDebuggerQueue *self, const gchar *directory);
+gboolean dma_queue_set_environment (DmaDebuggerQueue *self, const GList *variables);
 gboolean dma_queue_attach (DmaDebuggerQueue *self, pid_t pid, const GList *search_dirs);
 gboolean dma_queue_start (DmaDebuggerQueue *self, const gchar *args, gboolean terminal, gboolean stop);
 gboolean dma_queue_unload (DmaDebuggerQueue *self);

Modified: trunk/plugins/debug-manager/start.c
==============================================================================
--- trunk/plugins/debug-manager/start.c	(original)
+++ trunk/plugins/debug-manager/start.c	Sun Mar 30 18:57:25 2008
@@ -37,6 +37,9 @@
 #include <libanjuta/anjuta-debug.h>
 #include <libanjuta/resources.h>
 #include <libanjuta/interfaces/ianjuta-project-manager.h>
+#include <libanjuta/interfaces/ianjuta-document-manager.h>
+#include <libanjuta/interfaces/ianjuta-buildable.h>
+#include <libanjuta/interfaces/ianjuta-file-savable.h>
 #include <libanjuta/anjuta-utils.h>
 
 #include <libgnomevfs/gnome-vfs-mime-utils.h>
@@ -97,6 +100,12 @@
 	N_("Pid"), N_("User"), N_("Time"), N_("Command")
 };
 
+enum {
+	VARIABLE_COLUMN,
+	VALUE_COLUMN,
+	VAR_COLUMNS_NB
+};
+
 struct _AddSourceDialog
 {
 	GtkTreeView *tree;
@@ -116,12 +125,14 @@
 
 	DmaDebuggerQueue *debugger;
 
-	gchar* target_uri;
-	gchar* program_args;
 	gboolean run_in_terminal;
 	gboolean stop_at_beginning;
 
  	GList *source_dirs;
+	GList *environment_vars;
+	GList *recent_target;
+	GList *recent_dirs;
+	GList *recent_args;
 };
 
 /* Widgets found in glade file
@@ -133,6 +144,10 @@
 #define PARAMETER_COMBO "parameter_combo"
 #define TARGET_COMBO "target_combo"
 #define TARGET_SELECT_SIGNAL "on_select_target_clicked"
+#define ADD_VAR_BUTTON "add_button"
+#define REMOVE_VAR_BUTTON "remove_button"
+#define VAR_TREEVIEW "environment_treeview"
+#define DIR_CHOOSER "working_dir_chooser"
 
 #define ADD_SOURCE_DIALOG "source_paths_dialog"
 #define SOURCE_ENTRY "src_entry"
@@ -144,6 +159,8 @@
 
 #define ANJUTA_RESPONSE_SELECT_TARGET 0
 
+#define MAX_RECENT_ITEM		12
+
 static void attach_process_clear (AttachProcess * ap, gint ClearRequest);
 
 /* Helper functions
@@ -224,86 +241,148 @@
 	g_list_free (dirs);
 }
 
+static gboolean
+save_all_files_and_continue (AnjutaPlugin *plugin)
+{
+	IAnjutaDocumentManager *docman;
+	IAnjutaFileSavable* save;
+
+	docman = anjuta_shell_get_interface (plugin->shell, IAnjutaDocumentManager, NULL);
+	
+    /* No document manager, so no file to save */
+	if (docman != NULL)
+    {
+    	save = IANJUTA_FILE_SAVABLE (docman);
+		if (save != NULL)
+		{
+			if (ianjuta_file_savable_is_dirty (save, NULL))
+			{
+				gboolean yes;
+				
+				yes = anjuta_util_dialog_boolean_question (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell),
+					_("Some files are not saved. Do you want to save all them before starting the debugger?"));
+
+				if (yes)
+				{
+                	ianjuta_file_savable_save (save, NULL);
+				}
+				
+				return yes;
+			}
+		}
+	}
+	
+	return TRUE;
+}
+
+static gboolean
+build_target (AnjutaPlugin* plugin, const gchar *target_uri)
+{
+	IAnjutaBuildable *buildable;
+
+	buildable = anjuta_shell_get_interface (plugin->shell, IAnjutaBuildable, NULL);
+	if (buildable != NULL)
+	{
+		gchar *filename;
+		gchar *dirname;
+		
+		filename = gnome_vfs_get_local_path_from_uri (target_uri);
+		g_free (filename);
+		dirname = g_path_get_dirname (filename);
+		ianjuta_buildable_build (buildable, dirname, NULL);
+		g_free (dirname);
+	}
+	
+	return TRUE;
+}
+
 /* Callback for saving session
  *---------------------------------------------------------------------------*/
 
 static void
-on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, DmaStart *this)
+anjuta_session_set_limited_string_list (AnjutaSession *session, const gchar *section, const gchar *key, GList **value)
+{
+	GList *node;
+	
+	while ((node = g_list_nth (*value, MAX_RECENT_ITEM)) != NULL)
+	{
+		g_free (node->data);
+		*value = g_list_delete_link (*value, node);
+	}
+	anjuta_session_set_string_list (session, section, key, *value);
+}
+
+static void
+on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, DmaStart *self)
 {
 	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
 		return;
 
-	if (this->program_args)
-	{
-		gchar *arg;
-		anjuta_session_set_string (session, "Execution", "Program arguments", this->program_args);
-		arg = anjuta_session_get_string (session, "Execution", "Program arguments");
-	}
-	if (this->target_uri)
-	{
-		gchar *uri;
-		anjuta_session_set_string (session, "Execution", "Program uri", this->target_uri);
-		uri = anjuta_session_get_string (session, "Execution", "Program uri");
-	}
-	anjuta_session_set_int (session, "Execution", "Run in terminal", this->run_in_terminal + 1);
-	anjuta_session_set_int (session, "Execution", "Stop at beginning", this->stop_at_beginning + 1);
- 	if (this->source_dirs)
- 	{
- 		anjuta_session_set_string_list (session, "Debugger", "Source directories", this->source_dirs);
- 	}
+	anjuta_session_set_limited_string_list (session, "Debugger", "Program arguments", &self->recent_args);
+	anjuta_session_set_limited_string_list (session, "Debugger", "Program uri", &self->recent_target);
+	anjuta_session_set_int (session, "Execution", "Run in terminal", self->run_in_terminal + 1);
+	anjuta_session_set_int (session, "Debugger", "Stop at beginning", self->stop_at_beginning + 1);
+	anjuta_session_set_string_list (session, "Debugger", "Source directories", self->source_dirs);
+	anjuta_session_set_string_list (session, "Debugger", "Working directories", self->recent_dirs);
+	anjuta_session_set_string_list (session, "Debugger", "Environment variables", self->environment_vars);
 }
 
-static void on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, DmaStart *this)
+static void on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, DmaStart *self)
 {
-	gchar *program_args;
-	gchar *target_uri;
     gint run_in_terminal;
 	gint stop_at_beginning;
 
 	if (phase != ANJUTA_SESSION_PHASE_NORMAL)
 		return;
 
-	program_args = anjuta_session_get_string (session, "Execution", "Program arguments");
-	if (this->program_args)
-	{
-		g_free (this->program_args);
-		this->program_args = NULL;
-	}
-    if (program_args)
-    {
-		this->program_args = program_args;
-    }
+ 	if (self->recent_args != NULL)
+ 	{		
+ 		g_list_foreach (self->recent_args, (GFunc)g_free, NULL);
+ 		g_list_free (self->recent_args);
+ 	}
+ 	self->recent_args = anjuta_session_get_string_list (session, "Debugger", "Program arguments");
 
-	target_uri = anjuta_session_get_string (session, "Execution", "Program uri");
-	if (this->target_uri)
-	{
-		g_free (this->target_uri);
-		this->target_uri = NULL;
-	}
-    if (target_uri)
-    {
-		this->target_uri = target_uri;
-    }
+ 	if (self->recent_target != NULL)
+ 	{		
+ 		g_list_foreach (self->recent_target, (GFunc)g_free, NULL);
+ 		g_list_free (self->recent_target);
+ 	}
+ 	self->recent_target = anjuta_session_get_string_list (session, "Debugger", "Program uri");
 	
 	/* The flag is store as 1 == FALSE, 2 == TRUE */
 	run_in_terminal = anjuta_session_get_int (session, "Execution", "Run in terminal");
 	if (run_in_terminal == 0)
-		this->run_in_terminal = TRUE;	/* Default value */
+		self->run_in_terminal = TRUE;	/* Default value */
 	else
-		this->run_in_terminal = run_in_terminal - 1;
+		self->run_in_terminal = run_in_terminal - 1;
 	
-	stop_at_beginning = anjuta_session_get_int (session, "Execution", "Stop at beginning");
+	stop_at_beginning = anjuta_session_get_int (session, "Debugger", "Stop at beginning");
 	if (stop_at_beginning == 0)
-		this->stop_at_beginning = TRUE;	/* Default value */
+		self->stop_at_beginning = TRUE;	/* Default value */
 	else
-		this->stop_at_beginning = stop_at_beginning - 1;
+		self->stop_at_beginning = stop_at_beginning - 1;
+	
 	/* Initialize source_dirs */
- 	if (this->source_dirs != NULL)
+ 	if (self->source_dirs != NULL)
  	{		
- 		g_list_foreach (this->source_dirs, (GFunc)g_free, NULL);
- 		g_list_free (this->source_dirs);
+ 		g_list_foreach (self->source_dirs, (GFunc)g_free, NULL);
+ 		g_list_free (self->source_dirs);
  	}
- 	this->source_dirs = anjuta_session_get_string_list (session, "Debugger", "Source directories");
+ 	self->source_dirs = anjuta_session_get_string_list (session, "Debugger", "Source directories");
+	
+ 	if (self->recent_dirs != NULL)
+ 	{		
+ 		g_list_foreach (self->recent_dirs, (GFunc)g_free, NULL);
+ 		g_list_free (self->recent_dirs);
+ 	}
+ 	self->recent_dirs = anjuta_session_get_string_list (session, "Debugger", "Working directories");
+
+ 	if (self->environment_vars != NULL)
+ 	{		
+ 		g_list_foreach (self->environment_vars, (GFunc)g_free, NULL);
+ 		g_list_free (self->environment_vars);
+ 	}
+ 	self->environment_vars = anjuta_session_get_string_list (session, "Debugger", "Environment variables");
 }
 
 /* Attach to process private functions
@@ -841,12 +920,6 @@
 /* Load file private functions
  *---------------------------------------------------------------------------*/
 
-static void
-on_select_target (GtkButton *button, gpointer user_data)
-{
-	gtk_dialog_response (GTK_DIALOG (user_data), ANJUTA_RESPONSE_SELECT_TARGET);
-}
-
 static gboolean
 dma_start_load_uri (DmaStart *this)
 {
@@ -855,32 +928,34 @@
 	gchar *mime_type;
 	gchar *filename;
 
+	if (this->recent_target == NULL) return FALSE;	/* Missing URI */
+	
 	if (!dma_quit_debugger (this)) return FALSE;
 	
-	if ((this->target_uri == NULL) || (*(this->target_uri) == '\0'))
-	{
-		/* Missing URI */
-		return FALSE;
-	}
-	vfs_uri = gnome_vfs_uri_new (this->target_uri);
+	vfs_uri = gnome_vfs_uri_new ((const gchar *)(this->recent_target->data));
 		
-	g_return_if_fail (vfs_uri != NULL);
+	g_return_val_if_fail (vfs_uri != NULL, TRUE);
 	
 	if (!gnome_vfs_uri_is_local (vfs_uri)) return FALSE;
-			
+
+	if (save_all_files_and_continue (this->plugin))
+	{
+		build_target (this->plugin, (const gchar *)(this->recent_target->data));
+	}
+	
 	search_dirs = get_source_directories (this->plugin);
-		
-	mime_type = gnome_vfs_get_mime_type (this->target_uri);
+	
+	mime_type = gnome_vfs_get_mime_type ((const gchar *)(this->recent_target->data));
 	if (mime_type == NULL)
 	{
 		anjuta_util_dialog_error(GTK_WINDOW (this->plugin->shell),
-				_("Unable to open %s. Debugger cannot start."), this->target_uri);
+				_("Unable to open %s. Debugger cannot start."), (const gchar *)(this->recent_target->data));
 		return FALSE;
 	}
-    	filename = gnome_vfs_get_local_path_from_uri (this->target_uri);
-
+	filename = gnome_vfs_get_local_path_from_uri ((const gchar *)(this->recent_target->data));
+	
 	dma_queue_load (this->debugger, filename, mime_type, this->source_dirs);
-		
+	
 	g_free (filename);
 	g_free (mime_type);
 	gnome_vfs_uri_unref (vfs_uri);
@@ -889,6 +964,156 @@
 	return TRUE;
 }
 
+/* Run program dialog
+ *---------------------------------------------------------------------------*/
+
+static void
+on_select_target (GtkButton *button, gpointer user_data)
+{
+	gtk_dialog_response (GTK_DIALOG (user_data), ANJUTA_RESPONSE_SELECT_TARGET);
+}
+
+static void
+on_environment_add_button (GtkButton *button, GtkTreeView *view)
+{
+	GtkTreeIter iter;
+	GtkListStore *model;
+	GtkTreeViewColumn *column;
+	GtkTreePath *path;
+		
+	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+	gtk_list_store_append (model, &iter);
+	path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+	column = gtk_tree_view_get_column (view, 0);
+	gtk_tree_view_set_cursor (view, path, column ,TRUE);
+	gtk_tree_path_free (path);
+}
+
+static void
+on_environment_remove_button (GtkButton *button, GtkTreeView *view)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection* sel;
+
+	sel = gtk_tree_view_get_selection (view);
+	if (gtk_tree_selection_get_selected (sel, NULL, &iter))
+	{
+		GtkListStore *model;
+		model = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+		
+		gtk_list_store_remove (model, &iter);
+	}
+}
+
+static void
+on_environment_variable_edited (GtkCellRendererText *cell,
+						  gchar *path,
+                          gchar *text,
+                          GtkTreeView *view)
+{
+	GtkTreeIter iter;
+	GtkListStore *model;
+	
+	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));	
+	if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
+	{
+		GtkTreeViewColumn *column;
+		GtkTreePath *path;
+		gtk_list_store_set (model, &iter, VARIABLE_COLUMN, text, -1);		
+		path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+		column = gtk_tree_view_get_column (view, 1);
+		gtk_tree_view_set_cursor (view, path, column ,TRUE);
+	}
+}
+
+static void
+on_environment_selection_changed (GtkTreeSelection *selection, GtkWidget *button)
+{
+	gtk_widget_set_sensitive (button, gtk_tree_selection_get_selected (selection, NULL, NULL));
+}
+
+static void
+on_environment_value_edited (GtkCellRendererText *cell,
+						  gchar *path,
+                          gchar *text,
+                          GtkTreeView *view)
+{
+	GtkTreeIter iter;
+	GtkListStore *model;
+	
+	model = GTK_LIST_STORE (gtk_tree_view_get_model (view));	
+	if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path))
+	{
+		gtk_list_store_set (model, &iter, VALUE_COLUMN, text, -1);		
+	}
+}
+
+static void
+on_add_string_in_model (gpointer data, gpointer user_data)
+{
+	GtkListStore* model = (GtkListStore *)user_data;
+	GtkTreeIter iter;
+	
+	gtk_list_store_append (model, &iter);
+	gtk_list_store_set (model, &iter, 0, (const gchar *)data, -1);
+}
+
+static void
+on_add_uri_in_model (gpointer data, gpointer user_data)
+{
+	GtkListStore* model = (GtkListStore *)user_data;
+	GtkTreeIter iter;
+	gchar *local;
+	
+	local = gnome_vfs_get_local_path_from_uri ((const char *)data);
+	gtk_list_store_append (model, &iter);
+	gtk_list_store_set (model, &iter, 0, local, -1);
+	g_free (local);
+}
+
+static void
+on_add_variable_in_model (gpointer data, gpointer user_data)
+{
+	GtkListStore* model = (GtkListStore *)user_data;
+	GtkTreeIter iter;
+	gchar **var;
+	
+	var = g_strsplit ((const gchar *)data, "=", 2);
+
+	if (var)
+	{
+		gtk_list_store_append (model, &iter);
+		gtk_list_store_set (model, &iter, 0, var[0], 1, var[1], -1);
+		g_strfreev (var);
+	}
+}
+
+static void
+on_add_directory_in_chooser (gpointer data, gpointer user_data)
+{
+	GtkFileChooser* chooser = (GtkFileChooser *)user_data;
+	gchar *local;
+
+	local = gnome_vfs_get_local_path_from_uri ((const char *)data);
+	gtk_file_chooser_add_shortcut_folder (chooser, (const gchar *)local, NULL);
+	g_free (local);
+}
+
+static gboolean
+on_add_variable_in_list (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
+{
+	GList** list = (GList **)user_data;
+	gchar* name;
+	gchar* value;
+
+	gtk_tree_model_get (model, iter, 0, &name, 1, &value, -1);
+	*list = g_list_prepend (*list, g_strconcat(name, "=", value, NULL));
+	g_free (name);
+	g_free (value);
+	
+	return FALSE;
+}
+
 static gboolean
 dma_set_parameters (DmaStart *this)
 {
@@ -901,7 +1126,12 @@
 	GtkComboBox *target;
 	gint response;
 	GtkTreeModel* model;
-	GtkTreeIter iter;
+	GtkTreeView *vars;
+	GtkFileChooser *dirs;
+	GtkCellRenderer *renderer;	
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *selection;
+	GObject *button;
 	GValue value = {0,};
 	const gchar *project_root_uri;
 	
@@ -918,18 +1148,28 @@
 	stop_at_beginning = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gxml, STOP_AT_BEGINNING_CHECK_BUTTON));
 	params = GTK_COMBO_BOX (glade_xml_get_widget (gxml, PARAMETER_COMBO));
 	target = GTK_COMBO_BOX (glade_xml_get_widget (gxml, TARGET_COMBO));
+	vars = GTK_TREE_VIEW (glade_xml_get_widget (gxml, VAR_TREEVIEW));
+	dirs = GTK_FILE_CHOOSER (glade_xml_get_widget (gxml, DIR_CHOOSER));
+
+	/* Connect signals */	
 	glade_xml_signal_connect_data (gxml, TARGET_SELECT_SIGNAL, GTK_SIGNAL_FUNC (on_select_target), dlg);
+	button = G_OBJECT (glade_xml_get_widget (gxml, ADD_VAR_BUTTON));
+	g_signal_connect (button, "clicked", G_CALLBACK (on_environment_add_button), vars);
+	button = G_OBJECT (glade_xml_get_widget (gxml, REMOVE_VAR_BUTTON));
+	g_signal_connect (button, "clicked", G_CALLBACK (on_environment_remove_button), vars);
+	selection = gtk_tree_view_get_selection (vars);
+	g_signal_connect (selection, "changed", G_CALLBACK (on_environment_selection_changed), GTK_WIDGET (button));
+	
 	g_object_unref (gxml);
 
 	/* Fill parameter combo box */
 	model = GTK_TREE_MODEL (gtk_list_store_new (1, GTK_TYPE_STRING));
 	gtk_combo_box_set_model (params, model);
 	gtk_combo_box_entry_set_text_column( GTK_COMBO_BOX_ENTRY(params), 0);
-	if (this->program_args != NULL)
+	g_list_foreach (this->recent_args, on_add_string_in_model, model);
+	if (this->recent_args != NULL)
 	{
-		gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, this->program_args, -1);
-		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (params)->child), this->program_args);
+		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (params)->child), (const char *)this->recent_args->data);
 	}
 	g_object_unref (model);
 
@@ -937,6 +1177,7 @@
 	model = GTK_TREE_MODEL (gtk_list_store_new (1, GTK_TYPE_STRING));
 	gtk_combo_box_set_model (target, model);
 	gtk_combo_box_entry_set_text_column( GTK_COMBO_BOX_ENTRY(target), 0);
+	g_list_foreach (this->recent_target, on_add_uri_in_model, model);
 
     anjuta_shell_get_value (this->plugin->shell, "project_root_uri", &value, NULL);
 	project_root_uri = G_VALUE_HOLDS_STRING (&value) ? g_value_get_string (&value) : NULL;
@@ -960,10 +1201,16 @@
 
 			for (node = exec_targets; node; node = g_list_next (node))
 			{
-				if ((this->target_uri == NULL) || (strcmp(this->target_uri, node->data) != 0))
+				GList *target;
+				for (target = this->recent_target; target; target = g_list_next (target))
+				{
+					if (strcmp ((const gchar *)target->data, node->data) == 0) break;
+				}
+				if (target == NULL)
 				{
-					gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-					gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, node->data, -1);
+					on_add_uri_in_model (node->data, model);
+					/*gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+					gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, node->data, -1);*/
 				}
 				g_free (node->data);
 			}
@@ -972,20 +1219,35 @@
 	}
 	g_object_unref (model);
 
-	if (this->target_uri != NULL)
-	{
-		gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, this->target_uri, -1);
-		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (target)->child), this->target_uri);
-	}
-	else if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter))
+	if (this->recent_target != NULL)
 	{
-		gchar *txt;
+		gchar *local;
 		
-		gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &txt, -1);
-		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (target)->child), txt);
-		g_free (txt);
-	}
+		local = gnome_vfs_get_local_path_from_uri ((const char *)this->recent_target->data);
+		gtk_entry_set_text (GTK_ENTRY (GTK_BIN (target)->child), local);
+		g_free (local);
+	}
+	/* Fill working directory list */
+	g_list_foreach (this->recent_dirs, on_add_directory_in_chooser, dirs);	
+	
+	/* Fill environment variable list */
+	model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING)); 
+	gtk_tree_view_set_model (vars, model);
+	g_list_foreach (this->environment_vars, on_add_variable_in_model, model);
+	g_object_unref (model);
+	
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set(renderer, "editable", TRUE, NULL);	
+	g_signal_connect(renderer, "edited", (GCallback) on_environment_variable_edited, vars);
+	column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, "text", 0, NULL);
+	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+	gtk_tree_view_append_column (vars, column);
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set(renderer, "editable", TRUE, NULL);	
+	g_signal_connect(renderer, "edited", (GCallback) on_environment_value_edited, vars);
+	column = gtk_tree_view_column_new_with_attributes (_("Value"), renderer, "text", 1, NULL);
+	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+	gtk_tree_view_append_column (vars, column);
 	
 	/* Set terminal option */	
 	if (this->run_in_terminal) gtk_toggle_button_set_active (term, TRUE);
@@ -1003,26 +1265,57 @@
 		case GTK_RESPONSE_APPLY:
 		{
 			const gchar *arg;
-			const gchar *uri;
+			const gchar *filename;
+			gchar *uri;
+			GList *find;
 			
-			if (this->program_args != NULL) g_free (this->program_args);
 			arg = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (params)->child));
-			this->program_args = g_strdup (arg);
+			if (arg != NULL)
+			{
+				find = g_list_find_custom(this->recent_args, arg, (GCompareFunc)strcmp);
+				if (find)
+				{
+					g_free (find->data);
+					this->recent_args = g_list_delete_link (this->recent_args, find);
+				}
+				this->recent_args = g_list_prepend (this->recent_args, g_strdup (arg));
+			}	
 			
-			uri = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (target)->child));
-			if (this->target_uri != NULL)
+			filename = gtk_entry_get_text (GTK_ENTRY (GTK_BIN (target)->child));
+			if (filename != NULL)
 			{
-				if (strcmp(uri, this->target_uri) != 0)
+				uri = gnome_vfs_get_uri_from_local_path (filename);
+				if (uri != NULL)
 				{
-					g_free (this->target_uri);
-					this->target_uri = g_strdup (uri);
+					find = g_list_find_custom (this->recent_target, uri, (GCompareFunc)strcmp);
+					if (find)
+					{
+						g_free (find->data);
+						this->recent_target = g_list_delete_link (this->recent_target, find);
+					}
+					this->recent_target = g_list_prepend (this->recent_target, uri);
 				}
 			}
-			else
+
+			uri = gtk_file_chooser_get_uri (dirs);
+			if (uri != NULL)
 			{
-				this->target_uri = g_strdup (uri);
+				find = g_list_find_custom(this->recent_dirs, uri, (GCompareFunc)strcmp);
+				if (find)
+				{
+					g_free (find->data);
+					this->recent_dirs = g_list_delete_link (this->recent_dirs, find);
+				}
+				this->recent_dirs = g_list_prepend (this->recent_dirs, uri);
 			}
 			
+			g_list_foreach (this->environment_vars, (GFunc)g_free, NULL);
+			g_list_free (this->environment_vars);
+			this->environment_vars = NULL;
+			model = gtk_tree_view_get_model (vars);			
+			gtk_tree_model_foreach (GTK_TREE_MODEL (model), on_add_variable_in_list, &this->environment_vars);
+			this->environment_vars = g_list_reverse (this->environment_vars);
+			
 			this->run_in_terminal = gtk_toggle_button_get_active (term);
 			this->stop_at_beginning = gtk_toggle_button_get_active (stop_at_beginning);
 			break;
@@ -1048,27 +1341,10 @@
 
 			if (response == GTK_RESPONSE_OK)
 			{
-				gchar* uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (sel_dlg));
-				
-				if (this->target_uri != NULL)
-				{
-					if (strcmp(uri, this->target_uri) != 0)
-					{
-						g_free (this->target_uri);
-						this->target_uri = uri;
-					}
-					else
-					{
-						g_free (uri);
-					}
-				}
-				else
-				{
-					this->target_uri = uri;
-				}
-					
-				gtk_entry_set_text (GTK_ENTRY (GTK_BIN (target)->child), this->target_uri);
+				gchar* filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (sel_dlg));
 
+				gtk_entry_set_text (GTK_ENTRY (GTK_BIN (target)->child), filename);
+				g_free (filename);
 			}
 			gtk_widget_destroy (GTK_WIDGET (sel_dlg));
 
@@ -1103,19 +1379,6 @@
 }
 
 static void
-on_add_source_in_model (gpointer data, gpointer user_data)
-{
-	GtkListStore* model = (GtkListStore *)user_data;
-	GtkTreeIter iter;
-	gchar *local;
-	
-	local = gnome_vfs_get_local_path_from_uri ((const char *)data);
-	gtk_list_store_append (model, &iter);
-	gtk_list_store_set (model, &iter, 0, local, -1);
-	g_free (local);
-}
-
-static void
 on_source_add_button (GtkButton *button, AddSourceDialog *dlg)
 {
 	GtkTreeIter iter;
@@ -1229,7 +1492,7 @@
 	gtk_window_set_transient_for (GTK_WINDOW (widget), parent);
 
 	/* Initialize source path list */
-	g_list_foreach (this->source_dirs, on_add_source_in_model, dlg.model);
+	g_list_foreach (this->source_dirs, on_add_uri_in_model, dlg.model);
 	
 	/* Run dialog */
 	for (;;)
@@ -1248,7 +1511,7 @@
 			break;
 		case GTK_RESPONSE_CANCEL:
 			gtk_list_store_clear (dlg.model);
-			g_list_foreach (this->source_dirs, on_add_source_in_model, dlg.model);
+			g_list_foreach (this->source_dirs, on_add_uri_in_model, dlg.model);
 			continue;
 		default:
 			break;
@@ -1314,22 +1577,30 @@
 dma_run_target (DmaStart *this)
 {
 	if (!dma_set_parameters (this)) return FALSE;
-       
-	if (!dma_start_load_uri (this)) return FALSE;
-
-	dma_queue_start (this->debugger, this->program_args == NULL ? "" : this->program_args, this->run_in_terminal, this->stop_at_beginning);
-	
-	return TRUE;
+    
+	return dma_rerun_target (this);
 }
 
 gboolean
 dma_rerun_target (DmaStart *this)
 {
-	if (this->target_uri == NULL) return FALSE;
-
+	gchar *dir;
+	
 	if (!dma_start_load_uri (this)) return FALSE;
 
-	dma_queue_start (this->debugger, this->program_args == NULL ? "" : this->program_args, this->run_in_terminal, this->stop_at_beginning);
+	if (this->recent_dirs != NULL)
+	{
+		dir = gnome_vfs_get_local_path_from_uri ((const gchar *)(this->recent_dirs->data));
+	}
+	else
+	{
+		dir = NULL;
+	}
+	dma_queue_set_working_directory (this->debugger, dir);
+	g_free (dir);
+	dma_queue_set_environment (this->debugger, this->environment_vars);
+	
+	dma_queue_start (this->debugger, this->recent_args == NULL ? "" : (const char *)this->recent_args->data,this->run_in_terminal, this->stop_at_beginning);
 	
 	return TRUE;
 }
@@ -1361,13 +1632,18 @@
 {
 	g_signal_handlers_disconnect_by_func (this->plugin->shell, G_CALLBACK (on_session_save), this);
     g_signal_handlers_disconnect_by_func (this->plugin->shell, G_CALLBACK (on_session_load), this);
-	if (this->source_dirs != NULL)
-	{
-		g_list_foreach (this->source_dirs, (GFunc)g_free, NULL);
-		g_list_free (this->source_dirs);
-	}
-	if (this->program_args != NULL) g_free (this->program_args);
-	if (this->target_uri != NULL) g_free (this->target_uri);
+	g_list_foreach (this->source_dirs, (GFunc)g_free, NULL);
+	g_list_free (this->source_dirs);
+	g_list_foreach (this->recent_target, (GFunc)g_free, NULL);
+	g_list_free (this->recent_target);
+	g_list_foreach (this->recent_args, (GFunc)g_free, NULL);
+	g_list_free (this->recent_args);
+	g_list_foreach (this->recent_args, (GFunc)g_free, NULL);
+	g_list_free (this->recent_args);
+	g_list_foreach (this->recent_dirs, (GFunc)g_free, NULL);
+	g_list_free (this->recent_dirs);
+	g_list_foreach (this->environment_vars, (GFunc)g_free, NULL);
+	g_list_free (this->environment_vars);
 	g_free (this);
 }
 

Modified: trunk/plugins/gdb/debugger.c
==============================================================================
--- trunk/plugins/gdb/debugger.c	(original)
+++ trunk/plugins/gdb/debugger.c	Sun Mar 30 18:57:25 2008
@@ -726,6 +726,45 @@
 	g_free (command);
 }
 
+/* Set environment
+ *---------------------------------------------------------------------------*/
+
+gboolean
+debugger_set_working_directory (Debugger *debugger, const gchar *directory)
+{
+	gchar *buff;
+
+	DEBUG_PRINT ("In function: set_working_directory()");
+	
+	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
+
+	buff = g_strdup_printf ("-environment-cd %s", directory);	
+	debugger_queue_command (debugger, buff, FALSE, FALSE, NULL, NULL, NULL);
+	g_free (buff);
+	
+	return TRUE;
+}
+
+gboolean
+debugger_set_environment (Debugger *debugger, const GList *variables)
+{
+	gchar *buff;
+	GList *node;
+
+	DEBUG_PRINT ("In function: set_environment()");
+
+	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
+
+	for (node = variables; node != NULL; node = g_list_next (node))
+	{
+		buff = g_strdup_printf("set environment %s", (const char *)node->data);
+		debugger_queue_command (debugger, buff, FALSE, FALSE, NULL, NULL, NULL);
+		g_free (buff);
+	}
+	
+	return TRUE;
+}
+
 gboolean
 debugger_start (Debugger *debugger, const GList *search_dirs,
 				const gchar *prog, gboolean is_libtool_prog)

Modified: trunk/plugins/gdb/debugger.h
==============================================================================
--- trunk/plugins/gdb/debugger.h	(original)
+++ trunk/plugins/gdb/debugger.h	Sun Mar 30 18:57:25 2008
@@ -107,6 +107,10 @@
 void debugger_attach_process (Debugger *debugger, pid_t pid);
 void debugger_detach_process (Debugger *debugger);
 
+/* Environment */
+gboolean debugger_set_working_directory (Debugger *debugger, const gchar *directory);
+gboolean debugger_set_environment (Debugger *debugger, const GList *variables);
+
 /* Execution */
 void debugger_start_program (Debugger *debugger, const gchar* args, const gchar* tty, gboolean stop);
 void debugger_stop_program (Debugger *debugger);

Modified: trunk/plugins/gdb/plugin.c
==============================================================================
--- trunk/plugins/gdb/plugin.c	(original)
+++ trunk/plugins/gdb/plugin.c	Sun Mar 30 18:57:25 2008
@@ -350,6 +350,26 @@
 }
 
 static gboolean
+idebugger_set_working_directory (IAnjutaDebugger *plugin, const gchar *directory, GError **err)
+{
+	GdbPlugin *self = ANJUTA_PLUGIN_GDB (plugin);
+
+	debugger_set_working_directory (self->debugger, directory);
+
+	return TRUE;
+}
+
+static gboolean
+idebugger_set_environment (IAnjutaDebugger *plugin, const GList *variables, GError **err)
+{
+	GdbPlugin *self = ANJUTA_PLUGIN_GDB (plugin);
+
+	debugger_set_environment (self->debugger, variables);
+
+	return TRUE;
+}
+
+static gboolean
 idebugger_attach (IAnjutaDebugger *plugin, pid_t pid, const GList *search_dirs, GError **err)
 {
 	GdbPlugin *this = ANJUTA_PLUGIN_GDB (plugin);
@@ -733,6 +753,8 @@
 	iface->get_state = idebugger_get_state;
 	iface->attach = idebugger_attach;
 	iface->load = idebugger_load;
+	iface->set_working_directory = idebugger_set_working_directory;
+	iface->set_environment = idebugger_set_environment;
 	iface->start = idebugger_start;
 	iface->unload = idebugger_unload;
 	iface->quit = idebugger_quit;



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