Check pointer types
authorSøren Sandmann <sandmann@redhat.com>
Sat, 23 Apr 2005 22:47:35 +0000 (22:47 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Sat, 23 Apr 2005 22:47:35 +0000 (22:47 +0000)
Sat Apr 23 18:38:46 2005  Søren Sandmann  <sandmann@redhat.com>

* sfile.c (post_process_read_instructions): Check pointer types

* sfile.c (post_process_instructions_recurse): Delete this unused function

ChangeLog
sfile.c
sfile.h

index 63577bf..fe08e1d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sat Apr 23 18:38:46 2005  Søren Sandmann  <sandmann@redhat.com>
+
+       * sfile.c (post_process_read_instructions): Check pointer types
+
+       * sfile.c (post_process_instructions_recurse): Delete this unused function
+
 Sat Apr 23 17:49:33 2005  Søren Sandmann  <sandmann@redhat.com>
 
        * sysprof-module.c (page_readable): New function to check if the
diff --git a/sfile.c b/sfile.c
index 67e3936..dea3d27 100644 (file)
--- a/sfile.c
+++ b/sfile.c
@@ -44,6 +44,7 @@ enum
     TYPE_INTEGER,
     TYPE_GENERIC_RECORD,
     TYPE_GENERIC_LIST,
+    TYPE_VOID,
     N_BUILTIN_TYPES,
 };
 
@@ -60,11 +61,13 @@ struct Transition
     TransitionKind kind;
     State *to;
     char *element;         /* for begin/end transitions */
+    SType target_type;    /* for pointer transitions */
 };
 
 struct State
 {
     GQueue *transitions;
+    guint marked : 1;     /* Used by sformat_free */
 };
 
 struct Fragment
@@ -148,6 +151,7 @@ transition_new (const char *element,
     t->kind = kind;
     t->type = type;
     t->to = to;
+    t->target_type = TYPE_UNDEFINED;
     
     if (from)
         g_queue_push_tail (from->transitions, t);
@@ -403,7 +407,12 @@ sformat_new_pointer (const char *name,
                      SType      *target_type)
 {
     Fragment *fragment = sformat_new_value (name, TYPE_POINTER);
-    /* FIXME: store the target type in the fragment */
+    Transition *value;
+
+    /* store the target type in the value transition */ 
+    value = fragment->enter->to->transitions->head->data;
+    value->target_type = define_type (target_type, TYPE_VOID);
+    
     return fragment;
 }
 
@@ -467,7 +476,7 @@ state_transition_end (const State *state, const char *element, SType *type)
 }
 
 static const State *
-state_transition_text (const State *state, SType *type)
+state_transition_text (const State *state, SType *type, SType *target_type)
 {
     GList *list;
     
@@ -479,6 +488,9 @@ state_transition_text (const State *state, SType *type)
         {
             *type = transition->type;
 
+           if (*type == TYPE_POINTER && target_type)
+               *target_type = transition->target_type;
+           
             /* There will never be more than one allowed value transition for
              * a given state
              */
@@ -520,6 +532,7 @@ struct Instruction
         
         struct
         {
+           SType target_type;
             int target_id;
             Instruction *target_instruction;
             gpointer target_object;
@@ -692,8 +705,6 @@ hook_up_pointers (SFileInput *file)
 {
     int i;
 
-    /* FIXME: we need to check the types here */
-    
 #if 0
     g_print ("emfle\n");
 #endif
@@ -852,13 +863,14 @@ handle_text (GMarkupParseContext *context,
     BuildContext *build = user_data;
     Instruction instruction;
     char *free_me;
+    SType target_type;
 
     text = free_me = g_strstrip (g_strdup (text));
 
     if (strlen (text) == 0)
         goto out;
         
-    build->state = state_transition_text (build->state, &instruction.type);
+    build->state = state_transition_text (build->state, &instruction.type, &target_type);
     if (!build->state)
     {
         int line, ch;
@@ -876,6 +888,7 @@ handle_text (GMarkupParseContext *context,
     switch (instruction.type)
     {
     case TYPE_POINTER:
+       instruction.u.pointer.target_type = target_type;
         if (!get_number (text, &instruction.u.pointer.target_id))
         {
             set_invalid_content_error (err, "Contents '%s' of pointer element is not a number", text);
@@ -929,45 +942,6 @@ free_instructions (Instruction *instructions, int n_instructions)
     g_free (instructions);
 }
 
-/* This functions counts the number of instructions in each list, and
- * matches up pointers with the lists/records they point to.
- * FIMXE: think of a better name
- */
-static Instruction *
-post_process_instructions_recurse (Instruction *first, GHashTable *instructions_by_id, GError **err)
-{
-    Instruction *instruction;
-    int n_elements;
-
-    g_assert (first->kind == BEGIN);
-    
-    instruction = first + 1;
-
-    n_elements = 0;
-    while (instruction->kind != END)
-    {
-        if (instruction->kind == BEGIN)
-        {
-            instruction = post_process_instructions_recurse (instruction, instructions_by_id, err);
-            if (!instruction)
-                return NULL;
-        }
-        else
-        {
-            instruction++;
-        }
-        
-        n_elements++;
-    }
-
-    first->u.begin.n_elements = n_elements;
-    first->u.begin.end_instruction = instruction;
-
-    instruction->u.end.begin_instruction = first;
-    
-    return instruction + 1;
-}
-        
 /* This functions makes end instructions point to the corresponding
  * begin instructions, and counts the number of instructions
  * contained in a begin/end pair
@@ -979,7 +953,7 @@ process_instruction_pairs (Instruction *first)
     int n_elements;
 
     g_assert (first->kind == BEGIN);
-    
+
     instruction = first + 1;
 
     n_elements = 0;
@@ -995,7 +969,7 @@ process_instruction_pairs (Instruction *first)
         {
             instruction++;
         }
-        
+
         n_elements++;
     }
 
@@ -1003,10 +977,10 @@ process_instruction_pairs (Instruction *first)
     first->u.begin.end_instruction = instruction;
 
     instruction->u.end.begin_instruction = first;
-    
+
     return instruction + 1;
 }
-        
+      
 static gboolean
 post_process_read_instructions (Instruction *instructions, int n_instructions, GError **err)
 {
@@ -1049,11 +1023,21 @@ post_process_read_instructions (Instruction *instructions, int n_instructions, G
                 
                 if (target)
                 {
-                    instruction->u.pointer.target_instruction = target;
+                   if (instruction->u.pointer.target_type == target->type)
+                   {
+                       instruction->u.pointer.target_instruction = target;
+                   }
+                   else
+                   {
+                       set_invalid_content_error (err, "Id %d references an element of the wrong type",
+                                                  instruction->u.pointer.target_id);
+                       retval = FALSE;
+                       break;
+                   }
                 }
                 else
                 {
-                    set_invalid_content_error (err, "Id %d doesn't reference any record or list\n",
+                    set_invalid_content_error (err, "Id %d doesn't reference any record or list",
                                                instruction->u.pointer.target_id);
                     retval = FALSE;
                     break;
@@ -1243,7 +1227,7 @@ sfile_check_value (SFileOutput *file,
     file->state = state_transition_begin (file->state, name, &tmp_type);
     g_return_if_fail (file->state && tmp_type == type);
 
-    file->state = state_transition_text (file->state, &type);
+    file->state = state_transition_text (file->state, &type, NULL);
     g_return_if_fail (file->state && tmp_type == type);
     
     file->state = state_transition_end (file->state, name, &type);
@@ -1552,10 +1536,6 @@ sfile_output_save (SFileOutput  *sfile,
         }
     }
 
-#if 0
-    g_print (output->str);
-#endif
-
     /* FIMXE: bz2 compressing the output is probably
      * interesting at some point. For now just make sure
      * it works without actually using it.
diff --git a/sfile.h b/sfile.h
index 042fe8f..e3ec83b 100644 (file)
--- a/sfile.h
+++ b/sfile.h
@@ -42,7 +42,10 @@ typedef guint SType;
  *  For formats consider:
  *
  *   Format *format_new (void);
- *   void format_new_record (Format *f, Record *r);
+ *   void format_set_record (Format *f, Content *r);
+ *   Content *new_record (Content *c1, ...);
+ *
+ *   List *format_new_list (Format *f
  *   
  *
  * Consider adding optional elements: