mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
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:
committed by
Søren Sandmann Pedersen
parent
de4b3c076d
commit
466b093348
@ -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
|
||||||
|
|||||||
71
profile.c
71
profile.c
@ -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);
|
||||||
#if 0
|
|
||||||
sformat_free (format);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
sformat_free (format);
|
||||||
|
|
||||||
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ProfileObject *
|
static ProfileObject *
|
||||||
|
|||||||
252
sfile.c
252
sfile.c
@ -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,7 +284,8 @@ 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);
|
||||||
|
|
||||||
@ -291,27 +305,33 @@ sformat_new_record (const char * name,
|
|||||||
state = state_new ();
|
state = state_new ();
|
||||||
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 ();
|
||||||
|
|
||||||
|
real_type = define_type (type, TYPE_GENERIC_LIST);
|
||||||
|
|
||||||
enter = transition_new (name, BEGIN_LIST, NULL, list_state);
|
enter = transition_new (name, BEGIN, real_type, NULL, list_state);
|
||||||
exit = transition_new (name, END_LIST, list_state, NULL);
|
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,18 +392,19 @@ 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;
|
||||||
|
|
||||||
for (list = state->transitions->head; list; list = list->next)
|
for (list = state->transitions->head; list; list = list->next)
|
||||||
{
|
{
|
||||||
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 */
|
||||||
|
}
|
||||||
|
|||||||
6
sfile.h
6
sfile.h
@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user