mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
*** empty log message ***
This commit is contained in:
427
sfile.c
427
sfile.c
@ -24,156 +24,294 @@
|
||||
#include <glib.h>
|
||||
#include "sfile.h"
|
||||
|
||||
typedef struct ReadItem ReadItem;
|
||||
struct SFormat
|
||||
{
|
||||
State *begin;
|
||||
State *end;
|
||||
};
|
||||
|
||||
/* defining types */
|
||||
typedef struct State State;
|
||||
typedef struct Transition Transition;
|
||||
typedef struct Fragment Fragment;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BEGIN_RECORD,
|
||||
BEGIN_LIST,
|
||||
END,
|
||||
READ_POINTER,
|
||||
READ_INTEGER,
|
||||
READ_STRING
|
||||
} ReadAction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RECORD,
|
||||
LIST,
|
||||
END_RECORD,
|
||||
END_LIST,
|
||||
BEGIN_POINTER,
|
||||
END_POINTER,
|
||||
BEGIN_INTEGER,
|
||||
END_INTEGER,
|
||||
BEGIN_STRING,
|
||||
END_STRING
|
||||
POINTER,
|
||||
INTEGER,
|
||||
STRING
|
||||
} SFormatType;
|
||||
} TransitionType;
|
||||
|
||||
struct SFormat
|
||||
struct Transition
|
||||
{
|
||||
SFormatType type;
|
||||
|
||||
char *name;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
GQueue *fields;
|
||||
} record;
|
||||
|
||||
struct
|
||||
{
|
||||
SFormat *content;
|
||||
} list;
|
||||
} u;
|
||||
TransitionType type;
|
||||
State *to;
|
||||
char *element; /* for begin/end transitions */
|
||||
};
|
||||
|
||||
struct ReadItem
|
||||
struct State
|
||||
{
|
||||
ReadAction action;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int id;
|
||||
gpointer pointer; /* Points to the user created object */
|
||||
} end;
|
||||
|
||||
struct
|
||||
{
|
||||
int id;
|
||||
} read_pointer;
|
||||
|
||||
struct
|
||||
{
|
||||
int n_items;
|
||||
} read_list;
|
||||
|
||||
struct
|
||||
{
|
||||
int value;
|
||||
} read_integer;
|
||||
|
||||
struct
|
||||
{
|
||||
char * value;
|
||||
} read_string;
|
||||
} u;
|
||||
GQueue *transitions;
|
||||
};
|
||||
|
||||
struct SFile
|
||||
struct Fragment
|
||||
{
|
||||
int n_items;
|
||||
ReadItem *items;
|
||||
ReadItem *current_item;
|
||||
GHashTable *locations_by_id;
|
||||
GHashTable *objects_by_id;
|
||||
Transition *enter, *exit;
|
||||
};
|
||||
|
||||
/* defining types */
|
||||
|
||||
static SFormat *
|
||||
create_sformat (const char *name,
|
||||
SFormatType type)
|
||||
SFormat *
|
||||
sformat_new (gpointer f)
|
||||
{
|
||||
SFormat *sformat = g_new0 (SFormat, 1);
|
||||
Fragment *fragment = f;
|
||||
|
||||
sformat->name = g_strdup (name);
|
||||
sformat->type = type;
|
||||
sformat->begin = state_new ();
|
||||
sformat->end = state_new ();
|
||||
|
||||
g_queue_push_tail (sformat->begin->transitions, f->enter);
|
||||
f->exit->to = sformat->end;
|
||||
|
||||
g_free (fragment);
|
||||
|
||||
return sformat;
|
||||
}
|
||||
|
||||
SFormat *
|
||||
static GQueue *
|
||||
format_queue (va_list formats)
|
||||
{
|
||||
GQueue *formats = g_queue_new ();
|
||||
|
||||
format = va_arg (args, SFormat *);
|
||||
while (format)
|
||||
{
|
||||
g_queue_push_tail (formats, format);
|
||||
format = va_arg (args, SFormat *);
|
||||
}
|
||||
va_end (args);
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
/* Consider adding unions at some point
|
||||
*
|
||||
* To be useful they should probably be anonymous, so that
|
||||
* the union itself doesn't have a representation in the
|
||||
* xml file.
|
||||
*
|
||||
* API:
|
||||
* sformat_new_union (gpointer content1, ...);
|
||||
*
|
||||
* char *content = begin_get_union ();
|
||||
* if (strcmp (content, ...) == 0)
|
||||
* get_pointer ();
|
||||
* else if (strcmp (content, ...) == 0)
|
||||
*
|
||||
* ;
|
||||
*
|
||||
* Annoying though, that we then won't have the nice one-to-one
|
||||
* correspondence between begin()/end() calls and <element></element>s
|
||||
* Actually, we will probably have to have <union>asdlfkj</union>
|
||||
* elements. That will make things a lot easier, and unions are
|
||||
* still pretty useful if you put big things like lists in them.
|
||||
*
|
||||
* We may also consider adding anonymous records. These will
|
||||
* not be able to have pointers associated with them though
|
||||
* (because there wouldn't be a natural place
|
||||
*/
|
||||
|
||||
gpointer
|
||||
sformat_new_union (const char *name,
|
||||
gpointer content1,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
GQueue *fragments;
|
||||
GList *list;
|
||||
Fragment *fragment;
|
||||
Transition *enter, *exit;
|
||||
State *begin;
|
||||
State *end;
|
||||
|
||||
va_start (args, content1);
|
||||
|
||||
fragments = format_queue (args);
|
||||
|
||||
va_end (args);
|
||||
|
||||
begin = state_new ();
|
||||
end = state_new ();
|
||||
|
||||
enter = transition_new_begin_union (name, NULL, begin);
|
||||
exit = transition_new_end_union (name, end, NULL);
|
||||
|
||||
for (list = fragments->head; list; list = list->next)
|
||||
{
|
||||
Fragment *fragment = list->data;
|
||||
|
||||
g_queue_push_tail (begin, fragment->enter);
|
||||
}
|
||||
|
||||
for (list = fragments->head; list; list = list->next)
|
||||
{
|
||||
fragment = list->data;
|
||||
|
||||
m->exit->to = end;
|
||||
|
||||
g_free (fragment);
|
||||
}
|
||||
|
||||
g_queue_free (fragments);
|
||||
|
||||
fragment = g_new (Fragment, 1);
|
||||
fragment->enter = enter;
|
||||
fragment->exit = exit;
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
gpointer
|
||||
sformat_new_record (const char * name,
|
||||
SFormat *content1,
|
||||
gpointer content1,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
SFormat *sformat = create_sformat (name, RECORD);
|
||||
SFormat *field;
|
||||
GQueue *fields = g_queue_new ();
|
||||
|
||||
GQueue *fragments;
|
||||
Transition *enter, *exit;
|
||||
State *begin, *end, *state;
|
||||
Fragment *fragment;
|
||||
|
||||
/* Build queue of fragments */
|
||||
va_start (args, content1);
|
||||
field = va_arg (args, SFormat *);
|
||||
while (field)
|
||||
{
|
||||
g_queue_push_tail (fields, field);
|
||||
field = va_arg (args, SFormat *);
|
||||
}
|
||||
|
||||
fragments = format_queue (args);
|
||||
|
||||
va_end (args);
|
||||
|
||||
sformat->u.record.fields = fields;
|
||||
/* chain fragments together */
|
||||
begin = state_new ();
|
||||
enter = transition_new_begin_record (name, NULL, begin);
|
||||
|
||||
return sformat;
|
||||
state = begin;
|
||||
|
||||
for (list = fragments->head; list != NULL; list = list->next)
|
||||
{
|
||||
/* At each point in the iteration we need,
|
||||
* - a target machine (in list->data)
|
||||
* - a state that will lead into that machine (in state)
|
||||
*/
|
||||
fragment = list->data;
|
||||
|
||||
g_queue_push_tail (state->transitions, fragment->enter);
|
||||
|
||||
state = state_new ();
|
||||
fragment->exit->to = state;
|
||||
}
|
||||
|
||||
/* Return resulting fragment */
|
||||
fragment = g_new (Fragment, 1);
|
||||
fragment->enter = enter;
|
||||
fragment->exit = transition_new_end_record (name, state, NULL);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
SFormat *
|
||||
gpointer
|
||||
sformat_new_list (const char *name,
|
||||
SFormat *content)
|
||||
gpointer content)
|
||||
{
|
||||
SFormat *sformat = create_sformat (name, LIST);
|
||||
sformat->u.list.content = content;
|
||||
return sformat;
|
||||
Fragment *m = content;
|
||||
State *list_state;
|
||||
Transition *enter, *exit;
|
||||
|
||||
list_state = state_new ();
|
||||
begin_state = state_new ();
|
||||
end_state = state_new ();
|
||||
|
||||
enter = transition_new_begin_list (name, NJLL, list_state);
|
||||
exit = transition_new_end_list (name, list_state, NULL);
|
||||
|
||||
g_queue_push_tail (list_state->transitions, m->enter);
|
||||
m->exit->to = list_state;
|
||||
|
||||
m->enter = enter;
|
||||
m->exit = exit;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
SFormat *
|
||||
gpointer
|
||||
sformat_new_value (const char *name, TransitionType type)
|
||||
{
|
||||
Fragment *m = g_new (Fragment, 1);
|
||||
State *before, *after;
|
||||
Transition *enter, *exit, *value;
|
||||
|
||||
before = state_new ();
|
||||
after = state_new ();
|
||||
|
||||
m->enter = transition_new_begin_value (name, type, NULL, before);
|
||||
m->exit = transition_new_end_value (name, type, after, NULL);
|
||||
value = transition_new_text (type, before, after);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
gpointer
|
||||
sformat_new_pointer (const char *name)
|
||||
{
|
||||
SFormat *sformat = create_sformat (name, POINTER);
|
||||
return sformat;
|
||||
return sformat_new_value (name, POINTER);
|
||||
}
|
||||
|
||||
SFormat *
|
||||
gpointer
|
||||
sformat_new_integer (const char *name)
|
||||
{
|
||||
SFormat *sformat = create_sformat (name, INTEGER);
|
||||
return sformat;
|
||||
return sformat_new_value (name, INTEGER);
|
||||
}
|
||||
|
||||
SFormat *
|
||||
gpointer
|
||||
sformat_new_string (const char *name)
|
||||
{
|
||||
SFormat *sformat = create_sformat (name, STRING);
|
||||
return sformat;
|
||||
return sformat_new_value (name, STRING);
|
||||
}
|
||||
|
||||
static const State *
|
||||
sformat_get_start_state (SFormat *format)
|
||||
{
|
||||
return format->start_state;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sformat_is_end_state (SFormat *format, const State *state)
|
||||
{
|
||||
return format->end_state == state;
|
||||
}
|
||||
|
||||
static const State *
|
||||
state_transition_begin (const State *state, const char *element,
|
||||
TranstionType *type, GError **err)
|
||||
{
|
||||
}
|
||||
|
||||
static const State *
|
||||
state_transition_end (const State *state, const char *element,
|
||||
TransitionType *type, GError **err)
|
||||
{
|
||||
}
|
||||
|
||||
static const State *
|
||||
state_transition_text (const State *state, const char *element,
|
||||
TransitionType *type, GError **err)
|
||||
{
|
||||
}
|
||||
|
||||
/* reading */
|
||||
@ -698,90 +836,3 @@ sfile_load (const char *filename,
|
||||
|
||||
return sfile;
|
||||
}
|
||||
|
||||
/* A transisition can start or end in the 'external state'.
|
||||
* This state just represents something outside the machine.
|
||||
* There is one transition *from* the external state, and
|
||||
* one transition *to* the external state.
|
||||
*/
|
||||
|
||||
#define EXTERNAL_STATE (-1)
|
||||
|
||||
struct Transition
|
||||
{
|
||||
int from, to;
|
||||
|
||||
enum { BEGIN, END, TEXT } type;
|
||||
char *element;
|
||||
};
|
||||
|
||||
struct StateMachine
|
||||
{
|
||||
int n_transitions;
|
||||
Transition *transitions;
|
||||
};
|
||||
|
||||
static void
|
||||
get_machine_info (StateMachine *machine,
|
||||
Transition **enter,
|
||||
Transition **exit,
|
||||
int *n_states)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
make_list_machine (State *external, State *content, )
|
||||
{
|
||||
int n_transitions = content->n_transitions;
|
||||
int n_states, new_state;
|
||||
Transition *enter_trans;
|
||||
Transition *exit_trans;
|
||||
|
||||
get_machine_info (content, &n_states, &enter_trans, &exit_trans);
|
||||
|
||||
new_state = n_states;
|
||||
|
||||
content->transitions = g_renew (Transition, content->transitions, n_transitions + 2);
|
||||
|
||||
content->transitions[n_transitions].from = EXTERNAL_STATE;
|
||||
content->transitions[n_transitions].to = n_states;
|
||||
content->transitions[n_transitions].type = BEGIN;
|
||||
content->transitions[n_transitions].element = g_strdup ("froot");
|
||||
|
||||
content->transitions[n_transitions + 1].to = EXTERNAL_STATE;
|
||||
content->transitions[n_transitions + 1].from = n_states;
|
||||
content->transitions[n_transitions + 1].type = END;
|
||||
content->transitions[n_transitions + 1].element = g_strdup ("froot");
|
||||
|
||||
enter_trans->from = new_state;
|
||||
exit_trans->to = new_state;
|
||||
}
|
||||
|
||||
static void
|
||||
chain_machines (GList *machines, int *enter_state, int *exit_state)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
make_record_machine (GQueue *fields)
|
||||
{
|
||||
Transition *enter_trans;
|
||||
int from = EXTERNAL_STATE;
|
||||
GQueue *state_chain = g_queue_new ();
|
||||
|
||||
g_queue_push_tail (state_chain, EXTERNAL_STATEA);
|
||||
|
||||
for (list = fields->head; list; list = list->next)
|
||||
{
|
||||
StateMachine *machine = list->data;
|
||||
Transition *enter_trans;
|
||||
Transition *exit_trans;
|
||||
|
||||
get_machine_info (machine, NULL, &enter_trans, &exit_trans);
|
||||
enter_trans->from = from;
|
||||
|
||||
if (list->next)
|
||||
get_machine_info (list->next->data, NULL, NULL, next_enterenter_trans->to = to;
|
||||
}
|
||||
}
|
||||
|
||||
34
sfile.h
34
sfile.h
@ -2,29 +2,29 @@ typedef struct SFormat SFormat;
|
||||
typedef struct SFile SFile;
|
||||
|
||||
/* - Describing Types - */
|
||||
|
||||
SFormat * sdesc_new_record (const char *name,
|
||||
SFormat *content,
|
||||
...);
|
||||
SFormat * sdesc_new_list (const char *name,
|
||||
SFormat *content);
|
||||
SFormat * sdesc_new_pointer (const char *name);
|
||||
SFormat * sdesc_new_integer (const char *name);
|
||||
SFormat * sdesc_new_string (const char *name);
|
||||
SFormat *sformat_new (gpointer f);
|
||||
gpointer sformat_new_record (const char *name,
|
||||
SFormat *content,
|
||||
...);
|
||||
gpointer sformat_new_list (const char *name,
|
||||
SFormat *content);
|
||||
gpointer sformat_new_pointer (const char *name);
|
||||
gpointer sformat_new_integer (const char *name);
|
||||
gpointer sformat_new_string (const char *name);
|
||||
|
||||
/* - Reading - */
|
||||
SFile * sfile_load (const char *filename,
|
||||
SFileInput * sfile_load (const char *filename,
|
||||
SFormat *format,
|
||||
GError **err);
|
||||
void sfile_begin_get_record (SFile *file);
|
||||
int sfile_begin_get_list (SFile *file);
|
||||
void sfile_get_pointer (SFile *file,
|
||||
void sfile_begin_get_record (SFileInput *file);
|
||||
int sfile_begin_get_list (SFileInput *file);
|
||||
void sfile_get_pointer (SFileInput *file,
|
||||
gpointer *pointer);
|
||||
void sfile_get_integer (SFile *file,
|
||||
void sfile_get_integer (SFileInput *file,
|
||||
int *integer);
|
||||
void sfile_get_string (SFile *file,
|
||||
void sfile_get_string (SFileInput *file,
|
||||
char **string);
|
||||
void sfile_end_get (SFile *file,
|
||||
void sfile_end_get (SFileInput *file,
|
||||
gpointer object);
|
||||
|
||||
#if 0
|
||||
@ -39,7 +39,7 @@ void sfile_loader_free (SFileLoader *loader);
|
||||
#endif
|
||||
|
||||
/* - Writing - */
|
||||
SFile * sfile_new (SFormat *format);
|
||||
SFileOutput * sfile_output_mew (SFormat *format);
|
||||
void sfile_begin_add_record (SFile *file,
|
||||
gpointer id);
|
||||
void sfile_begin_add_list (SFile *file,
|
||||
|
||||
Reference in New Issue
Block a user