1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) James Liggett 2006 <jrliggett@cox.net>
6 * gprof-flat-profile.c is free software.
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 * 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
24 #include "gprof-flat-profile.h"
26 struct _GProfFlatProfilePriv
28 GList
*entries
; /* List of all entries */
29 GHashTable
*lookup_table
; /* Find entries by name */
33 gprof_flat_profile_init (GProfFlatProfile
*self
)
35 self
->priv
= g_new0 (GProfFlatProfilePriv
, 1);
36 self
->priv
->lookup_table
= g_hash_table_new (g_str_hash
, g_str_equal
);
40 gprof_flat_profile_finalize (GObject
*obj
)
42 GProfFlatProfile
*self
;
45 self
= (GProfFlatProfile
*) obj
;
47 g_hash_table_destroy (self
->priv
->lookup_table
);
49 current
= self
->priv
->entries
;
53 gprof_flat_profile_entry_free (current
->data
);
54 current
= g_list_next (current
);
57 g_list_free (self
->priv
->entries
);
62 gprof_flat_profile_class_init (GProfFlatProfileClass
*klass
)
64 GObjectClass
*object_class
;
66 object_class
= (GObjectClass
*) klass
;
67 object_class
->finalize
= gprof_flat_profile_finalize
;
71 get_flat_profile_fields (gchar
*buffer
)
74 gchar
*calls_field
; /* Pointer to string that begins at the calls field */
76 gint pos
; /* Where are we in the buffer? */
78 string_table
= g_new0 (gchar
*, 8); /* NULL terminated */
80 /* Get the first 3 fields */
83 for (i
= 0; i
< 3; i
++)
84 string_table
[i
] = read_to_whitespace (&buffer
[pos
], &pos
, pos
);
86 /* In some cases, uncalled functions may have empty calls, self ms/call, and
87 * total ms/call fields. */
89 /* If the next field begins with a digit, we have the fields */
90 calls_field
= strip_whitespace (&buffer
[pos
]);
92 if (g_ascii_isdigit (calls_field
[0]))
94 for (i
= 3; i
< 6; i
++)
95 string_table
[i
] = read_to_whitespace (&buffer
[pos
], &pos
, pos
);
97 string_table
[6] = strip_whitespace (&buffer
[pos
]);
99 else /* We don't have the fields; calls_field points to function name */
101 for (i
= 3; i
< 6; i
++)
102 string_table
[i
] = g_strdup ("0");
104 string_table
[6] = g_strdup (calls_field
);
107 g_free (calls_field
);
113 gprof_flat_profile_add_entry (GProfFlatProfile
*self
,
114 GProfFlatProfileEntry
*entry
)
116 self
->priv
->entries
= g_list_append (self
->priv
->entries
, entry
);
117 g_hash_table_insert (self
->priv
->lookup_table
,
118 gprof_flat_profile_entry_get_name (entry
),
123 gprof_flat_profile_get_type (void)
125 static GType obj_type
= 0;
129 static const GTypeInfo obj_info
=
131 sizeof (GProfFlatProfileClass
),
132 (GBaseInitFunc
) NULL
,
133 (GBaseFinalizeFunc
) NULL
,
134 (GClassInitFunc
) gprof_flat_profile_class_init
,
135 (GClassFinalizeFunc
) NULL
,
136 NULL
, /* class_data */
137 sizeof (GProfFlatProfile
),
139 (GInstanceInitFunc
) gprof_flat_profile_init
,
140 NULL
/* value_table */
142 obj_type
= g_type_register_static (G_TYPE_OBJECT
,
143 "GProfFlatProfile", &obj_info
, 0);
149 gprof_flat_profile_new (FILE *stream
)
151 gchar buffer
[PATH_MAX
];
154 GProfFlatProfile
*flat_profile
;
156 flat_profile
= g_object_new (GPROF_FLAT_PROFILE_TYPE
, NULL
);
158 /* Read to beginning of flat profile data */
161 /* Don't loop infinitely if we don't have any data */
162 if (!fgets (buffer
, PATH_MAX
, stream
))
165 } while (!strchr (buffer
, '%'));
167 /* Skip the second line of the column header */
168 fgets (buffer
, PATH_MAX
, stream
);
170 while (fgets (buffer
, PATH_MAX
, stream
))
172 /* If the first character is 12, that's the end of the flat profile. */
176 /* Remove the newline from the buffer */
177 length
= strlen (buffer
);
178 buffer
[length
- 1] = 0;
180 fields
= get_flat_profile_fields (buffer
);
184 gprof_flat_profile_add_entry (flat_profile
,
185 gprof_flat_profile_entry_new (fields
));
195 gprof_flat_profile_free (GProfFlatProfile
*self
)
197 g_object_unref (self
);
200 GProfFlatProfileEntry
*
201 gprof_flat_profile_get_first_entry (GProfFlatProfile
*self
, GList
**iter
)
203 *iter
= self
->priv
->entries
;
205 if (self
->priv
->entries
)
206 return GPROF_FLAT_PROFILE_ENTRY ((*iter
)->data
);
211 GProfFlatProfileEntry
*
212 gprof_flat_profile_find_entry (GProfFlatProfile
* self
, const gchar
*name
)
214 return GPROF_FLAT_PROFILE_ENTRY (g_hash_table_lookup (self
->priv
->lookup_table
,
219 gprof_flat_profile_dump (GProfFlatProfile
*self
, FILE *stream
)
222 GProfFlatProfileEntry
*entry
;
224 current
= self
->priv
->entries
;
228 entry
= GPROF_FLAT_PROFILE_ENTRY (current
->data
);
230 fprintf (stream
, "Function: %s\n",
231 gprof_flat_profile_entry_get_name (entry
));
232 fprintf (stream
, "Time: %2.2f\n",
233 gprof_flat_profile_entry_get_time_perc (entry
));
234 fprintf (stream
, "Cumulative time: %2.2f\n",
235 gprof_flat_profile_entry_get_cum_sec (entry
));
236 fprintf (stream
, "Current function time: %2.2f\n",
237 gprof_flat_profile_entry_get_self_sec (entry
));
238 fprintf (stream
, "Calls: %i\n",
239 gprof_flat_profile_entry_get_calls (entry
));
240 fprintf (stream
, "Average time: %2.2f\n",
241 gprof_flat_profile_entry_get_avg_ms (entry
));
242 fprintf (stream
, "Total time: %2.2f\n",
243 gprof_flat_profile_entry_get_total_ms (entry
));
244 fprintf (stream
, "\n");
246 current
= g_list_next (current
);