Patch from James Liggett <jrliggett@cox.net>:
[anjuta-git-plugin.git] / plugins / profiler / gprof-profile-data.c
blob1470118eab012a935aee0f768dd0a8a452f64d4a
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * gprof-profile-data.c
4 * Copyright (C) James Liggett 2006 <jrliggett@cox.net>
5 *
6 * gprof-profile-data.c is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2, or (at your option) any later version.
12 * plugin.c is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 * See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with plugin.c. See the file "COPYING". If not,
19 * write to: The Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 #include <libgnomevfs/gnome-vfs-mime.h>
25 #include "gprof-profile-data.h"
27 struct _GProfProfileDataPriv
29 GProfFlatProfile *flat_profile;
30 GProfCallGraph *call_graph;
33 static void
34 gprof_profile_data_init (GProfProfileData *self)
36 self->priv = g_new0 (GProfProfileDataPriv, 1);
39 static void
40 gprof_profile_data_finalize (GObject *obj)
42 GProfProfileData *self;
44 self = (GProfProfileData *) obj;
46 if (self->priv->flat_profile)
47 gprof_flat_profile_free (self->priv->flat_profile);
49 if (self->priv->call_graph)
50 gprof_call_graph_free (self->priv->call_graph);
52 g_free (self->priv);
55 static void
56 gprof_profile_data_class_init (GProfProfileDataClass *klass)
58 GObjectClass *object_class;
60 object_class = (GObjectClass *) klass;
62 object_class->finalize = gprof_profile_data_finalize;
65 GType
66 gprof_profile_data_get_type ()
68 static GType obj_type = 0;
70 if (!obj_type)
72 static const GTypeInfo obj_info =
74 sizeof (GProfProfileDataClass),
75 (GBaseInitFunc) NULL,
76 (GBaseFinalizeFunc) NULL,
77 (GClassInitFunc) gprof_profile_data_class_init,
78 (GClassFinalizeFunc) NULL,
79 NULL, /* class_self */
80 sizeof (GProfProfileData),
81 0, /* n_preallocs */
82 (GInstanceInitFunc) gprof_profile_data_init,
83 NULL /* value_table */
85 obj_type = g_type_register_static (G_TYPE_OBJECT,
86 "GProfProfileData", &obj_info, 0);
88 return obj_type;
91 GProfProfileData *
92 gprof_profile_data_new ()
94 return g_object_new (GPROF_PROFILE_DATA_TYPE, NULL);;
97 void
98 gprof_profile_data_free (GProfProfileData *self)
100 g_object_unref (self);
103 gboolean
104 gprof_profile_data_init_profile (GProfProfileData *self, gchar *path,
105 GPtrArray *options)
107 gint stdout_pipe;
108 gint i;
109 FILE *stdout_stream;
110 gchar *program_dir;
111 gchar *gmon_out_path;
112 GPtrArray *gprof_args;
113 gchar *mime_type;
114 gboolean is_libtool_target = FALSE;
115 GPid gprof_pid;
116 gint gprof_status;
118 /* Determine target mime type */
119 mime_type = gnome_vfs_get_mime_type (path);
120 if (strcmp (mime_type, "application/x-shellscript") == 0)
121 is_libtool_target = TRUE;
122 g_free (mime_type);
124 /* Run gprof with -b given the path to a program run with profiling */
126 gprof_args = g_ptr_array_sized_new ((options->len - 1) + 7);
127 if (is_libtool_target)
129 g_ptr_array_add (gprof_args, "libtool");
130 g_ptr_array_add (gprof_args, "--mode=execute");
132 g_ptr_array_add (gprof_args, "gprof");
133 g_ptr_array_add (gprof_args, "-b");
135 /* Add options */
137 for (i = 0; i < options->len - 1; i++)
138 g_ptr_array_add (gprof_args, g_ptr_array_index (options, i));
140 g_ptr_array_add (gprof_args, path);
142 /* Also give the path of the gmon.out file */
144 program_dir = g_path_get_dirname (path);
145 gmon_out_path = g_build_filename (program_dir, "gmon.out", NULL);
146 g_ptr_array_add (gprof_args, gmon_out_path);
147 g_ptr_array_add (gprof_args, NULL);
149 g_spawn_async_with_pipes (NULL, (gchar **) gprof_args->pdata,
150 NULL,
151 G_SPAWN_SEARCH_PATH |
152 G_SPAWN_DO_NOT_REAP_CHILD |
153 G_SPAWN_STDERR_TO_DEV_NULL,
154 NULL, NULL, &gprof_pid, NULL, &stdout_pipe,
155 NULL, NULL);
157 g_ptr_array_free (gprof_args, TRUE);
158 g_free (gmon_out_path);
159 g_free (program_dir);
161 stdout_stream = fdopen (stdout_pipe, "r");
163 if (self->priv->flat_profile)
164 gprof_flat_profile_free (self->priv->flat_profile);
166 self->priv->flat_profile = gprof_flat_profile_new (stdout_stream);
168 if (self->priv->call_graph)
169 gprof_call_graph_free (self->priv->call_graph);
171 self->priv->call_graph = gprof_call_graph_new (stdout_stream,
172 self->priv->flat_profile);
174 fclose (stdout_stream);
175 close (stdout_pipe);
177 waitpid (gprof_pid, &gprof_status, 0);
178 g_spawn_close_pid (gprof_pid);
180 if (WIFEXITED (gprof_status) && WEXITSTATUS (gprof_status) != 0)
181 return FALSE;
183 return TRUE;
186 GProfFlatProfile *
187 gprof_profile_data_get_flat_profile (GProfProfileData *self)
189 return self->priv->flat_profile;
192 GProfCallGraph *
193 gprof_profile_data_get_call_graph (GProfProfileData *self)
195 return self->priv->call_graph;
198 gboolean
199 gprof_profile_data_has_data (GProfProfileData *self)
201 return (self->priv->flat_profile != NULL) &&
202 (self->priv->call_graph != NULL);