Integrate adding files with the file manager
[anjuta-git-plugin.git] / plugins / valgrind / vgactions.c
bloba366659bb19c74f4ad896da8dca813437500809c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * Copyright (C) Massimo Cora' 2005 <maxcvs@gmail.com>
5 * You may redistribute it and/or modify it under the terms of the
6 * GNU General Public License, as published by the Free Software
7 * Foundation; either version 2, or (at your option) any later version.
8 *
9 * plugin.h is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with plugin.h. See the file "COPYING". If not,
16 * write to: The Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include <gtk/gtk.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <errno.h>
31 #include <libanjuta/anjuta-debug.h>
33 #include "vgactions.h"
34 #include "vgtoolview.h"
35 #include "vgdefaultview.h"
37 #define EXE_PATH "/apps/anjuta/valgrind/exe-path"
39 static void vg_actions_class_init(VgActionsClass *klass);
40 static void vg_actions_init(VgActions *sp);
41 static void vg_actions_finalize(GObject *object);
43 static GObjectClass *parent_class = NULL;
45 struct _VgActionsPriv {
46 const gchar *program;
47 const char **srcdir;
48 SymTab *symtab;
50 GtkWidget *view;
52 GIOChannel *gio;
53 guint watch_id;
54 pid_t pid;
56 AnjutaValgrindPlugin *anjuta_plugin; /* mainly for valgrind_update_ui () */
57 ValgrindPluginPrefs **prefs;
61 GType
62 vg_actions_get_type (void)
64 static GType type = 0;
66 if(type == 0) {
67 static const GTypeInfo our_info = {
68 sizeof (VgActionsClass),
69 NULL,
70 NULL,
71 (GClassInitFunc)vg_actions_class_init,
72 NULL,
73 NULL,
74 sizeof (VgActions),
76 (GInstanceInitFunc)vg_actions_init,
79 type = g_type_register_static(G_TYPE_OBJECT,
80 "VgActions", &our_info, 0);
83 return type;
86 static void
87 vg_actions_class_init(VgActionsClass *klass)
89 GObjectClass *object_class = G_OBJECT_CLASS(klass);
91 parent_class = g_type_class_peek_parent(klass);
92 object_class->finalize = vg_actions_finalize;
95 static void
96 vg_actions_init(VgActions *obj)
98 VgActionsPriv *priv;
99 obj->priv = g_new0(VgActionsPriv, 1);
101 priv = obj->priv;
103 priv->srcdir = NULL;
104 priv->symtab = NULL;
106 priv->view = NULL;
108 priv->gio = NULL;
109 priv->watch_id = 0;
110 priv->pid = (pid_t) -1;
112 priv->prefs = NULL;
115 static void
116 vg_actions_finalize(GObject *object)
118 VgActions *cobj;
119 cobj = VG_ACTIONS(object);
121 g_object_unref (G_OBJECT (cobj->priv->anjuta_plugin));
122 g_object_unref (G_OBJECT (cobj->priv->view));
124 /* Free private members, etc. */
125 /* wouldn't be necessary.. anyway */
126 cobj->priv->anjuta_plugin = NULL;
127 cobj->priv->prefs = NULL;
129 g_free(cobj->priv);
130 G_OBJECT_CLASS(parent_class)->finalize(object);
133 VgActions *
134 vg_actions_new (AnjutaValgrindPlugin *anjuta_plugin,
135 ValgrindPluginPrefs **prefs, GtkWidget *vg_default_view)
137 VgActions *obj;
139 g_return_val_if_fail(prefs != NULL, NULL);
141 obj = VG_ACTIONS(g_object_new(VG_TYPE_ACTIONS, NULL));
143 /* set the anjuta plugin object */
144 obj->priv->anjuta_plugin = anjuta_plugin;
146 /* set the prefs object */
147 obj->priv->prefs = prefs;
149 /* and the view object */
150 obj->priv->view = GTK_WIDGET (vg_default_view);
152 g_object_ref (G_OBJECT (obj->priv->anjuta_plugin));
153 g_object_ref (G_OBJECT (obj->priv->view));
155 return obj;
158 static gboolean
159 io_ready_cb (GIOChannel *gio, GIOCondition condition, gpointer user_data)
161 VgActions *actions = user_data;
162 VgActionsPriv *priv;
164 priv = actions->priv;
166 if ((condition & G_IO_IN) && vg_tool_view_step (VG_TOOL_VIEW (priv->view)) <= 0) {
167 DEBUG_PRINT ("child program exited or error in GIOChannel [IO_IN], killing");
168 anjuta_util_dialog_info (NULL, _("Reached the end of the input file or error "
169 "in parsing valgrind output."));
170 vg_actions_kill (actions);
171 priv->watch_id = 0;
172 return FALSE;
175 if (condition & G_IO_HUP) {
176 DEBUG_PRINT ("child program exited or error in GIOChannel [IO_HUP], killing");
177 anjuta_util_dialog_info (NULL, _("Process exited."));
178 vg_actions_kill (actions);
179 priv->watch_id = 0;
180 return FALSE;
183 return TRUE;
186 static gboolean
187 check_valgrind_binary()
189 GConfClient *gconf;
190 gchar *str_valgrind_file;
191 GError *err = NULL;
193 gconf = gconf_client_get_default ();
194 if (!(str_valgrind_file =
195 gconf_client_get_string (gconf, EXE_PATH, &err)) || err != NULL) {
196 anjuta_util_dialog_error (NULL,
197 _("Could not get the right valgrind-binary gconf key:"));
198 g_free (str_valgrind_file);
199 return FALSE;
202 if ( g_file_test (str_valgrind_file,
203 G_FILE_TEST_EXISTS | G_FILE_TEST_IS_SYMLINK) == FALSE ) {;
204 anjuta_util_dialog_error (NULL,
205 _("Valgrind binary [%s] does not exist. Please check "
206 "the preferences or install Valgrind package."),
207 str_valgrind_file);
209 g_free (str_valgrind_file);
210 return FALSE;
213 g_free (str_valgrind_file);
214 return TRUE;
217 void
218 vg_actions_run (VgActions *actions, gchar* prg_to_debug, gchar* tool, GError **err)
220 char logfd_arg[30];
221 GPtrArray *args;
222 int logfd[2];
223 char **argv;
224 int i;
225 VgActionsPriv *priv;
227 g_return_if_fail (actions != NULL);
229 priv = actions->priv;
231 g_return_if_fail (priv->prefs != NULL);
233 /* check the valgrind binary availability */
234 if (!check_valgrind_binary ())
235 return;
237 priv->program = g_strdup (prg_to_debug);
239 if (priv->pid != (pid_t) -1) {
240 anjuta_util_dialog_error (NULL,
241 _("Could not get the right pipe for the process."));
243 return;
246 if (pipe (logfd) == -1) {
247 anjuta_util_dialog_error (NULL,
248 _("Could not get the right pipe for the process."));
249 return;
252 args = valgrind_plugin_prefs_create_argv (*priv->prefs, tool);
254 sprintf (logfd_arg, "--log-fd=%d", logfd[1]);
255 g_ptr_array_add (args, logfd_arg);
257 for ( i=0; i < args->len; i++ ) {
258 DEBUG_PRINT ("arg %d is %s", i, (char*)g_ptr_array_index (args, i));
261 g_ptr_array_add (args, (gpointer)priv->program);
263 DEBUG_PRINT("program noticed is %s", priv->program);
264 g_ptr_array_add (args, NULL);
266 argv = (char **) args->pdata;
268 priv->pid = process_fork (argv[0], argv, TRUE, logfd[1], NULL, NULL, NULL, err);
270 if (priv->pid == (pid_t) -1) {
271 close (logfd[0]);
272 close (logfd[1]);
273 return;
276 g_ptr_array_free (args, TRUE);
277 close (logfd[1]);
279 vg_tool_view_clear(VG_TOOL_VIEW (priv->view));
280 vg_tool_view_connect (VG_TOOL_VIEW (priv->view), logfd[0]);
282 priv->gio = g_io_channel_unix_new (logfd[0]);
283 priv->watch_id = g_io_add_watch (priv->gio, G_IO_IN | G_IO_HUP,
284 io_ready_cb, actions);
286 /* let's update our menu status */
287 valgrind_set_busy_status (priv->anjuta_plugin, TRUE);
288 valgrind_update_ui (priv->anjuta_plugin);
291 void
292 vg_actions_kill (VgActions *actions)
294 VgActionsPriv *priv;
296 g_return_if_fail (actions != NULL);
297 priv = actions->priv;
299 vg_tool_view_disconnect (VG_TOOL_VIEW (priv->view));
301 if (priv->gio) {
302 g_io_channel_close (priv->gio);
303 g_io_channel_unref (priv->gio);
304 priv->watch_id = 0;
305 priv->gio = NULL;
308 if (priv->pid != (pid_t) -1) {
309 process_kill (priv->pid);
310 priv->pid = (pid_t) -1;
313 /* let's set the correct sensitive menu */
314 valgrind_set_busy_status (priv->anjuta_plugin, FALSE);
315 valgrind_update_ui (priv->anjuta_plugin);
318 void vg_actions_set_pid (VgActions *actions, pid_t pid)
320 VgActionsPriv *priv;
322 g_return_if_fail (actions != NULL);
323 priv = actions->priv;
325 priv->pid = (pid_t) pid;
329 void vg_actions_set_giochan (VgActions *actions, GIOChannel*gio)
331 VgActionsPriv *priv;
333 g_return_if_fail (actions != NULL);
334 priv = actions->priv;
336 priv->gio = gio;
338 priv->watch_id = g_io_add_watch (priv->gio, G_IO_IN | G_IO_HUP,
339 io_ready_cb, actions);