mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 07:00:53 +00:00
more sfile work
This commit is contained in:
319
sfile.c
319
sfile.c
@ -79,8 +79,8 @@ struct Fragment
|
|||||||
struct Action
|
struct Action
|
||||||
{
|
{
|
||||||
TransitionType type;
|
TransitionType type;
|
||||||
char *name;
|
|
||||||
|
|
||||||
|
char *name;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
@ -114,6 +114,59 @@ struct Action
|
|||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_error (GError **err, gint code, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
char *msg;
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
return;
|
||||||
|
|
||||||
|
msg = g_strdup_vprintf (format, args);
|
||||||
|
|
||||||
|
if (*err == NULL)
|
||||||
|
{
|
||||||
|
*err = g_error_new_literal (G_MARKUP_ERROR, code, msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Warning text from GLib */
|
||||||
|
g_warning ("GError set over the top of a previous GError or uninitialized memory.\n"
|
||||||
|
"This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n"
|
||||||
|
"The overwriting error message was: %s",
|
||||||
|
msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_unknown_element_error (GError **err, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start (args, format);
|
||||||
|
set_error (err, G_MARKUP_ERROR_UNKNOWN_ELEMENT, format, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_unknown_attribute_error (GError **err, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start (args, format);
|
||||||
|
set_error (err, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, format, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_invalid_content_error (GError **err, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start (args, format);
|
||||||
|
set_error (err, G_MARKUP_ERROR_INVALID_CONTENT, format, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
static State *
|
static State *
|
||||||
state_new (void)
|
state_new (void)
|
||||||
{
|
{
|
||||||
@ -123,93 +176,18 @@ state_new (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Transition *
|
static Transition *
|
||||||
transition_new_begin_union (const char *name, State *from, State *to)
|
transition_new (const char *element, TransitionType type, State *from, State *to)
|
||||||
{
|
{
|
||||||
return NULL; /* FIXME */
|
Transition *t = g_new (Transition, 1);
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
t->element = element? g_strdup (element) : NULL;
|
||||||
transition_new_end_union (const char *name, State *from, State *to)
|
t->type = type;
|
||||||
{
|
t->to = to;
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
if (from)
|
||||||
transition_new_begin_record (const char *name, State *from, State *to)
|
g_queue_push_tail (from->transitions, t);
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
return t;
|
||||||
transition_new_end_record (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_begin_pointer (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_end_pointer (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_begin_integer (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_end_integer (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_begin_string (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_end_string (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_begin_list (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_end_list (const char *name, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_begin_value (const char *name, TransitionType type, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_end_value (const char *name, TransitionType type, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
static Transition *
|
|
||||||
transition_new_value (TransitionType type, State *from, State *to)
|
|
||||||
{
|
|
||||||
return NULL; /* FIXME */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SFormat *
|
SFormat *
|
||||||
@ -246,6 +224,7 @@ fragment_queue (va_list args)
|
|||||||
return fragments;
|
return fragments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Consider adding unions at some point
|
/* Consider adding unions at some point
|
||||||
*
|
*
|
||||||
* To be useful they should probably be anonymous, so that
|
* To be useful they should probably be anonymous, so that
|
||||||
@ -295,8 +274,8 @@ sformat_new_union (const char *name,
|
|||||||
begin = state_new ();
|
begin = state_new ();
|
||||||
end = state_new ();
|
end = state_new ();
|
||||||
|
|
||||||
enter = transition_new_begin_union (name, NULL, begin);
|
enter = transition_new (name, TRANSITION_BEGIN_UNION, NULL, begin);
|
||||||
exit = transition_new_end_union (name, end, NULL);
|
exit = transition_new (name, TRANSITION_END_UNION, end, NULL);
|
||||||
|
|
||||||
for (list = fragments->head; list; list = list->next)
|
for (list = fragments->head; list; list = list->next)
|
||||||
{
|
{
|
||||||
@ -322,6 +301,7 @@ sformat_new_union (const char *name,
|
|||||||
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
sformat_new_record (const char * name,
|
sformat_new_record (const char * name,
|
||||||
@ -337,14 +317,14 @@ sformat_new_record (const char * name,
|
|||||||
|
|
||||||
/* Build queue of fragments */
|
/* Build queue of fragments */
|
||||||
va_start (args, content1);
|
va_start (args, content1);
|
||||||
|
|
||||||
fragments = fragment_queue (args);
|
fragments = fragment_queue (args);
|
||||||
|
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
/* chain fragments together */
|
/* chain fragments together */
|
||||||
begin = state_new ();
|
begin = state_new ();
|
||||||
enter = transition_new_begin_record (name, NULL, begin);
|
enter = transition_new (name, BEGIN_RECORD, NULL, begin);
|
||||||
|
|
||||||
state = begin;
|
state = begin;
|
||||||
|
|
||||||
@ -365,7 +345,7 @@ sformat_new_record (const char * name,
|
|||||||
/* Return resulting fragment */
|
/* Return resulting fragment */
|
||||||
fragment = g_new (Fragment, 1);
|
fragment = g_new (Fragment, 1);
|
||||||
fragment->enter = enter;
|
fragment->enter = enter;
|
||||||
fragment->exit = transition_new_end_record (name, state, NULL);
|
fragment->exit = transition_new (name, END_RECORD, state, NULL);
|
||||||
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
@ -380,8 +360,8 @@ sformat_new_list (const char *name,
|
|||||||
|
|
||||||
list_state = state_new ();
|
list_state = state_new ();
|
||||||
|
|
||||||
enter = transition_new_begin_list (name, NULL, list_state);
|
enter = transition_new (name, BEGIN_LIST, NULL, list_state);
|
||||||
exit = transition_new_end_list (name, list_state, NULL);
|
exit = transition_new (name, END_LIST, 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;
|
||||||
@ -392,7 +372,7 @@ sformat_new_list (const char *name,
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
static gpointer
|
||||||
sformat_new_value (const char *name, TransitionType type)
|
sformat_new_value (const char *name, TransitionType type)
|
||||||
{
|
{
|
||||||
Fragment *m = g_new (Fragment, 1);
|
Fragment *m = g_new (Fragment, 1);
|
||||||
@ -402,9 +382,9 @@ sformat_new_value (const char *name, TransitionType type)
|
|||||||
before = state_new ();
|
before = state_new ();
|
||||||
after = state_new ();
|
after = state_new ();
|
||||||
|
|
||||||
m->enter = transition_new_begin_value (name, type, NULL, before);
|
m->enter = transition_new (name, type, NULL, before);
|
||||||
m->exit = transition_new_end_value (name, type, after, NULL);
|
m->exit = transition_new (name, type, after, NULL);
|
||||||
value = transition_new_value (type, before, after);
|
value = transition_new (NULL, type, before, after);
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@ -459,7 +439,8 @@ state_transition_check (const State *state, const char *element,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: generate appropriate error */
|
set_unknown_element_error (err, "<%s> or </%s> unexpected here", element, element);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,27 +472,20 @@ state_transition_text (const State *state, const char *text,
|
|||||||
{
|
{
|
||||||
Transition *transition = list->data;
|
Transition *transition = list->data;
|
||||||
|
|
||||||
if ((transition->type >= FIRST_BEGIN_TRANSITION &&
|
/* There will never be more than one allowed value transition for
|
||||||
transition->type <= LAST_BEGIN_TRANSITION) ||
|
* a given state
|
||||||
(transition->type >= FIRST_END_TRANSITION &&
|
*/
|
||||||
transition->type <= LAST_END_TRANSITION))
|
if (transition->type == POINTER ||
|
||||||
|
transition->type == INTEGER ||
|
||||||
|
transition->type == STRING)
|
||||||
{
|
{
|
||||||
continue;
|
*type = transition->type;
|
||||||
}
|
return transition->to;
|
||||||
|
|
||||||
if (transition->type == POINTER)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (transition->type == INTEGER)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (transition->type == STRING)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_invalid_content_error (err, "Unexpected text data unexpected (%s)", text);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reading */
|
/* reading */
|
||||||
@ -520,7 +494,8 @@ typedef struct ParseNode ParseNode;
|
|||||||
|
|
||||||
struct BuildContext
|
struct BuildContext
|
||||||
{
|
{
|
||||||
State *state;
|
const State *state;
|
||||||
|
|
||||||
Action *actions;
|
Action *actions;
|
||||||
int n_actions;
|
int n_actions;
|
||||||
};
|
};
|
||||||
@ -648,22 +623,39 @@ sfile_end_get (SFileInput *file,
|
|||||||
GINT_TO_POINTER (action->u.end.id), object);
|
GINT_TO_POINTER (action->u.end.id), object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseNode *
|
static int
|
||||||
parse_node_new (ParseNode *parent,
|
get_id (const char **names, const char **values, GError **err)
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
ParseNode *node = g_new0 (ParseNode, 1);
|
const char *id_string = NULL;
|
||||||
|
int id, i;
|
||||||
node->parent = parent;
|
|
||||||
node->name = g_strdup (name);
|
|
||||||
node->id = NULL;
|
|
||||||
node->children = g_ptr_array_new ();
|
|
||||||
node->text = g_string_new ("");
|
|
||||||
|
|
||||||
if (parent)
|
|
||||||
g_ptr_array_add (parent->children, node);
|
|
||||||
|
|
||||||
return node;
|
for (i = 0; names[i] != NULL; ++i)
|
||||||
|
{
|
||||||
|
if (strcmp (names[i], "id") != 0)
|
||||||
|
{
|
||||||
|
set_unknown_attribute_error (err, "Unknown attribute: %s", names[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id_string)
|
||||||
|
{
|
||||||
|
set_invalid_content_error (err, "Attribute 'id' defined twice");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
id_string = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!id_string)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!get_number (id_string, &id) || id < 1)
|
||||||
|
{
|
||||||
|
set_invalid_content_error (err, "Bad attribute value for attribute 'id' (must be >= 1)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -675,46 +667,18 @@ handle_begin_element (GMarkupParseContext *parse_context,
|
|||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
const char *id_string;
|
|
||||||
Action action;
|
Action action;
|
||||||
int id;
|
int id;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Check for id */
|
/* Check for id */
|
||||||
id_string = NULL;
|
id = get_id (attribute_names, attribute_values, err);
|
||||||
for (i = 0; attribute_names[i] != NULL; ++i)
|
|
||||||
{
|
|
||||||
if (strcmp (attribute_names[i], "id") == 0)
|
|
||||||
{
|
|
||||||
if (id_string)
|
|
||||||
{
|
|
||||||
/* FIXME: error: id defined twice */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id_string = attribute_values[i];
|
|
||||||
|
|
||||||
if (!get_number (id_string, &id) || id < 1)
|
|
||||||
{
|
|
||||||
/* FIXME: bad attribute value for attribute 'id' */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* FIXME: unknown attribute */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* */
|
if (id == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!state_transition_begin (build->state, element_name, &action.type, err))
|
build->state = state_transition_begin (build->state, element_name, &action.type, err);
|
||||||
{
|
|
||||||
/* FIXME: report error */
|
/* FIXME create action/add to list */
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -724,6 +688,11 @@ handle_end_element (GMarkupParseContext *context,
|
|||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
|
Action action;
|
||||||
|
|
||||||
|
build->state = state_transition_end (build->state, element_name, &action.type, err);
|
||||||
|
|
||||||
|
/* FIXME create action/add to list */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -734,10 +703,20 @@ handle_text (GMarkupParseContext *context,
|
|||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
|
Action action;
|
||||||
|
|
||||||
|
build->state = state_transition_text (build->state, text, &action.type, err);
|
||||||
|
|
||||||
|
/* FIXME create acxtion/add to list */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_actions (Action *actions, int n_actions)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static Action *
|
static Action *
|
||||||
build_actions (const char *contents, int *n_actions, GError **err)
|
build_actions (const char *contents, SFormat *format, int *n_actions, GError **err)
|
||||||
{
|
{
|
||||||
BuildContext build;
|
BuildContext build;
|
||||||
GMarkupParseContext *parse_context;
|
GMarkupParseContext *parse_context;
|
||||||
@ -750,11 +729,19 @@ build_actions (const char *contents, int *n_actions, GError **err)
|
|||||||
NULL, /* error */
|
NULL, /* error */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
build.state = sformat_get_start_state (format);
|
||||||
parse_context = g_markup_parse_context_new (&parser, 0, &build, NULL);
|
parse_context = g_markup_parse_context_new (&parser, 0, &build, NULL);
|
||||||
|
if (!sformat_is_end_state (format, build.state))
|
||||||
|
{
|
||||||
|
set_invalid_content_error (err, "Unexpected end of file\n");
|
||||||
|
|
||||||
|
free_actions (build.actions, build.n_actions);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_markup_parse_context_parse (parse_context, contents, -1, err))
|
if (!g_markup_parse_context_parse (parse_context, contents, -1, err))
|
||||||
{
|
{
|
||||||
/* FIXME: free stuff */
|
free_actions (build.actions, build.n_actions);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,7 +762,7 @@ sfile_load (const char *filename,
|
|||||||
|
|
||||||
input = g_new (SFileInput, 1);
|
input = g_new (SFileInput, 1);
|
||||||
|
|
||||||
input->actions = build_actions (contents, &input->n_actions, err);
|
input->actions = build_actions (contents, format, &input->n_actions, err);
|
||||||
|
|
||||||
if (!input->actions)
|
if (!input->actions)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user