diff options
author | Soeren Sandmann <sandmann@redhat.com> | 2005-03-04 04:48:40 +0000 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@src.gnome.org> | 2005-03-04 04:48:40 +0000 |
commit | 466b093348a64659655350dda150324e41a55bb7 (patch) | |
tree | 0fdfc39cb45332d2feda6c02db2274d0f670eac7 | |
parent | de4b3c076d51124ef1ce6c35f2233cb935fa4ec0 (diff) |
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.
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | profile.c | 69 | ||||
-rw-r--r-- | sfile.c | 252 | ||||
-rw-r--r-- | sfile.h | 6 |
4 files changed, 212 insertions, 122 deletions
@@ -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> * profile.[ch], sfile.[ch]: Experiment with a @@ -55,21 +55,20 @@ struct Profile static SFormat * create_format (void) { -#if 0 SType object_type = 0; SType node_type = 0; return sformat_new ( sformat_new_record ( "profile", - sformat_new_integer ("size", NULL), + sformat_new_integer ("size"), sformat_new_list ( "objects", NULL, sformat_new_record ( "object", &object_type, - sformat_new_string ("name", NULL), - sformat_new_integer ("total", NULL), - sformat_new_integer ("self", NULL), + sformat_new_string ("name"), + sformat_new_integer ("total"), + sformat_new_integer ("self"), NULL)), sformat_new_list ( "nodes", NULL, @@ -82,7 +81,6 @@ create_format (void) sformat_new_pointer ("next", &node_type), NULL)), NULL)); -#endif } static void @@ -103,6 +101,9 @@ add_object (gpointer key, gpointer value, gpointer data) static void serialize_call_tree (Node *node, SFileOutput *output) { + if (!node) + return; + sfile_begin_add_record (output, "node"); sfile_add_pointer (output, "object", node->object); sfile_add_pointer (output, "siblings", node->siblings); @@ -123,8 +124,8 @@ profile_save (Profile *profile, gboolean result; SFormat *format = create_format (); -#if 0 SFileOutput *output = sfile_output_new (format); + sfile_begin_add_record (output, "profile"); sfile_add_integer (output, "size", profile->size); @@ -144,25 +145,67 @@ profile_save (Profile *profile, sformat_free (format); sfile_output_free (output); -#endif return result; } Profile * profile_load (const char *filename, GError **err) { - SFormat *format = create_format (); + SFormat *format; SFileInput *input; - + Profile *profile; + int n, i; + + format = create_format (); 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); -#endif - + return profile; } static ProfileObject * @@ -16,37 +16,29 @@ struct SFormat State *end; }; -/* defining types */ +enum +{ + TYPE_POINTER, + TYPE_STRING, + TYPE_INTEGER, + TYPE_GENERIC_RECORD, + TYPE_GENERIC_LIST, + N_BUILTIN_TYPES, +}; + typedef enum { -#define FIRST_BEGIN_TRANSITION BEGIN_RECORD - BEGIN_RECORD, - BEGIN_LIST, - BEGIN_POINTER, - 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; + BEGIN, + VALUE, + END +} TransitionKind; struct Transition { - TransitionType type; + SType type; + TransitionKind kind; State *to; - char *element; /* for begin/end transitions */ + char *element; /* for begin/end transitions */ }; struct State @@ -121,7 +113,11 @@ state_new (void) } 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); @@ -153,7 +149,7 @@ sformat_new (gpointer f) } void -sformat_destroy (SFormat *format) +sformat_free (SFormat *format) { /* FIXME */ } @@ -207,7 +203,7 @@ fragment_queue (va_list args) * * Binary blobs of data, stored as base64 perhaps * floating point values. How do we store those portably - * without losing precision? + * without losing precision? Gnumeric may know. * enums, stored as strings */ gpointer @@ -261,8 +257,25 @@ sformat_new_union (const char *name, } #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 sformat_new_record (const char * name, + SType *type, gpointer content1, ...) { @@ -271,7 +284,8 @@ sformat_new_record (const char * name, State *begin, *state; Fragment *fragment; GList *list; - + SType real_type; + /* Build queue of fragments */ va_start (args, content1); @@ -291,27 +305,33 @@ sformat_new_record (const char * name, state = state_new (); fragment->exit->to = state; } + + real_type = define_type (type, TYPE_GENERIC_RECORD); /* Return resulting fragment */ fragment = g_new (Fragment, 1); - fragment->enter = transition_new (name, BEGIN_RECORD, NULL, begin); - fragment->exit = transition_new (name, END_RECORD, state, NULL); + fragment->enter = transition_new (name, BEGIN, real_type, NULL, begin); + fragment->exit = transition_new (name, END, real_type, state, NULL); return fragment; } gpointer sformat_new_list (const char *name, + SType *type, gpointer content) { Fragment *m = content; State *list_state; Transition *enter, *exit; + SType real_type; list_state = state_new (); + + real_type = define_type (type, TYPE_GENERIC_LIST); - enter = transition_new (name, BEGIN_LIST, NULL, list_state); - 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); m->exit->to = list_state; @@ -324,9 +344,7 @@ sformat_new_list (const char *name, static gpointer sformat_new_value (const char *name, - TransitionType enter, - TransitionType type, - TransitionType exit) + SType type) { Fragment *m = g_new (Fragment, 1); State *before, *after; @@ -335,29 +353,30 @@ sformat_new_value (const char *name, before = state_new (); after = state_new (); - m->enter = transition_new (name, enter, NULL, before); - m->exit = transition_new (name, type, after, NULL); - value = transition_new (NULL, exit, before, after); + m->enter = transition_new (name, BEGIN, type, NULL, before); + m->exit = transition_new (name, END, type, after, NULL); + value = transition_new (NULL, VALUE, type, before, after); return m; } 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 sformat_new_integer (const char *name) { - return sformat_new_value (name, BEGIN_INTEGER, INTEGER, END_INTEGER); + return sformat_new_value (name, TYPE_INTEGER); } gpointer 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 * @@ -373,18 +392,19 @@ sformat_is_end_state (SFormat *format, const State *state) } static const State * -state_transition_check (const State *state, const char *element, - TransitionType first, TransitionType last, - TransitionType *type, GError **err) +state_transition_check (const State *state, + const char *element, + TransitionKind kind, + SType *type, + GError **err) { GList *list; for (list = state->transitions->head; list; list = list->next) { Transition *transition; - - if (transition->type >= first && - transition->type <= last && + + if (transition->kind == kind && strcmp (element, transition->element) == 0) { *type = transition->type; @@ -399,24 +419,20 @@ state_transition_check (const State *state, const char *element, static const State * state_transition_begin (const State *state, const char *element, - TransitionType *type, GError **err) + SType *type, GError **err) { - return state_transition_check (state, element, - FIRST_BEGIN_TRANSITION, LAST_BEGIN_TRANSITION, - type, err); + return state_transition_check (state, element, BEGIN, type, err); } static const State * state_transition_end (const State *state, const char *element, - TransitionType *type, GError **err) + SType *type, GError **err) { - return state_transition_check (state, element, - FIRST_END_TRANSITION, LAST_END_TRANSITION, - type, err); + return state_transition_check (state, element, END, type, err); } 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; @@ -424,9 +440,7 @@ state_transition_text (const State *state, TransitionType *type, GError **err) { Transition *transition = list->data; - if (transition->type == POINTER || - transition->type == INTEGER || - transition->type == STRING) + if (transition->kind == VALUE) { *type = transition->type; @@ -447,7 +461,8 @@ typedef struct Instruction Instruction; struct Instruction { - TransitionType type; + TransitionKind kind; + SType type; char *name; union @@ -518,16 +533,30 @@ struct SFileInput Instruction *instructions; Instruction *current_instruction; 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 sfile_begin_get_record (SFileInput *file, const char *name) { Instruction *instruction = file->current_instruction++; - - g_return_if_fail (instruction->type == BEGIN_RECORD && - strcmp (instruction->name, name) == 0); + + g_return_if_fail (instruction->kind == BEGIN); + g_return_if_fail (strcmp (instruction->name, name) == 0); + g_return_if_fail (is_record_type (instruction->type)); } int @@ -536,8 +565,9 @@ sfile_begin_get_list (SFileInput *file, { Instruction *instruction = file->current_instruction++; - g_return_val_if_fail (instruction->type == BEGIN_LIST && - strcmp (instruction->name, name) == 0, 0); + g_return_val_if_fail (instruction->kind == BEGIN, 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; } @@ -548,7 +578,7 @@ sfile_get_pointer (SFileInput *file, gpointer *location) { 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); instruction->u.pointer.location = location; @@ -570,7 +600,7 @@ sfile_get_integer (SFileInput *file, int *integer) { 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); if (integer) @@ -583,7 +613,7 @@ sfile_get_string (SFileInput *file, char **string) { 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); if (string) @@ -599,7 +629,7 @@ hook_up_pointers (SFileInput *file) { Instruction *instruction = &(file->instructions[i]); - if (instruction->type == POINTER) + if (instruction->type == TYPE_POINTER) { gpointer target_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++; - g_return_if_fail ((instruction->type == END_LIST || - instruction->type == END_RECORD) && + g_return_if_fail (instruction->kind == END && strcmp (instruction->name, name) == 0); instruction->u.end.object = object; @@ -732,7 +761,7 @@ handle_text (GMarkupParseContext *context, switch (instruction.type) { - case POINTER: + case TYPE_POINTER: if (!get_number (text, &instruction.u.pointer.target_id)) { set_invalid_content_error (err, "Contents '%s' of pointer element is not a number", text); @@ -740,7 +769,7 @@ handle_text (GMarkupParseContext *context, } break; - case INTEGER: + case TYPE_INTEGER: if (!get_number (text, &instruction.u.integer.value)) { set_invalid_content_error (err, "Contents '%s' of integer element not a number", text); @@ -748,7 +777,7 @@ handle_text (GMarkupParseContext *context, } break; - case STRING: + case TYPE_STRING: if (!decode_text (text, &instruction.u.string.value)) { 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) g_free (instruction->name); - if (instruction->type == STRING) + if (instruction->type == TYPE_STRING) g_free (instruction->u.string.value); } @@ -793,17 +822,14 @@ post_process_instructions_recurse (Instruction *first, GHashTable *instructions_ Instruction *instruction; int n_instructions; - g_assert (first->type >= FIRST_BEGIN_TRANSITION && - first->type <= LAST_BEGIN_TRANSITION); + g_assert (first->kind == BEGIN); instruction = first + 1; n_instructions = 0; - while (instruction->type < FIRST_END_TRANSITION || - instruction->type > LAST_END_TRANSITION) + while (instruction->kind != END) { - if (instruction->type >= FIRST_BEGIN_TRANSITION && - instruction->type <= LAST_BEGIN_TRANSITION) + if (instruction->kind == BEGIN) { instruction = post_process_instructions_recurse (instruction, instructions_by_id, err); if (!instruction) @@ -811,7 +837,7 @@ post_process_instructions_recurse (Instruction *first, GHashTable *instructions_ } else { - if (instruction->type == POINTER) + if (instruction->type == TYPE_POINTER) { int target_id = instruction->u.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]); - if (instruction->type >= FIRST_BEGIN_TRANSITION && - instruction->type <= LAST_BEGIN_TRANSITION) + if (instruction->kind == BEGIN) { int id = instruction->u.begin.id; @@ -952,7 +977,7 @@ struct SFileOutput SFileOutput * -sfile_output_mew (SFormat *format) +sfile_output_new (SFormat *format) { SFileOutput *output = g_new (SFileOutput, 1); @@ -972,8 +997,10 @@ sfile_begin_add_record (SFileOutput *file, file->state = state_transition_begin ( 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); g_array_append_val (file->instructions, instruction); @@ -984,13 +1011,14 @@ sfile_begin_add_list (SFileOutput *file, const char *name) { Instruction instruction; - TransitionType type; file->state = state_transition_begin ( 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); g_array_append_val (file->instructions, instruction); @@ -1006,9 +1034,9 @@ sfile_end_add (SFileOutput *file, file->state = state_transition_end ( file->state, name, &instruction.type, NULL); - g_return_if_fail (file->state && - (instruction.type == END_RECORD || instruction.type == END_LIST)); + g_return_if_fail (file->state && instruction.kind == END); + instruction.kind = END; instruction.name = g_strdup (name); instruction.u.end.object = object; @@ -1018,20 +1046,18 @@ sfile_end_add (SFileOutput *file, static void sfile_check_value (SFileOutput *file, const char *name, - TransitionType begin, - TransitionType value, - TransitionType end) + SType type) { - TransitionType type; + SType tmp_type; - file->state = state_transition_begin (file->state, name, &type, NULL); - g_return_if_fail (file->state && type == begin); + file->state = state_transition_begin (file->state, name, &tmp_type, NULL); + g_return_if_fail (file->state && tmp_type == type); 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); - g_return_if_fail (file->state && type == end); + g_return_if_fail (file->state && tmp_type == type); } void @@ -1043,9 +1069,10 @@ sfile_add_string (SFileOutput *file, 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); g_array_append_val (file->instructions, instruction); @@ -1058,9 +1085,10 @@ sfile_add_integer (SFileOutput *file, { 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.u.integer.value = integer; @@ -1074,9 +1102,10 @@ sfile_add_pointer (SFileOutput *file, { 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.u.pointer.object = pointer; @@ -1091,3 +1120,10 @@ sfile_output_save (SFileOutput *sfile, return FALSE; /* FIXME */ } + + +void +sfile_output_free (SFileOutput *sfile) +{ + /* FIXME */ +} @@ -1,15 +1,19 @@ typedef struct SFormat SFormat; typedef struct SFileInput SFileInput; typedef struct SFileOutput SFileOutput; +typedef guint SType; /* - 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); +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); |