TYPE_INTEGER,
TYPE_GENERIC_RECORD,
TYPE_GENERIC_LIST,
+ TYPE_VOID,
N_BUILTIN_TYPES,
};
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
t->kind = kind;
t->type = type;
t->to = to;
+ t->target_type = TYPE_UNDEFINED;
if (from)
g_queue_push_tail (from->transitions, t);
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;
}
}
static const State *
-state_transition_text (const State *state, SType *type)
+state_transition_text (const State *state, SType *type, SType *target_type)
{
GList *list;
{
*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
*/
struct
{
+ SType target_type;
int target_id;
Instruction *target_instruction;
gpointer target_object;
{
int i;
- /* FIXME: we need to check the types here */
-
#if 0
g_print ("emfle\n");
#endif
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;
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);
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
int n_elements;
g_assert (first->kind == BEGIN);
-
+
instruction = first + 1;
n_elements = 0;
{
instruction++;
}
-
+
n_elements++;
}
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)
{
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;
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);
}
}
-#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.