1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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.
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.
25 #include <sys/types.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
{
56 AnjutaValgrindPlugin
*anjuta_plugin
; /* mainly for valgrind_update_ui () */
57 ValgrindPluginPrefs
**prefs
;
62 vg_actions_get_type (void)
64 static GType type
= 0;
67 static const GTypeInfo our_info
= {
68 sizeof (VgActionsClass
),
71 (GClassInitFunc
)vg_actions_class_init
,
76 (GInstanceInitFunc
)vg_actions_init
,
79 type
= g_type_register_static(G_TYPE_OBJECT
,
80 "VgActions", &our_info
, 0);
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
;
96 vg_actions_init(VgActions
*obj
)
99 obj
->priv
= g_new0(VgActionsPriv
, 1);
110 priv
->pid
= (pid_t
) -1;
116 vg_actions_finalize(GObject
*object
)
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
;
130 G_OBJECT_CLASS(parent_class
)->finalize(object
);
134 vg_actions_new (AnjutaValgrindPlugin
*anjuta_plugin
,
135 ValgrindPluginPrefs
**prefs
, GtkWidget
*vg_default_view
)
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
));
159 io_ready_cb (GIOChannel
*gio
, GIOCondition condition
, gpointer user_data
)
161 VgActions
*actions
= user_data
;
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
);
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
);
187 check_valgrind_binary()
190 gchar
*str_valgrind_file
;
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
);
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."),
209 g_free (str_valgrind_file
);
213 g_free (str_valgrind_file
);
218 vg_actions_run (VgActions
*actions
, gchar
* prg_to_debug
, gchar
* tool
, GError
**err
)
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 ())
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."));
246 if (pipe (logfd
) == -1) {
247 anjuta_util_dialog_error (NULL
,
248 _("Could not get the right pipe for the process."));
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) {
276 g_ptr_array_free (args
, TRUE
);
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
);
292 vg_actions_kill (VgActions
*actions
)
296 g_return_if_fail (actions
!= NULL
);
297 priv
= actions
->priv
;
299 vg_tool_view_disconnect (VG_TOOL_VIEW (priv
->view
));
302 g_io_channel_close (priv
->gio
);
303 g_io_channel_unref (priv
->gio
);
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
)
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
)
333 g_return_if_fail (actions
!= NULL
);
334 priv
= actions
->priv
;
338 priv
->watch_id
= g_io_add_watch (priv
->gio
, G_IO_IN
| G_IO_HUP
,
339 io_ready_cb
, actions
);