1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 * gprof-call-graph-block.c
4 * Copyright (C) James Liggett 2006 <jrliggett@cox.net>
6 * gprof-call-graph-block.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-call-graph-block.h"
26 struct _GProfCallGraphBlockPriv
28 GProfCallGraphBlockEntry
*primary_entry
; /* Function this block refers to */
29 GList
*parents
; /* Functions that call this one */
30 GList
*children
; /* Function that this one calls */
31 GHashTable
*lookup_set
; /* Used to determine if this
32 * function is recursive */
36 gprof_call_graph_block_init (GProfCallGraphBlock
*self
)
38 self
->priv
= g_new0 (GProfCallGraphBlockPriv
, 1);
40 self
->priv
->lookup_set
= g_hash_table_new (g_str_hash
, g_str_equal
);
44 gprof_call_graph_block_finalize (GObject
*obj
)
46 GProfCallGraphBlock
*self
;
49 self
= (GProfCallGraphBlock
*) obj
;
51 gprof_call_graph_block_entry_free (self
->priv
->primary_entry
);
53 current
= self
->priv
->parents
;
57 gprof_call_graph_block_entry_free (GPROF_CALL_GRAPH_BLOCK_ENTRY (current
->data
));
58 current
= g_list_next (current
);
61 g_list_free (self
->priv
->parents
);
63 current
= self
->priv
->children
;
67 gprof_call_graph_block_entry_free (GPROF_CALL_GRAPH_BLOCK_ENTRY (current
->data
));
68 current
= g_list_next (current
);
71 g_list_free (self
->priv
->children
);
73 g_hash_table_destroy (self
->priv
->lookup_set
);
79 gprof_call_graph_block_class_init (GProfCallGraphBlockClass
*klass
)
81 GObjectClass
*object_class
;
83 object_class
= (GObjectClass
*) klass
;
85 object_class
->finalize
= gprof_call_graph_block_finalize
;
89 gprof_call_graph_block_get_type (void)
91 static GType obj_type
= 0;
95 static const GTypeInfo obj_info
=
97 sizeof (GProfCallGraphBlockClass
),
99 (GBaseFinalizeFunc
) NULL
,
100 (GClassInitFunc
) gprof_call_graph_block_class_init
,
101 (GClassFinalizeFunc
) NULL
,
102 NULL
, /* class_data */
103 sizeof (GProfCallGraphBlock
),
105 (GInstanceInitFunc
) gprof_call_graph_block_init
,
106 NULL
/* value_table */
108 obj_type
= g_type_register_static (G_TYPE_OBJECT
,
109 "GProfCallGraphBlock", &obj_info
,
115 GProfCallGraphBlock
*
116 gprof_call_graph_block_new (void)
118 return g_object_new (GPROF_CALL_GRAPH_BLOCK_TYPE
, NULL
);
122 gprof_call_graph_block_free (GProfCallGraphBlock
*self
)
124 g_object_unref (self
);
128 gprof_call_graph_block_add_primary_entry (GProfCallGraphBlock
*self
,
129 GProfCallGraphBlockEntry
*entry
)
131 if (!self
->priv
->primary_entry
)
132 self
->priv
->primary_entry
= entry
;
136 gprof_call_graph_block_add_parent_entry (GProfCallGraphBlock
*self
,
137 GProfCallGraphBlockEntry
*entry
)
139 self
->priv
->parents
= g_list_append (self
->priv
->parents
, entry
);
140 g_hash_table_insert (self
->priv
->lookup_set
,
141 gprof_call_graph_block_entry_get_name (entry
), NULL
);
145 gprof_call_graph_block_add_child_entry (GProfCallGraphBlock
*self
,
146 GProfCallGraphBlockEntry
*entry
)
148 self
->priv
->children
= g_list_append (self
->priv
->children
, entry
);
149 g_hash_table_insert (self
->priv
->lookup_set
,
150 gprof_call_graph_block_entry_get_name (entry
), NULL
);
153 GProfCallGraphBlockEntry
*
154 gprof_call_graph_block_get_primary_entry (GProfCallGraphBlock
*self
)
156 return self
->priv
->primary_entry
;
160 gprof_call_graph_block_has_parents (GProfCallGraphBlock
*self
)
162 return (self
->priv
->parents
!= NULL
);
166 gprof_call_graph_block_has_children (GProfCallGraphBlock
*self
)
168 return (self
->priv
->children
!= NULL
);
171 GProfCallGraphBlockEntry
*
172 gprof_call_graph_block_get_first_child (GProfCallGraphBlock
*self
,
175 *iter
= self
->priv
->children
;
177 if (self
->priv
->children
)
178 return GPROF_CALL_GRAPH_BLOCK_ENTRY ((*iter
)->data
);
183 GProfCallGraphBlockEntry
*
184 gprof_call_graph_block_get_first_parent (GProfCallGraphBlock
*self
,
187 *iter
= self
->priv
->parents
;
189 if (self
->priv
->parents
)
190 return GPROF_CALL_GRAPH_BLOCK_ENTRY ((*iter
)->data
);
196 gprof_call_graph_block_is_recursive (GProfCallGraphBlock
*self
)
200 name
= gprof_call_graph_block_entry_get_name (self
->priv
->primary_entry
);
202 /* Determine if this block refers to a recursive function.
203 * Recursive blocks are those whose primary entry also is a parent
204 * or child of the primary. */
205 return g_hash_table_lookup_extended (self
->priv
->lookup_set
, name
, NULL
,
209 GProfCallGraphBlock
*
210 gprof_call_graph_block_get_next (GList
*current_iter
, GList
**next_iter
)
212 *next_iter
= g_list_next (current_iter
);
215 return GPROF_CALL_GRAPH_BLOCK ((*next_iter
)->data
);