Store a pointer to the root of the call tree
authorSøren Sandmann <sandmann@redhat.com>
Sat, 23 Apr 2005 23:18:42 +0000 (23:18 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Sat, 23 Apr 2005 23:18:42 +0000 (23:18 +0000)
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

ChangeLog
profile.c
sfile.c
sfile.h

index fe08e1d..e9efbcc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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
index 6efe980..97f02d3 100644 (file)
--- a/profile.c
+++ b/profile.c
@@ -81,6 +81,7 @@ create_format (void)
        sformat_new_record (
            "profile", NULL,
            sformat_new_integer ("size"),
+           sformat_new_pointer ("call_tree", &node_type),
            sformat_new_list (
                "objects", NULL,
                sformat_new_record (
@@ -152,6 +153,7 @@ profile_save (Profile                *profile,
     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);
@@ -210,6 +212,7 @@ profile_load (const char *filename, GError **err)
     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)
@@ -244,19 +247,13 @@ profile_load (const char *filename, GError **err)
        
        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);
 
diff --git a/sfile.c b/sfile.c
index dea3d27..62e7ac2 100644 (file)
--- a/sfile.c
+++ b/sfile.c
@@ -67,7 +67,6 @@ struct Transition
 struct State
 {
     GQueue *transitions;
-    guint marked : 1;     /* Used by sformat_free */
 };
 
 struct Fragment
@@ -128,14 +127,6 @@ set_invalid_content_error (GError **err, const char *format, ...)
     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,
@@ -159,6 +150,38 @@ transition_new (const char *element,
     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)
 {
@@ -188,10 +211,41 @@ sformat_new_optional (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 *
@@ -1554,6 +1608,12 @@ sfile_output_save (SFileOutput  *sfile,
 
 
 void
+sfile_input_free       (SFileInput  *file)
+{
+    /* FIXME */
+}
+
+void
 sfile_output_free (SFileOutput *sfile)
 {
     /* FIXME */
diff --git a/sfile.h b/sfile.h
index e3ec83b..b35c551 100644 (file)
--- a/sfile.h
+++ b/sfile.h
@@ -54,22 +54,29 @@ typedef guint SType;
  *
  * 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,
@@ -89,6 +96,7 @@ void     sfile_get_string       (SFileInput  *file,
 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) */