Write this function.

Thu Mar  3 23:48:13 2005  Soeren Sandmann  <sandmann@redhat.com>

	* profile.c (profile_load): Write this function.

	* sfile.c: Add support for user defined record and list types.
	Simplify logic a lot.
This commit is contained in:
Soeren Sandmann
2005-03-04 04:48:40 +00:00
committed by Søren Sandmann Pedersen
parent de4b3c076d
commit 466b093348
4 changed files with 213 additions and 123 deletions

View File

@ -1,3 +1,10 @@
Thu Mar 3 23:48:13 2005 Soeren Sandmann <sandmann@redhat.com>
* profile.c (profile_load): Write this function.
* sfile.c: Add support for user defined record and list types.
Simplify logic a lot.
Wed Mar 2 23:39:50 2005 Soeren Sandmann <sandmann@redhat.com> Wed Mar 2 23:39:50 2005 Soeren Sandmann <sandmann@redhat.com>
* profile.[ch], sfile.[ch]: Experiment with a * profile.[ch], sfile.[ch]: Experiment with a

View File

@ -55,21 +55,20 @@ struct Profile
static SFormat * static SFormat *
create_format (void) create_format (void)
{ {
#if 0
SType object_type = 0; SType object_type = 0;
SType node_type = 0; SType node_type = 0;
return sformat_new ( return sformat_new (
sformat_new_record ( sformat_new_record (
"profile", "profile",
sformat_new_integer ("size", NULL), sformat_new_integer ("size"),
sformat_new_list ( sformat_new_list (
"objects", NULL, "objects", NULL,
sformat_new_record ( sformat_new_record (
"object", &object_type, "object", &object_type,
sformat_new_string ("name", NULL), sformat_new_string ("name"),
sformat_new_integer ("total", NULL), sformat_new_integer ("total"),
sformat_new_integer ("self", NULL), sformat_new_integer ("self"),
NULL)), NULL)),
sformat_new_list ( sformat_new_list (
"nodes", NULL, "nodes", NULL,
@ -82,7 +81,6 @@ create_format (void)
sformat_new_pointer ("next", &node_type), sformat_new_pointer ("next", &node_type),
NULL)), NULL)),
NULL)); NULL));
#endif
} }
static void static void
@ -103,6 +101,9 @@ add_object (gpointer key, gpointer value, gpointer data)
static void static void
serialize_call_tree (Node *node, SFileOutput *output) serialize_call_tree (Node *node, SFileOutput *output)
{ {
if (!node)
return;
sfile_begin_add_record (output, "node"); sfile_begin_add_record (output, "node");
sfile_add_pointer (output, "object", node->object); sfile_add_pointer (output, "object", node->object);
sfile_add_pointer (output, "siblings", node->siblings); sfile_add_pointer (output, "siblings", node->siblings);
@ -123,8 +124,8 @@ profile_save (Profile *profile,
gboolean result; gboolean result;
SFormat *format = create_format (); SFormat *format = create_format ();
#if 0
SFileOutput *output = sfile_output_new (format); SFileOutput *output = sfile_output_new (format);
sfile_begin_add_record (output, "profile"); sfile_begin_add_record (output, "profile");
sfile_add_integer (output, "size", profile->size); sfile_add_integer (output, "size", profile->size);
@ -144,25 +145,67 @@ profile_save (Profile *profile,
sformat_free (format); sformat_free (format);
sfile_output_free (output); sfile_output_free (output);
#endif
return result; return result;
} }
Profile * Profile *
profile_load (const char *filename, GError **err) profile_load (const char *filename, GError **err)
{ {
SFormat *format = create_format (); SFormat *format;
SFileInput *input; SFileInput *input;
Profile *profile;
int n, i;
format = create_format ();
input = sfile_load (filename, format, err); input = sfile_load (filename, format, err);
if (!input)
return NULL;
profile = g_new (Profile, 1);
sfile_begin_get_record (input, "profile");
sfile_get_integer (input, "size", &profile->size);
n = sfile_begin_get_list (input, "objects");
for (i = 0; i < n; ++i)
{
ProfileObject *obj = g_new (ProfileObject, 1);
sfile_begin_get_record (input, "object");
sfile_get_string (input, "name", &obj->name);
sfile_get_integer (input, "total", &obj->total);
sfile_get_integer (input, "self", &obj->self);
sfile_end_get (input, "object", obj);
}
sfile_end_get (input, "objects", NULL);
n = sfile_begin_get_list (input, "nodes");
for (i = 0; i < n; ++i)
{
Node *node = g_new (Node, 1);
sfile_begin_get_record (input, "node");
sfile_get_pointer (input, "object", (gpointer *)&node->object);
sfile_get_pointer (input, "siblings", (gpointer *)&node->siblings);
sfile_get_pointer (input, "children", (gpointer *)&node->children);
sfile_get_pointer (input, "parent", (gpointer *)&node->parent);
sfile_get_pointer (input, "next", (gpointer *)&node->next);
sfile_end_get (input, "node", node);
if (!node->parent)
profile->call_tree = node;
}
sfile_end_get (input, "nodes", NULL);
#if 0
sformat_free (format); sformat_free (format);
#endif
return profile;
} }
static ProfileObject * static ProfileObject *

244
sfile.c
View File

@ -16,37 +16,29 @@ struct SFormat
State *end; State *end;
}; };
/* defining types */ enum
{
TYPE_POINTER,
TYPE_STRING,
TYPE_INTEGER,
TYPE_GENERIC_RECORD,
TYPE_GENERIC_LIST,
N_BUILTIN_TYPES,
};
typedef enum typedef enum
{ {
#define FIRST_BEGIN_TRANSITION BEGIN_RECORD BEGIN,
BEGIN_RECORD, VALUE,
BEGIN_LIST, END
BEGIN_POINTER, } TransitionKind;
BEGIN_INTEGER,
BEGIN_STRING,
#define LAST_BEGIN_TRANSITION BEGIN_STRING
#define FIRST_END_TRANSITION END_RECORD
END_RECORD,
END_LIST,
END_POINTER,
END_INTEGER,
END_STRING,
#define LAST_END_TRANSITION END_STRING
#define FIRST_VALUE_TRANSITION POINTER
POINTER,
INTEGER,
STRING
#define LAST_VALUE_TRANSITION STRING
} TransitionType;
struct Transition struct Transition
{ {
TransitionType type; SType type;
TransitionKind kind;
State *to; State *to;
char *element; /* for begin/end transitions */ char *element; /* for begin/end transitions */
}; };
struct State struct State
@ -121,7 +113,11 @@ state_new (void)
} }
static Transition * static Transition *
transition_new (const char *element, TransitionType type, State *from, State *to) transition_new (const char *element,
TransitionKind kind,
SType type,
State *from,
State *to)
{ {
Transition *t = g_new (Transition, 1); Transition *t = g_new (Transition, 1);
@ -153,7 +149,7 @@ sformat_new (gpointer f)
} }
void void
sformat_destroy (SFormat *format) sformat_free (SFormat *format)
{ {
/* FIXME */ /* FIXME */
} }
@ -207,7 +203,7 @@ fragment_queue (va_list args)
* *
* Binary blobs of data, stored as base64 perhaps * Binary blobs of data, stored as base64 perhaps
* floating point values. How do we store those portably * floating point values. How do we store those portably
* without losing precision? * without losing precision? Gnumeric may know.
* enums, stored as strings * enums, stored as strings
*/ */
gpointer gpointer
@ -261,8 +257,25 @@ sformat_new_union (const char *name,
} }
#endif #endif
static SType
define_type (SType *type, SType fallback)
{
static SType type_ids = N_BUILTIN_TYPES;
if (type)
{
if (*type == 0)
*type = type_ids++;
return *type;
}
return fallback;
}
gpointer gpointer
sformat_new_record (const char * name, sformat_new_record (const char * name,
SType *type,
gpointer content1, gpointer content1,
...) ...)
{ {
@ -271,6 +284,7 @@ sformat_new_record (const char * name,
State *begin, *state; State *begin, *state;
Fragment *fragment; Fragment *fragment;
GList *list; GList *list;
SType real_type;
/* Build queue of fragments */ /* Build queue of fragments */
va_start (args, content1); va_start (args, content1);
@ -292,26 +306,32 @@ sformat_new_record (const char * name,
fragment->exit->to = state; fragment->exit->to = state;
} }
real_type = define_type (type, TYPE_GENERIC_RECORD);
/* Return resulting fragment */ /* Return resulting fragment */
fragment = g_new (Fragment, 1); fragment = g_new (Fragment, 1);
fragment->enter = transition_new (name, BEGIN_RECORD, NULL, begin); fragment->enter = transition_new (name, BEGIN, real_type, NULL, begin);
fragment->exit = transition_new (name, END_RECORD, state, NULL); fragment->exit = transition_new (name, END, real_type, state, NULL);
return fragment; return fragment;
} }
gpointer gpointer
sformat_new_list (const char *name, sformat_new_list (const char *name,
SType *type,
gpointer content) gpointer content)
{ {
Fragment *m = content; Fragment *m = content;
State *list_state; State *list_state;
Transition *enter, *exit; Transition *enter, *exit;
SType real_type;
list_state = state_new (); list_state = state_new ();
enter = transition_new (name, BEGIN_LIST, NULL, list_state); real_type = define_type (type, TYPE_GENERIC_LIST);
exit = transition_new (name, END_LIST, list_state, NULL);
enter = transition_new (name, BEGIN, real_type, NULL, list_state);
exit = transition_new (name, END, real_type, list_state, NULL);
g_queue_push_tail (list_state->transitions, m->enter); g_queue_push_tail (list_state->transitions, m->enter);
m->exit->to = list_state; m->exit->to = list_state;
@ -324,9 +344,7 @@ sformat_new_list (const char *name,
static gpointer static gpointer
sformat_new_value (const char *name, sformat_new_value (const char *name,
TransitionType enter, SType type)
TransitionType type,
TransitionType exit)
{ {
Fragment *m = g_new (Fragment, 1); Fragment *m = g_new (Fragment, 1);
State *before, *after; State *before, *after;
@ -335,29 +353,30 @@ sformat_new_value (const char *name,
before = state_new (); before = state_new ();
after = state_new (); after = state_new ();
m->enter = transition_new (name, enter, NULL, before); m->enter = transition_new (name, BEGIN, type, NULL, before);
m->exit = transition_new (name, type, after, NULL); m->exit = transition_new (name, END, type, after, NULL);
value = transition_new (NULL, exit, before, after); value = transition_new (NULL, VALUE, type, before, after);
return m; return m;
} }
gpointer gpointer
sformat_new_pointer (const char *name) sformat_new_pointer (const char *name,
SType *target_type)
{ {
return sformat_new_value (name, BEGIN_POINTER, POINTER, END_POINTER); return sformat_new_value (name, TYPE_POINTER);
} }
gpointer gpointer
sformat_new_integer (const char *name) sformat_new_integer (const char *name)
{ {
return sformat_new_value (name, BEGIN_INTEGER, INTEGER, END_INTEGER); return sformat_new_value (name, TYPE_INTEGER);
} }
gpointer gpointer
sformat_new_string (const char *name) sformat_new_string (const char *name)
{ {
return sformat_new_value (name, BEGIN_STRING, STRING, END_STRING); return sformat_new_value (name, TYPE_STRING);
} }
static const State * static const State *
@ -373,9 +392,11 @@ sformat_is_end_state (SFormat *format, const State *state)
} }
static const State * static const State *
state_transition_check (const State *state, const char *element, state_transition_check (const State *state,
TransitionType first, TransitionType last, const char *element,
TransitionType *type, GError **err) TransitionKind kind,
SType *type,
GError **err)
{ {
GList *list; GList *list;
@ -383,8 +404,7 @@ state_transition_check (const State *state, const char *element,
{ {
Transition *transition; Transition *transition;
if (transition->type >= first && if (transition->kind == kind &&
transition->type <= last &&
strcmp (element, transition->element) == 0) strcmp (element, transition->element) == 0)
{ {
*type = transition->type; *type = transition->type;
@ -399,24 +419,20 @@ state_transition_check (const State *state, const char *element,
static const State * static const State *
state_transition_begin (const State *state, const char *element, state_transition_begin (const State *state, const char *element,
TransitionType *type, GError **err) SType *type, GError **err)
{ {
return state_transition_check (state, element, return state_transition_check (state, element, BEGIN, type, err);
FIRST_BEGIN_TRANSITION, LAST_BEGIN_TRANSITION,
type, err);
} }
static const State * static const State *
state_transition_end (const State *state, const char *element, state_transition_end (const State *state, const char *element,
TransitionType *type, GError **err) SType *type, GError **err)
{ {
return state_transition_check (state, element, return state_transition_check (state, element, END, type, err);
FIRST_END_TRANSITION, LAST_END_TRANSITION,
type, err);
} }
static const State * static const State *
state_transition_text (const State *state, TransitionType *type, GError **err) state_transition_text (const State *state, SType *type, GError **err)
{ {
GList *list; GList *list;
@ -424,9 +440,7 @@ state_transition_text (const State *state, TransitionType *type, GError **err)
{ {
Transition *transition = list->data; Transition *transition = list->data;
if (transition->type == POINTER || if (transition->kind == VALUE)
transition->type == INTEGER ||
transition->type == STRING)
{ {
*type = transition->type; *type = transition->type;
@ -447,7 +461,8 @@ typedef struct Instruction Instruction;
struct Instruction struct Instruction
{ {
TransitionType type; TransitionKind kind;
SType type;
char *name; char *name;
union union
@ -518,16 +533,30 @@ struct SFileInput
Instruction *instructions; Instruction *instructions;
Instruction *current_instruction; Instruction *current_instruction;
GHashTable *instructions_by_location; GHashTable *instructions_by_location;
GHashTable *objects_by_id;
}; };
static gboolean
is_record_type (SType type)
{
/* FIXME */
return TRUE;
}
static gboolean
is_list_type (SType type)
{
/* FIXME */
return FALSE;
}
void void
sfile_begin_get_record (SFileInput *file, const char *name) sfile_begin_get_record (SFileInput *file, const char *name)
{ {
Instruction *instruction = file->current_instruction++; Instruction *instruction = file->current_instruction++;
g_return_if_fail (instruction->type == BEGIN_RECORD && g_return_if_fail (instruction->kind == BEGIN);
strcmp (instruction->name, name) == 0); g_return_if_fail (strcmp (instruction->name, name) == 0);
g_return_if_fail (is_record_type (instruction->type));
} }
int int
@ -536,8 +565,9 @@ sfile_begin_get_list (SFileInput *file,
{ {
Instruction *instruction = file->current_instruction++; Instruction *instruction = file->current_instruction++;
g_return_val_if_fail (instruction->type == BEGIN_LIST && g_return_val_if_fail (instruction->kind == BEGIN, 0);
strcmp (instruction->name, name) == 0, 0); g_return_val_if_fail (strcmp (instruction->name, name) == 0, 0);
g_return_val_if_fail (is_list_type (instruction->type), 0);
return instruction->u.begin.n_instructions; return instruction->u.begin.n_instructions;
} }
@ -548,7 +578,7 @@ sfile_get_pointer (SFileInput *file,
gpointer *location) gpointer *location)
{ {
Instruction *instruction = file->current_instruction++; Instruction *instruction = file->current_instruction++;
g_return_if_fail (instruction->type == POINTER && g_return_if_fail (instruction->type == TYPE_POINTER &&
strcmp (instruction->name, name) == 0); strcmp (instruction->name, name) == 0);
instruction->u.pointer.location = location; instruction->u.pointer.location = location;
@ -570,7 +600,7 @@ sfile_get_integer (SFileInput *file,
int *integer) int *integer)
{ {
Instruction *instruction = file->current_instruction++; Instruction *instruction = file->current_instruction++;
g_return_if_fail (instruction->type == INTEGER && g_return_if_fail (instruction->type == TYPE_INTEGER &&
strcmp (instruction->name, name) == 0); strcmp (instruction->name, name) == 0);
if (integer) if (integer)
@ -583,7 +613,7 @@ sfile_get_string (SFileInput *file,
char **string) char **string)
{ {
Instruction *instruction = file->current_instruction++; Instruction *instruction = file->current_instruction++;
g_return_if_fail (instruction->type == STRING && g_return_if_fail (instruction->type == TYPE_STRING &&
strcmp (instruction->name, name) == 0); strcmp (instruction->name, name) == 0);
if (string) if (string)
@ -599,7 +629,7 @@ hook_up_pointers (SFileInput *file)
{ {
Instruction *instruction = &(file->instructions[i]); Instruction *instruction = &(file->instructions[i]);
if (instruction->type == POINTER) if (instruction->type == TYPE_POINTER)
{ {
gpointer target_object = gpointer target_object =
instruction->u.pointer.target_instruction->u.begin.end_instruction->u.end.object; instruction->u.pointer.target_instruction->u.begin.end_instruction->u.end.object;
@ -616,8 +646,7 @@ sfile_end_get (SFileInput *file,
{ {
Instruction *instruction = file->current_instruction++; Instruction *instruction = file->current_instruction++;
g_return_if_fail ((instruction->type == END_LIST || g_return_if_fail (instruction->kind == END &&
instruction->type == END_RECORD) &&
strcmp (instruction->name, name) == 0); strcmp (instruction->name, name) == 0);
instruction->u.end.object = object; instruction->u.end.object = object;
@ -732,7 +761,7 @@ handle_text (GMarkupParseContext *context,
switch (instruction.type) switch (instruction.type)
{ {
case POINTER: case TYPE_POINTER:
if (!get_number (text, &instruction.u.pointer.target_id)) if (!get_number (text, &instruction.u.pointer.target_id))
{ {
set_invalid_content_error (err, "Contents '%s' of pointer element is not a number", text); set_invalid_content_error (err, "Contents '%s' of pointer element is not a number", text);
@ -740,7 +769,7 @@ handle_text (GMarkupParseContext *context,
} }
break; break;
case INTEGER: case TYPE_INTEGER:
if (!get_number (text, &instruction.u.integer.value)) if (!get_number (text, &instruction.u.integer.value))
{ {
set_invalid_content_error (err, "Contents '%s' of integer element not a number", text); set_invalid_content_error (err, "Contents '%s' of integer element not a number", text);
@ -748,7 +777,7 @@ handle_text (GMarkupParseContext *context,
} }
break; break;
case STRING: case TYPE_STRING:
if (!decode_text (text, &instruction.u.string.value)) if (!decode_text (text, &instruction.u.string.value))
{ {
set_invalid_content_error (err, "Contents '%s' of text element is illformed", text); set_invalid_content_error (err, "Contents '%s' of text element is illformed", text);
@ -776,7 +805,7 @@ free_instructions (Instruction *instructions, int n_instructions)
if (instruction->name) if (instruction->name)
g_free (instruction->name); g_free (instruction->name);
if (instruction->type == STRING) if (instruction->type == TYPE_STRING)
g_free (instruction->u.string.value); g_free (instruction->u.string.value);
} }
@ -793,17 +822,14 @@ post_process_instructions_recurse (Instruction *first, GHashTable *instructions_
Instruction *instruction; Instruction *instruction;
int n_instructions; int n_instructions;
g_assert (first->type >= FIRST_BEGIN_TRANSITION && g_assert (first->kind == BEGIN);
first->type <= LAST_BEGIN_TRANSITION);
instruction = first + 1; instruction = first + 1;
n_instructions = 0; n_instructions = 0;
while (instruction->type < FIRST_END_TRANSITION || while (instruction->kind != END)
instruction->type > LAST_END_TRANSITION)
{ {
if (instruction->type >= FIRST_BEGIN_TRANSITION && if (instruction->kind == BEGIN)
instruction->type <= LAST_BEGIN_TRANSITION)
{ {
instruction = post_process_instructions_recurse (instruction, instructions_by_id, err); instruction = post_process_instructions_recurse (instruction, instructions_by_id, err);
if (!instruction) if (!instruction)
@ -811,7 +837,7 @@ post_process_instructions_recurse (Instruction *first, GHashTable *instructions_
} }
else else
{ {
if (instruction->type == POINTER) if (instruction->type == TYPE_POINTER)
{ {
int target_id = instruction->u.pointer.target_id; int target_id = instruction->u.pointer.target_id;
Instruction *target = g_hash_table_lookup (instructions_by_id, GINT_TO_POINTER (target_id)); Instruction *target = g_hash_table_lookup (instructions_by_id, GINT_TO_POINTER (target_id));
@ -853,8 +879,7 @@ post_process_read_instructions (Instruction *instructions, int n_instructions, G
{ {
Instruction *instruction = &(instructions[i]); Instruction *instruction = &(instructions[i]);
if (instruction->type >= FIRST_BEGIN_TRANSITION && if (instruction->kind == BEGIN)
instruction->type <= LAST_BEGIN_TRANSITION)
{ {
int id = instruction->u.begin.id; int id = instruction->u.begin.id;
@ -952,7 +977,7 @@ struct SFileOutput
SFileOutput * SFileOutput *
sfile_output_mew (SFormat *format) sfile_output_new (SFormat *format)
{ {
SFileOutput *output = g_new (SFileOutput, 1); SFileOutput *output = g_new (SFileOutput, 1);
@ -972,8 +997,10 @@ sfile_begin_add_record (SFileOutput *file,
file->state = state_transition_begin ( file->state = state_transition_begin (
file->state, name, &instruction.type, NULL); file->state, name, &instruction.type, NULL);
g_return_if_fail (file->state && instruction.type == BEGIN_RECORD); g_return_if_fail (file->state);
g_return_if_fail (is_record_type (instruction.type));
instruction.kind = BEGIN;
instruction.name = g_strdup (name); instruction.name = g_strdup (name);
g_array_append_val (file->instructions, instruction); g_array_append_val (file->instructions, instruction);
@ -984,13 +1011,14 @@ sfile_begin_add_list (SFileOutput *file,
const char *name) const char *name)
{ {
Instruction instruction; Instruction instruction;
TransitionType type;
file->state = state_transition_begin ( file->state = state_transition_begin (
file->state, name, &instruction.type, NULL); file->state, name, &instruction.type, NULL);
g_return_if_fail (file->state && type == BEGIN_LIST); g_return_if_fail (file->state);
g_return_if_fail (is_list_type (instruction.type));
instruction.kind = BEGIN;
instruction.name = g_strdup (name); instruction.name = g_strdup (name);
g_array_append_val (file->instructions, instruction); g_array_append_val (file->instructions, instruction);
@ -1006,9 +1034,9 @@ sfile_end_add (SFileOutput *file,
file->state = state_transition_end ( file->state = state_transition_end (
file->state, name, &instruction.type, NULL); file->state, name, &instruction.type, NULL);
g_return_if_fail (file->state && g_return_if_fail (file->state && instruction.kind == END);
(instruction.type == END_RECORD || instruction.type == END_LIST));
instruction.kind = END;
instruction.name = g_strdup (name); instruction.name = g_strdup (name);
instruction.u.end.object = object; instruction.u.end.object = object;
@ -1018,20 +1046,18 @@ sfile_end_add (SFileOutput *file,
static void static void
sfile_check_value (SFileOutput *file, sfile_check_value (SFileOutput *file,
const char *name, const char *name,
TransitionType begin, SType type)
TransitionType value,
TransitionType end)
{ {
TransitionType type; SType tmp_type;
file->state = state_transition_begin (file->state, name, &type, NULL); file->state = state_transition_begin (file->state, name, &tmp_type, NULL);
g_return_if_fail (file->state && type == begin); g_return_if_fail (file->state && tmp_type == type);
file->state = state_transition_text (file->state, &type, NULL); file->state = state_transition_text (file->state, &type, NULL);
g_return_if_fail (file->state && type == value); g_return_if_fail (file->state && tmp_type == type);
file->state = state_transition_end (file->state, name, &type, NULL); file->state = state_transition_end (file->state, name, &type, NULL);
g_return_if_fail (file->state && type == end); g_return_if_fail (file->state && tmp_type == type);
} }
void void
@ -1043,9 +1069,10 @@ sfile_add_string (SFileOutput *file,
g_return_if_fail (g_utf8_validate (string, -1, NULL)); g_return_if_fail (g_utf8_validate (string, -1, NULL));
sfile_check_value (file, name, BEGIN_STRING, STRING, END_STRING); sfile_check_value (file, name, TYPE_STRING);
instruction.type = STRING; instruction.kind = VALUE;
instruction.type = TYPE_STRING;
instruction.u.string.value = g_strdup (string); instruction.u.string.value = g_strdup (string);
g_array_append_val (file->instructions, instruction); g_array_append_val (file->instructions, instruction);
@ -1058,9 +1085,10 @@ sfile_add_integer (SFileOutput *file,
{ {
Instruction instruction; Instruction instruction;
sfile_check_value (file, name, BEGIN_INTEGER, INTEGER, END_INTEGER); sfile_check_value (file, name, TYPE_INTEGER);
instruction.type = INTEGER; instruction.kind = VALUE;
instruction.type = TYPE_INTEGER;
instruction.name = g_strdup (name); instruction.name = g_strdup (name);
instruction.u.integer.value = integer; instruction.u.integer.value = integer;
@ -1074,9 +1102,10 @@ sfile_add_pointer (SFileOutput *file,
{ {
Instruction instruction; Instruction instruction;
sfile_check_value (file, name, BEGIN_POINTER, POINTER, END_POINTER); sfile_check_value (file, name, TYPE_POINTER);
instruction.type = POINTER; instruction.kind = VALUE;
instruction.type = TYPE_POINTER;
instruction.name = g_strdup (name); instruction.name = g_strdup (name);
instruction.u.pointer.object = pointer; instruction.u.pointer.object = pointer;
@ -1091,3 +1120,10 @@ sfile_output_save (SFileOutput *sfile,
return FALSE; /* FIXME */ return FALSE; /* FIXME */
} }
void
sfile_output_free (SFileOutput *sfile)
{
/* FIXME */
}

View File

@ -1,15 +1,19 @@
typedef struct SFormat SFormat; typedef struct SFormat SFormat;
typedef struct SFileInput SFileInput; typedef struct SFileInput SFileInput;
typedef struct SFileOutput SFileOutput; typedef struct SFileOutput SFileOutput;
typedef guint SType;
/* - Describing Types - */ /* - Describing Types - */
SFormat *sformat_new (gpointer f); SFormat *sformat_new (gpointer f);
gpointer sformat_new_record (const char *name, gpointer sformat_new_record (const char *name,
SType *type,
gpointer content, gpointer content,
...); ...);
gpointer sformat_new_list (const char *name, gpointer sformat_new_list (const char *name,
SType *type,
gpointer content); gpointer content);
gpointer sformat_new_pointer (const char *name); gpointer sformat_new_pointer (const char *name,
SType *target_type);
gpointer sformat_new_integer (const char *name); gpointer sformat_new_integer (const char *name);
gpointer sformat_new_string (const char *name); gpointer sformat_new_string (const char *name);
void sformat_free (SFormat *format); void sformat_free (SFormat *format);