Updated Spanish translation
[anjuta-git-plugin.git] / plugins / valgrind / vggeneralprefs.c
blobfde32bced433e67926970067ece1269e0417ebb9
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Authors: Jeffrey Stedfast <fejj@ximian.com>
4 * Copyright (C) Massimo Cora' 2005 <maxcvs@gmail.com>
6 * Copyright 2003 Ximian, Inc. (www.ximian.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 #include <limits.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <string.h>
37 #include <gconf/gconf-client.h>
38 #include <libgnome/gnome-i18n.h>
39 #include <libgnomevfs/gnome-vfs.h>
40 #include <libanjuta/anjuta-debug.h>
42 #include "vggeneralprefs.h"
45 #define DEMANGLE_KEY "/apps/anjuta/valgrind/general/demangle"
46 #define NUM_CALLERS_KEY "/apps/anjuta/valgrind/general/num-callers"
47 #define ERROR_LIMIT_KEY "/apps/anjuta/valgrind/general/error-limit"
48 #define SLOPPY_MALLOC_KEY "/apps/anjuta/valgrind/general/sloppy-malloc"
49 #define TRACE_CHILDREN_KEY "/apps/anjuta/valgrind/general/trace-children"
50 #define TRACK_FDS_KEY "/apps/anjuta/valgrind/general/track-fds"
51 #define TIME_STAMP_KEY "/apps/anjuta/valgrind/general/time-stamp"
52 #define RUN_LIBC_FREERES_KEY "/apps/anjuta/valgrind/general/run-libc-freeres"
53 #define SUPPRESSIONS_KEY "/apps/anjuta/valgrind/general/suppressions"
55 #define SUPPRESSIONS_DEFAULT_FILE ".anjuta/valgrind.supp"
57 static void vg_general_prefs_class_init (VgGeneralPrefsClass *klass);
58 static void vg_general_prefs_init (VgGeneralPrefs *prefs);
59 static void vg_general_prefs_destroy (GtkObject *obj);
60 static void vg_general_prefs_finalize (GObject *obj);
62 static void general_prefs_apply (VgToolPrefs *prefs);
63 static void general_prefs_get_argv (VgToolPrefs *prefs, const char *tool, GPtrArray *argv);
66 static VgToolPrefsClass *parent_class = NULL;
69 GType
70 vg_general_prefs_get_type (void)
72 static GType type = 0;
74 if (!type) {
75 static const GTypeInfo info = {
76 sizeof (VgGeneralPrefsClass),
77 NULL, /* base_class_init */
78 NULL, /* base_class_finalize */
79 (GClassInitFunc) vg_general_prefs_class_init,
80 NULL, /* class_finalize */
81 NULL, /* class_data */
82 sizeof (VgGeneralPrefs),
83 0, /* n_preallocs */
84 (GInstanceInitFunc) vg_general_prefs_init,
87 type = g_type_register_static (VG_TYPE_TOOL_PREFS, "VgGeneralPrefs", &info, 0);
90 return type;
93 static void
94 vg_general_prefs_class_init (VgGeneralPrefsClass *klass)
96 GObjectClass *object_class = G_OBJECT_CLASS (klass);
97 GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
98 VgToolPrefsClass *tool_class = VG_TOOL_PREFS_CLASS (klass);
100 parent_class = g_type_class_ref (VG_TYPE_TOOL_PREFS);
102 object_class->finalize = vg_general_prefs_finalize;
103 gtk_object_class->destroy = vg_general_prefs_destroy;
105 /* virtual methods */
106 tool_class->apply = general_prefs_apply;
107 tool_class->get_argv = general_prefs_get_argv;
111 static void
112 toggle_button_toggled (GtkToggleButton *toggle, const char *key)
114 GConfClient *gconf;
115 gboolean bool;
117 gconf = gconf_client_get_default ();
119 bool = gtk_toggle_button_get_active (toggle);
120 gconf_client_set_bool (gconf, key, bool, NULL);
122 g_object_unref (gconf);
125 static gboolean
126 spin_focus_out (GtkSpinButton *spin, GdkEventFocus *event, const char *key)
128 GConfClient *gconf;
129 int num;
131 gconf = gconf_client_get_default ();
133 num = gtk_spin_button_get_value_as_int (spin);
134 gconf_client_set_int (gconf, key, num, NULL);
136 g_object_unref (gconf);
138 return FALSE;
141 static void
142 file_entry_changed (GtkFileChooser *chooser, const char *key)
144 GConfClient *gconf;
145 gchar *str;
147 gconf = gconf_client_get_default ();
149 str = gtk_file_chooser_get_filename (chooser);
151 DEBUG_PRINT ("str is %s key is %s", str, key);
153 gconf_client_set_string (gconf, key, str ? str : "", NULL);
154 g_free (str);
156 g_object_unref (gconf);
159 static void
160 vg_general_prefs_init (VgGeneralPrefs *prefs)
162 GtkWidget *vbox, *hbox, *label;
163 GConfClient *gconf;
164 GError *err = NULL;
165 GtkWidget *widget;
166 gboolean bool;
167 gchar *str_file;
168 int num;
170 gconf = gconf_client_get_default ();
172 VG_TOOL_PREFS (prefs)->label = _("General");
174 vbox = GTK_WIDGET (prefs);
175 gtk_box_set_spacing (GTK_BOX (vbox), 6);
177 bool = gconf_client_get_bool (gconf, DEMANGLE_KEY, NULL);
178 widget = gtk_check_button_new_with_label (_("Demangle c++ symbol names"));
179 g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_toggled), DEMANGLE_KEY);
180 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), bool);
181 prefs->demangle = GTK_TOGGLE_BUTTON (widget);
182 gtk_widget_show (widget);
183 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
185 hbox = gtk_hbox_new (FALSE, 6);
186 label = gtk_label_new (_("Show"));
187 gtk_widget_show (label);
188 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
189 num = gconf_client_get_int (gconf, NUM_CALLERS_KEY, NULL);
190 widget = gtk_spin_button_new_with_range (0, (gdouble) 1024, 1);
191 gtk_widget_show (widget);
192 prefs->num_callers = GTK_SPIN_BUTTON (widget);
193 gtk_spin_button_set_digits (prefs->num_callers, 0);
194 gtk_spin_button_set_numeric (prefs->num_callers, TRUE);
195 gtk_spin_button_set_value (prefs->num_callers, (gdouble) num);
196 g_signal_connect (widget, "focus-out-event", G_CALLBACK (spin_focus_out), NUM_CALLERS_KEY);
197 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
198 label = gtk_label_new (_("callers in stack trace"));
199 gtk_widget_show (label);
200 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
201 gtk_widget_show (hbox);
202 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
204 bool = gconf_client_get_bool (gconf, ERROR_LIMIT_KEY, NULL);
205 widget = gtk_check_button_new_with_label (_("Stop showing errors if there are too many"));
206 g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_toggled), ERROR_LIMIT_KEY);
207 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), bool);
208 prefs->error_limit = GTK_TOGGLE_BUTTON (widget);
209 gtk_widget_show (widget);
210 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
212 bool = gconf_client_get_bool (gconf, SLOPPY_MALLOC_KEY, NULL);
213 widget = gtk_check_button_new_with_label (_("Round malloc sizes to next word"));
214 g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_toggled), SLOPPY_MALLOC_KEY);
215 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), bool);
216 prefs->sloppy_malloc = GTK_TOGGLE_BUTTON (widget);
217 gtk_widget_show (widget);
218 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
220 bool = gconf_client_get_bool (gconf, TRACE_CHILDREN_KEY, NULL);
221 widget = gtk_check_button_new_with_label (_("Trace any child processes forked off by the program being debugged"));
222 g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_toggled), TRACE_CHILDREN_KEY);
223 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), bool);
224 prefs->trace_children = GTK_TOGGLE_BUTTON (widget);
225 gtk_widget_show (widget);
226 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
228 bool = gconf_client_get_bool (gconf, TRACK_FDS_KEY, NULL);
229 widget = gtk_check_button_new_with_label (_("Track open file descriptors"));
230 g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_toggled), TRACK_FDS_KEY);
231 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), bool);
232 prefs->track_fds = GTK_TOGGLE_BUTTON (widget);
233 gtk_widget_show (widget);
234 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
236 bool = gconf_client_get_bool (gconf, TIME_STAMP_KEY, NULL);
237 widget = gtk_check_button_new_with_label (_("Add time stamps to log messages"));
238 g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_toggled), TIME_STAMP_KEY);
239 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), bool);
240 prefs->time_stamp = GTK_TOGGLE_BUTTON (widget);
241 gtk_widget_show (widget);
242 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
244 bool = gconf_client_get_bool (gconf, RUN_LIBC_FREERES_KEY, NULL);
245 widget = gtk_check_button_new_with_label (_("Call __libc_freeres() at exit before checking for memory leaks"));
246 g_signal_connect (widget, "toggled", G_CALLBACK (toggle_button_toggled), RUN_LIBC_FREERES_KEY);
247 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), bool);
248 prefs->run_libc_freeres = GTK_TOGGLE_BUTTON (widget);
249 gtk_widget_show (widget);
250 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
252 hbox = gtk_hbox_new (FALSE, 6);
253 label = gtk_label_new (_("Suppressions File:"));
254 gtk_widget_show (label);
255 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
257 if (!(str_file = gconf_client_get_string (gconf, SUPPRESSIONS_KEY, &err)) || err != NULL) {
258 int fd;
260 str_file = g_build_filename (g_get_home_dir (), SUPPRESSIONS_DEFAULT_FILE, NULL);
261 if ((fd = open (str_file, O_WRONLY | O_CREAT, 0666)) == -1) {
262 g_free (str_file);
263 str_file = NULL;
264 } else {
265 close (fd);
268 g_clear_error (&err);
272 widget =
273 gtk_file_chooser_button_new (_("Choose Valgrind Suppressions File..."),
274 GTK_FILE_CHOOSER_ACTION_OPEN);
276 if ( gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (widget), str_file) == FALSE )
277 DEBUG_PRINT ("error: could not select file uri with gtk_file_chooser_select_filename ()");
279 /* grab every change in file selection */
280 g_signal_connect (widget, "selection-changed", G_CALLBACK (file_entry_changed), SUPPRESSIONS_KEY);
282 gtk_widget_show (widget);
283 gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
285 gtk_widget_show (hbox);
286 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
288 g_object_unref (gconf);
291 static void
292 vg_general_prefs_finalize (GObject *obj)
294 G_OBJECT_CLASS (parent_class)->finalize (obj);
297 static void
298 vg_general_prefs_destroy (GtkObject *obj)
300 GTK_OBJECT_CLASS (parent_class)->destroy (obj);
304 static void
305 general_prefs_apply (VgToolPrefs *prefs)
311 enum {
312 ARG_TYPE_BOOL,
313 ARG_TYPE_INT,
314 ARG_TYPE_STRING
317 static struct {
318 const char *key;
319 const char *arg;
320 char *buf;
321 int type;
322 int dval;
323 } general_args[] = {
324 { DEMANGLE_KEY, "--demangle", NULL, ARG_TYPE_BOOL, 1 },
325 { NUM_CALLERS_KEY, "--num-callers", NULL, ARG_TYPE_INT, 4 },
326 { ERROR_LIMIT_KEY, "--error-limit", NULL, ARG_TYPE_BOOL, 1 },
327 { SLOPPY_MALLOC_KEY, "--sloppy-malloc", NULL, ARG_TYPE_BOOL, 0 },
328 { TRACE_CHILDREN_KEY, "--trace-children", NULL, ARG_TYPE_BOOL, 0 },
329 { TRACK_FDS_KEY, "--track-fds", NULL, ARG_TYPE_BOOL, 0 },
330 { TIME_STAMP_KEY, "--time-stamp", NULL, ARG_TYPE_BOOL, 0 },
331 { RUN_LIBC_FREERES_KEY, "--run-libc-freeres", NULL, ARG_TYPE_BOOL, 0 },
332 { SUPPRESSIONS_KEY, "--suppressions", NULL, ARG_TYPE_STRING, 0 },
335 static void
336 general_prefs_get_argv (VgToolPrefs *prefs, const char *tool, GPtrArray *argv)
338 GConfClient *gconf;
339 int bool, num, i;
340 char *str;
342 gconf = gconf_client_get_default ();
344 g_ptr_array_add (argv, "--alignment=8");
346 for (i = 0; i < G_N_ELEMENTS (general_args); i++) {
347 const char *arg = general_args[i].arg;
348 const char *key = general_args[i].key;
349 struct stat st;
351 g_free (general_args[i].buf);
352 if (general_args[i].type == ARG_TYPE_INT) {
353 num = gconf_client_get_int (gconf, key, NULL);
354 if (num == general_args[i].dval)
355 continue;
357 general_args[i].buf = g_strdup_printf ("%s=%d", arg, num);
358 } else if (general_args[i].type == ARG_TYPE_BOOL) {
359 bool = gconf_client_get_bool (gconf, key, NULL) ? 1 : 0;
360 if (bool == general_args[i].dval)
361 continue;
363 general_args[i].buf = g_strdup_printf ("%s=%s", arg, bool ? "yes" : "no");
364 } else {
365 if (!(str = gconf_client_get_string (gconf, key, NULL)) || *str == '\0') {
366 general_args[i].buf = NULL;
367 g_free (str);
368 continue;
371 if (g_str_equal (general_args[i].key, SUPPRESSIONS_KEY) &&
372 (stat (str, &st) == -1 || !S_ISREG (st.st_mode))) {
373 general_args[i].buf = NULL;
374 g_free (str);
375 continue;
378 general_args[i].buf = g_strdup_printf ("%s=%s", arg, str);
379 g_free (str);
382 g_ptr_array_add (argv, general_args[i].buf);
385 g_object_unref (gconf);