mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 07:00:53 +00:00
*** empty log message ***
This commit is contained in:
427
sfile.c
427
sfile.c
@ -24,156 +24,294 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "sfile.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
|
typedef enum
|
||||||
{
|
{
|
||||||
BEGIN_RECORD,
|
BEGIN_RECORD,
|
||||||
BEGIN_LIST,
|
BEGIN_LIST,
|
||||||
END,
|
END_RECORD,
|
||||||
READ_POINTER,
|
END_LIST,
|
||||||
READ_INTEGER,
|
BEGIN_POINTER,
|
||||||
READ_STRING
|
END_POINTER,
|
||||||
} ReadAction;
|
BEGIN_INTEGER,
|
||||||
|
END_INTEGER,
|
||||||
typedef enum
|
BEGIN_STRING,
|
||||||
{
|
END_STRING
|
||||||
RECORD,
|
|
||||||
LIST,
|
|
||||||
POINTER,
|
POINTER,
|
||||||
INTEGER,
|
INTEGER,
|
||||||
STRING
|
STRING
|
||||||
} SFormatType;
|
} TransitionType;
|
||||||
|
|
||||||
struct SFormat
|
struct Transition
|
||||||
{
|
{
|
||||||
SFormatType type;
|
TransitionType type;
|
||||||
|
State *to;
|
||||||
char *name;
|
char *element; /* for begin/end transitions */
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
GQueue *fields;
|
|
||||||
} record;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
SFormat *content;
|
|
||||||
} list;
|
|
||||||
} u;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReadItem
|
struct State
|
||||||
{
|
{
|
||||||
ReadAction action;
|
GQueue *transitions;
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SFile
|
struct Fragment
|
||||||
{
|
{
|
||||||
int n_items;
|
Transition *enter, *exit;
|
||||||
ReadItem *items;
|
|
||||||
ReadItem *current_item;
|
|
||||||
GHashTable *locations_by_id;
|
|
||||||
GHashTable *objects_by_id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* defining types */
|
SFormat *
|
||||||
|
sformat_new (gpointer f)
|
||||||
static SFormat *
|
|
||||||
create_sformat (const char *name,
|
|
||||||
SFormatType type)
|
|
||||||
{
|
{
|
||||||
SFormat *sformat = g_new0 (SFormat, 1);
|
SFormat *sformat = g_new0 (SFormat, 1);
|
||||||
|
Fragment *fragment = f;
|
||||||
|
|
||||||
sformat->name = g_strdup (name);
|
sformat->begin = state_new ();
|
||||||
sformat->type = type;
|
sformat->end = state_new ();
|
||||||
|
|
||||||
|
g_queue_push_tail (sformat->begin->transitions, f->enter);
|
||||||
|
f->exit->to = sformat->end;
|
||||||
|
|
||||||
|
g_free (fragment);
|
||||||
|
|
||||||
return sformat;
|
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_new_record (const char * name,
|
||||||
SFormat *content1,
|
gpointer content1,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
SFormat *sformat = create_sformat (name, RECORD);
|
GQueue *fragments;
|
||||||
SFormat *field;
|
Transition *enter, *exit;
|
||||||
GQueue *fields = g_queue_new ();
|
State *begin, *end, *state;
|
||||||
|
Fragment *fragment;
|
||||||
|
|
||||||
|
/* Build queue of fragments */
|
||||||
va_start (args, content1);
|
va_start (args, content1);
|
||||||
field = va_arg (args, SFormat *);
|
|
||||||
while (field)
|
fragments = format_queue (args);
|
||||||
{
|
|
||||||
g_queue_push_tail (fields, field);
|
|
||||||
field = va_arg (args, SFormat *);
|
|
||||||
}
|
|
||||||
va_end (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_new_list (const char *name,
|
||||||
SFormat *content)
|
gpointer content)
|
||||||
{
|
{
|
||||||
SFormat *sformat = create_sformat (name, LIST);
|
Fragment *m = content;
|
||||||
sformat->u.list.content = content;
|
State *list_state;
|
||||||
return sformat;
|
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_new_pointer (const char *name)
|
||||||
{
|
{
|
||||||
SFormat *sformat = create_sformat (name, POINTER);
|
return sformat_new_value (name, POINTER);
|
||||||
return sformat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SFormat *
|
gpointer
|
||||||
sformat_new_integer (const char *name)
|
sformat_new_integer (const char *name)
|
||||||
{
|
{
|
||||||
SFormat *sformat = create_sformat (name, INTEGER);
|
return sformat_new_value (name, INTEGER);
|
||||||
return sformat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SFormat *
|
gpointer
|
||||||
sformat_new_string (const char *name)
|
sformat_new_string (const char *name)
|
||||||
{
|
{
|
||||||
SFormat *sformat = create_sformat (name, STRING);
|
return sformat_new_value (name, STRING);
|
||||||
return sformat;
|
}
|
||||||
|
|
||||||
|
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 */
|
/* reading */
|
||||||
@ -698,90 +836,3 @@ sfile_load (const char *filename,
|
|||||||
|
|
||||||
return sfile;
|
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;
|
typedef struct SFile SFile;
|
||||||
|
|
||||||
/* - Describing Types - */
|
/* - Describing Types - */
|
||||||
|
SFormat *sformat_new (gpointer f);
|
||||||
SFormat * sdesc_new_record (const char *name,
|
gpointer sformat_new_record (const char *name,
|
||||||
SFormat *content,
|
SFormat *content,
|
||||||
...);
|
...);
|
||||||
SFormat * sdesc_new_list (const char *name,
|
gpointer sformat_new_list (const char *name,
|
||||||
SFormat *content);
|
SFormat *content);
|
||||||
SFormat * sdesc_new_pointer (const char *name);
|
gpointer sformat_new_pointer (const char *name);
|
||||||
SFormat * sdesc_new_integer (const char *name);
|
gpointer sformat_new_integer (const char *name);
|
||||||
SFormat * sdesc_new_string (const char *name);
|
gpointer sformat_new_string (const char *name);
|
||||||
|
|
||||||
/* - Reading - */
|
/* - Reading - */
|
||||||
SFile * sfile_load (const char *filename,
|
SFileInput * sfile_load (const char *filename,
|
||||||
SFormat *format,
|
SFormat *format,
|
||||||
GError **err);
|
GError **err);
|
||||||
void sfile_begin_get_record (SFile *file);
|
void sfile_begin_get_record (SFileInput *file);
|
||||||
int sfile_begin_get_list (SFile *file);
|
int sfile_begin_get_list (SFileInput *file);
|
||||||
void sfile_get_pointer (SFile *file,
|
void sfile_get_pointer (SFileInput *file,
|
||||||
gpointer *pointer);
|
gpointer *pointer);
|
||||||
void sfile_get_integer (SFile *file,
|
void sfile_get_integer (SFileInput *file,
|
||||||
int *integer);
|
int *integer);
|
||||||
void sfile_get_string (SFile *file,
|
void sfile_get_string (SFileInput *file,
|
||||||
char **string);
|
char **string);
|
||||||
void sfile_end_get (SFile *file,
|
void sfile_end_get (SFileInput *file,
|
||||||
gpointer object);
|
gpointer object);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -39,7 +39,7 @@ void sfile_loader_free (SFileLoader *loader);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* - Writing - */
|
/* - Writing - */
|
||||||
SFile * sfile_new (SFormat *format);
|
SFileOutput * sfile_output_mew (SFormat *format);
|
||||||
void sfile_begin_add_record (SFile *file,
|
void sfile_begin_add_record (SFile *file,
|
||||||
gpointer id);
|
gpointer id);
|
||||||
void sfile_begin_add_list (SFile *file,
|
void sfile_begin_add_list (SFile *file,
|
||||||
|
|||||||
Reference in New Issue
Block a user