+Sat Apr 23 19:12:52 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * profile.c: Store a pointer to the root of the call tree
+
+ * profile.c (profile_load): Call sfile_input_free()
+
+ * sfile.c (sformat_free): Implement this function
+
Sat Apr 23 18:38:46 2005 Søren Sandmann <sandmann@redhat.com>
* sfile.c (post_process_read_instructions): Check pointer types
sformat_new_record (
"profile", NULL,
sformat_new_integer ("size"),
+ sformat_new_pointer ("call_tree", &node_type),
sformat_new_list (
"objects", NULL,
sformat_new_record (
sfile_begin_add_record (output, "profile");
sfile_add_integer (output, "size", profile->size);
+ sfile_add_pointer (output, "call_tree", profile->call_tree);
sfile_begin_add_list (output, "objects");
g_hash_table_foreach (profile->nodes_by_object, add_object, output);
sfile_begin_get_record (input, "profile");
sfile_get_integer (input, "size", &profile->size);
+ sfile_get_pointer (input, "call_tree", &profile->call_tree);
n = sfile_begin_get_list (input, "objects");
for (i = 0; i < n; ++i)
sfile_end_get (input, "node", node);
- if (!profile->call_tree)
- profile->call_tree = node;
-
g_assert (node->siblings != (void *)0x11);
}
sfile_end_get (input, "nodes", NULL);
sfile_end_get (input, "profile", NULL);
sformat_free (format);
-
- /* FIXME: why don't we just store the root node? */
- while (profile->call_tree && profile->call_tree->parent)
- profile->call_tree = profile->call_tree->parent;
+ sfile_input_free (input);
make_hash_table (profile->call_tree, profile->nodes_by_object);
struct State
{
GQueue *transitions;
- guint marked : 1; /* Used by sformat_free */
};
struct Fragment
va_end (args);
}
-static State *
-state_new (void)
-{
- State *state = g_new (State, 1);
- state->transitions = g_queue_new ();
- return state;
-}
-
static Transition *
transition_new (const char *element,
TransitionKind kind,
return t;
}
+static void
+transition_free (Transition *transition)
+{
+ if (transition->element)
+ g_free (transition->element);
+ g_free (transition);
+}
+
+static State *
+state_new (void)
+{
+ State *state = g_new (State, 1);
+ state->transitions = g_queue_new ();
+ return state;
+}
+
+static void
+state_free (State *state)
+{
+ GList *list;
+
+ for (list = state->transitions->head; list; list = list->next)
+ {
+ Transition *transition = list->data;
+
+ transition_free (transition);
+ }
+
+ g_queue_free (state->transitions);
+ g_free (state);
+}
+
SFormat *
sformat_new (gpointer f)
{
}
#endif
+static void
+add_state (State *state, GHashTable *seen_states, GQueue *todo_list)
+{
+ if (!g_hash_table_lookup (seen_states, state))
+ {
+ g_hash_table_insert (seen_states, state, state);
+ g_queue_push_tail (todo_list, state);
+ }
+}
+
void
sformat_free (SFormat *format)
{
- /* FIXME */
+ GHashTable *seen_states = g_hash_table_new (g_direct_hash, g_direct_equal);
+ GQueue *todo_list = g_queue_new ();
+
+ add_state (format->begin, seen_states, todo_list);
+ add_state (format->end, seen_states, todo_list);
+
+ while (!g_queue_is_empty (todo_list))
+ {
+ GList *list;
+ State *state = g_queue_pop_head (todo_list);
+
+ for (list = state->transitions->head; list != NULL; list = list->next)
+ {
+ Transition *transition = list->data;
+ add_state (transition->to, seen_states, todo_list);
+ }
+
+ state_free (state);
+ }
+
+ g_hash_table_destroy (seen_states);
+ g_queue_free (todo_list);
}
static GQueue *
void
+sfile_input_free (SFileInput *file)
+{
+ /* FIXME */
+}
+
+void
sfile_output_free (SFileOutput *sfile)
{
/* FIXME */
*
* enums, optionals, selections, empties
*
+ *
+ *==============================================
+ * Also think about versioning - apps will want to be able to read and write
+ * different versions of the format, and they want to be able to sniff the
+ * format + version
+ *
*/
/* - Describing Types - */
-SFormat *sformat_new (gpointer f);
-gpointer sformat_new_record (const char *name,
- SType *type,
- gpointer content,
- ...);
-gpointer sformat_new_list (const char *name,
- SType *type,
- gpointer content);
-gpointer sformat_new_pointer (const char *name,
- SType *target_type);
-gpointer sformat_new_integer (const char *name);
-gpointer sformat_new_string (const char *name);
-void sformat_free (SFormat *format);
+SFormat *sformat_new (gpointer f);
+gpointer sformat_new_record (const char *name,
+ SType *type,
+ gpointer content,
+ ...);
+gpointer sformat_new_list (const char *name,
+ SType *type,
+ gpointer content);
+gpointer sformat_new_pointer (const char *name,
+ SType *target_type);
+gpointer sformat_new_integer (const char *name);
+gpointer sformat_new_string (const char *name);
+void sformat_free (SFormat *format);
+
/* - Reading - */
SFileInput * sfile_load (const char *filename,
void sfile_end_get (SFileInput *file,
const char *name,
gpointer object);
+void sfile_input_free (SFileInput *file);
#if 0
/* incremental loading (worth considering at least) */