mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 16:10:54 +00:00
*** empty log message ***
This commit is contained in:
306
sfile.c
306
sfile.c
@ -1,23 +1,5 @@
|
|||||||
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
|
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
/* Lac - Library for asynchronous communication
|
|
||||||
* Copyright (C) 2004 Søren Sandmann (sandmann@daimi.au.dk)
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Library General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Library General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this library; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
* Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -86,12 +68,12 @@ struct Action
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
} begin_record;
|
} begin_record;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int n_items;
|
int n_items;
|
||||||
} begin_list;
|
} begin_list;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
@ -101,12 +83,12 @@ struct Action
|
|||||||
{
|
{
|
||||||
gpointer *location;
|
gpointer *location;
|
||||||
} pointer;
|
} pointer;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
} integer;
|
} integer;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char *value;
|
char *value;
|
||||||
@ -121,9 +103,9 @@ set_error (GError **err, gint code, const char *format, va_list args)
|
|||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
msg = g_strdup_vprintf (format, args);
|
msg = g_strdup_vprintf (format, args);
|
||||||
|
|
||||||
if (*err == NULL)
|
if (*err == NULL)
|
||||||
{
|
{
|
||||||
*err = g_error_new_literal (G_MARKUP_ERROR, code, msg);
|
*err = g_error_new_literal (G_MARKUP_ERROR, code, msg);
|
||||||
@ -136,7 +118,7 @@ set_error (GError **err, gint code, const char *format, va_list args)
|
|||||||
"The overwriting error message was: %s",
|
"The overwriting error message was: %s",
|
||||||
msg);
|
msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (msg);
|
g_free (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,14 +161,14 @@ static Transition *
|
|||||||
transition_new (const char *element, TransitionType type, State *from, State *to)
|
transition_new (const char *element, TransitionType type, State *from, State *to)
|
||||||
{
|
{
|
||||||
Transition *t = g_new (Transition, 1);
|
Transition *t = g_new (Transition, 1);
|
||||||
|
|
||||||
t->element = element? g_strdup (element) : NULL;
|
t->element = element? g_strdup (element) : NULL;
|
||||||
t->type = type;
|
t->type = type;
|
||||||
t->to = to;
|
t->to = to;
|
||||||
|
|
||||||
if (from)
|
if (from)
|
||||||
g_queue_push_tail (from->transitions, t);
|
g_queue_push_tail (from->transitions, t);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,13 +177,13 @@ sformat_new (gpointer f)
|
|||||||
{
|
{
|
||||||
SFormat *sformat = g_new0 (SFormat, 1);
|
SFormat *sformat = g_new0 (SFormat, 1);
|
||||||
Fragment *fragment = f;
|
Fragment *fragment = f;
|
||||||
|
|
||||||
sformat->begin = state_new ();
|
sformat->begin = state_new ();
|
||||||
sformat->end = state_new ();
|
sformat->end = state_new ();
|
||||||
|
|
||||||
g_queue_push_tail (sformat->begin->transitions, fragment->enter);
|
g_queue_push_tail (sformat->begin->transitions, fragment->enter);
|
||||||
fragment->exit->to = sformat->end;
|
fragment->exit->to = sformat->end;
|
||||||
|
|
||||||
g_free (fragment);
|
g_free (fragment);
|
||||||
|
|
||||||
return sformat;
|
return sformat;
|
||||||
@ -220,7 +202,7 @@ fragment_queue (va_list args)
|
|||||||
fragment = va_arg (args, Fragment *);
|
fragment = va_arg (args, Fragment *);
|
||||||
}
|
}
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
return fragments;
|
return fragments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,41 +246,41 @@ sformat_new_union (const char *name,
|
|||||||
Transition *enter, *exit;
|
Transition *enter, *exit;
|
||||||
State *begin;
|
State *begin;
|
||||||
State *end;
|
State *end;
|
||||||
|
|
||||||
va_start (args, content1);
|
va_start (args, content1);
|
||||||
|
|
||||||
fragments = fragment_queue (args);
|
fragments = fragment_queue (args);
|
||||||
|
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
begin = state_new ();
|
begin = state_new ();
|
||||||
end = state_new ();
|
end = state_new ();
|
||||||
|
|
||||||
enter = transition_new (name, TRANSITION_BEGIN_UNION, NULL, begin);
|
enter = transition_new (name, TRANSITION_BEGIN_UNION, NULL, begin);
|
||||||
exit = transition_new (name, TRANSITION_END_UNION, 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)
|
||||||
{
|
{
|
||||||
Fragment *fragment = list->data;
|
Fragment *fragment = list->data;
|
||||||
|
|
||||||
g_queue_push_tail (begin->transitions, fragment->enter);
|
g_queue_push_tail (begin->transitions, fragment->enter);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (list = fragments->head; list; list = list->next)
|
for (list = fragments->head; list; list = list->next)
|
||||||
{
|
{
|
||||||
fragment = list->data;
|
fragment = list->data;
|
||||||
|
|
||||||
fragment->exit->to = end;
|
fragment->exit->to = end;
|
||||||
|
|
||||||
g_free (fragment);
|
g_free (fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_queue_free (fragments);
|
g_queue_free (fragments);
|
||||||
|
|
||||||
fragment = g_new (Fragment, 1);
|
fragment = g_new (Fragment, 1);
|
||||||
fragment->enter = enter;
|
fragment->enter = enter;
|
||||||
fragment->exit = exit;
|
fragment->exit = exit;
|
||||||
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -314,12 +296,12 @@ sformat_new_record (const char * name,
|
|||||||
State *begin, *state;
|
State *begin, *state;
|
||||||
Fragment *fragment;
|
Fragment *fragment;
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
/* 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 */
|
||||||
@ -327,7 +309,7 @@ sformat_new_record (const char * name,
|
|||||||
enter = transition_new (name, BEGIN_RECORD, NULL, begin);
|
enter = transition_new (name, BEGIN_RECORD, NULL, begin);
|
||||||
|
|
||||||
state = begin;
|
state = begin;
|
||||||
|
|
||||||
for (list = fragments->head; list != NULL; list = list->next)
|
for (list = fragments->head; list != NULL; list = list->next)
|
||||||
{
|
{
|
||||||
/* At each point in the iteration we need,
|
/* At each point in the iteration we need,
|
||||||
@ -335,13 +317,13 @@ sformat_new_record (const char * name,
|
|||||||
* - a state that will lead into that machine (in state)
|
* - a state that will lead into that machine (in state)
|
||||||
*/
|
*/
|
||||||
fragment = list->data;
|
fragment = list->data;
|
||||||
|
|
||||||
g_queue_push_tail (state->transitions, fragment->enter);
|
g_queue_push_tail (state->transitions, fragment->enter);
|
||||||
|
|
||||||
state = state_new ();
|
state = state_new ();
|
||||||
fragment->exit->to = state;
|
fragment->exit->to = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return resulting fragment */
|
/* Return resulting fragment */
|
||||||
fragment = g_new (Fragment, 1);
|
fragment = g_new (Fragment, 1);
|
||||||
fragment->enter = enter;
|
fragment->enter = enter;
|
||||||
@ -357,7 +339,7 @@ sformat_new_list (const char *name,
|
|||||||
Fragment *m = content;
|
Fragment *m = content;
|
||||||
State *list_state;
|
State *list_state;
|
||||||
Transition *enter, *exit;
|
Transition *enter, *exit;
|
||||||
|
|
||||||
list_state = state_new ();
|
list_state = state_new ();
|
||||||
|
|
||||||
enter = transition_new (name, BEGIN_LIST, NULL, list_state);
|
enter = transition_new (name, BEGIN_LIST, NULL, list_state);
|
||||||
@ -365,10 +347,10 @@ sformat_new_list (const char *name,
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
m->enter = enter;
|
m->enter = enter;
|
||||||
m->exit = exit;
|
m->exit = exit;
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,10 +360,10 @@ sformat_new_value (const char *name, TransitionType type)
|
|||||||
Fragment *m = g_new (Fragment, 1);
|
Fragment *m = g_new (Fragment, 1);
|
||||||
State *before, *after;
|
State *before, *after;
|
||||||
Transition *value;
|
Transition *value;
|
||||||
|
|
||||||
before = state_new ();
|
before = state_new ();
|
||||||
after = state_new ();
|
after = state_new ();
|
||||||
|
|
||||||
m->enter = transition_new (name, type, NULL, before);
|
m->enter = transition_new (name, type, NULL, before);
|
||||||
m->exit = transition_new (name, type, after, NULL);
|
m->exit = transition_new (name, type, after, NULL);
|
||||||
value = transition_new (NULL, type, before, after);
|
value = transition_new (NULL, type, before, after);
|
||||||
@ -425,7 +407,7 @@ state_transition_check (const State *state, const char *element,
|
|||||||
TransitionType *type, GError **err)
|
TransitionType *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;
|
||||||
@ -438,7 +420,7 @@ state_transition_check (const State *state, const char *element,
|
|||||||
return transition->to;
|
return transition->to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_unknown_element_error (err, "<%s> or </%s> unexpected here", element, element);
|
set_unknown_element_error (err, "<%s> or </%s> unexpected here", element, element);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -463,15 +445,14 @@ state_transition_end (const State *state, const char *element,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const State *
|
static const State *
|
||||||
state_transition_text (const State *state, const char *text,
|
state_transition_text (const State *state, TransitionType *type, GError **err)
|
||||||
TransitionType *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 = list->data;
|
Transition *transition = list->data;
|
||||||
|
|
||||||
/* There will never be more than one allowed value transition for
|
/* There will never be more than one allowed value transition for
|
||||||
* a given state
|
* a given state
|
||||||
*/
|
*/
|
||||||
@ -483,8 +464,8 @@ state_transition_text (const State *state, const char *text,
|
|||||||
return transition->to;
|
return transition->to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_invalid_content_error (err, "Unexpected text data unexpected (%s)", text);
|
set_invalid_content_error (err, "Unexpected text data");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,8 +477,7 @@ struct BuildContext
|
|||||||
{
|
{
|
||||||
const State *state;
|
const State *state;
|
||||||
|
|
||||||
Action *actions;
|
GArray *actions;
|
||||||
int n_actions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParseNode
|
struct ParseNode
|
||||||
@ -507,7 +487,7 @@ struct ParseNode
|
|||||||
gpointer id;
|
gpointer id;
|
||||||
GPtrArray *children;
|
GPtrArray *children;
|
||||||
GString *text;
|
GString *text;
|
||||||
|
|
||||||
SFormat *format;
|
SFormat *format;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -544,7 +524,7 @@ void
|
|||||||
sfile_begin_get_record (SFileInput *file, const char *name)
|
sfile_begin_get_record (SFileInput *file, const char *name)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
Action *action = file->current_action++;
|
||||||
|
|
||||||
g_return_if_fail (action->type == BEGIN_RECORD &&
|
g_return_if_fail (action->type == BEGIN_RECORD &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (action->name, name) == 0);
|
||||||
}
|
}
|
||||||
@ -554,10 +534,10 @@ sfile_begin_get_list (SFileInput *file,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
Action *action = file->current_action++;
|
||||||
|
|
||||||
g_return_val_if_fail (action->type == BEGIN_LIST &&
|
g_return_val_if_fail (action->type == BEGIN_LIST &&
|
||||||
strcmp (action->name, name) == 0, 0);
|
strcmp (action->name, name) == 0, 0);
|
||||||
|
|
||||||
return action->u.begin_list.n_items;
|
return action->u.begin_list.n_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,9 +549,9 @@ sfile_get_pointer (SFileInput *file,
|
|||||||
Action *action = file->current_action++;
|
Action *action = file->current_action++;
|
||||||
g_return_if_fail (action->type == POINTER &&
|
g_return_if_fail (action->type == POINTER &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (action->name, name) == 0);
|
||||||
|
|
||||||
action->u.pointer.location = location;
|
action->u.pointer.location = location;
|
||||||
|
|
||||||
if (location)
|
if (location)
|
||||||
{
|
{
|
||||||
if (g_hash_table_lookup (file->actions_by_location, location))
|
if (g_hash_table_lookup (file->actions_by_location, location))
|
||||||
@ -589,7 +569,7 @@ sfile_get_integer (SFileInput *file,
|
|||||||
Action *action = file->current_action++;
|
Action *action = file->current_action++;
|
||||||
g_return_if_fail (action->type == INTEGER &&
|
g_return_if_fail (action->type == INTEGER &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (action->name, name) == 0);
|
||||||
|
|
||||||
if (integer)
|
if (integer)
|
||||||
*integer = action->u.integer.value;
|
*integer = action->u.integer.value;
|
||||||
}
|
}
|
||||||
@ -602,7 +582,7 @@ sfile_get_string (SFileInput *file,
|
|||||||
Action *action = file->current_action++;
|
Action *action = file->current_action++;
|
||||||
g_return_if_fail (action->type == STRING &&
|
g_return_if_fail (action->type == STRING &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (action->name, name) == 0);
|
||||||
|
|
||||||
if (string)
|
if (string)
|
||||||
*string = g_strdup (action->u.string.value);
|
*string = g_strdup (action->u.string.value);
|
||||||
}
|
}
|
||||||
@ -617,7 +597,7 @@ sfile_end_get (SFileInput *file,
|
|||||||
g_return_if_fail ((action->type == END_LIST ||
|
g_return_if_fail ((action->type == END_LIST ||
|
||||||
action->type == END_RECORD) &&
|
action->type == END_RECORD) &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (action->name, name) == 0);
|
||||||
|
|
||||||
if (action->u.end.id)
|
if (action->u.end.id)
|
||||||
g_hash_table_insert (file->objects_by_id,
|
g_hash_table_insert (file->objects_by_id,
|
||||||
GINT_TO_POINTER (action->u.end.id), object);
|
GINT_TO_POINTER (action->u.end.id), object);
|
||||||
@ -636,7 +616,7 @@ get_id (const char **names, const char **values, GError **err)
|
|||||||
set_unknown_attribute_error (err, "Unknown attribute: %s", names[i]);
|
set_unknown_attribute_error (err, "Unknown attribute: %s", names[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id_string)
|
if (id_string)
|
||||||
{
|
{
|
||||||
set_invalid_content_error (err, "Attribute 'id' defined twice");
|
set_invalid_content_error (err, "Attribute 'id' defined twice");
|
||||||
@ -645,7 +625,7 @@ get_id (const char **names, const char **values, GError **err)
|
|||||||
|
|
||||||
id_string = values[i];
|
id_string = values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!id_string)
|
if (!id_string)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -654,7 +634,7 @@ get_id (const char **names, const char **values, GError **err)
|
|||||||
set_invalid_content_error (err, "Bad attribute value for attribute 'id' (must be >= 1)\n");
|
set_invalid_content_error (err, "Bad attribute value for attribute 'id' (must be >= 1)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -669,18 +649,19 @@ handle_begin_element (GMarkupParseContext *parse_context,
|
|||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
Action action;
|
Action action;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
/* Check for id */
|
/* Check for id */
|
||||||
id = get_id (attribute_names, attribute_values, err);
|
id = get_id (attribute_names, attribute_values, err);
|
||||||
|
|
||||||
if (id == -1)
|
if (id == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
build->state = state_transition_begin (build->state, element_name, &action.type, err);
|
|
||||||
|
|
||||||
/* FIXME create action/add to list */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
build->state = state_transition_begin (build->state, element_name, &action.type, err);
|
||||||
|
|
||||||
|
/* FIXME create action/add to list */
|
||||||
|
/* FIXME figure out how to best count the number of items if action.type is a list */
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_end_element (GMarkupParseContext *context,
|
handle_end_element (GMarkupParseContext *context,
|
||||||
const gchar *element_name,
|
const gchar *element_name,
|
||||||
@ -689,9 +670,9 @@ handle_end_element (GMarkupParseContext *context,
|
|||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
Action action;
|
Action action;
|
||||||
|
|
||||||
build->state = state_transition_end (build->state, element_name, &action.type, err);
|
build->state = state_transition_end (build->state, element_name, &action.type, err);
|
||||||
|
|
||||||
/* FIXME create action/add to list */
|
/* FIXME create action/add to list */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,15 +685,30 @@ handle_text (GMarkupParseContext *context,
|
|||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
Action action;
|
Action action;
|
||||||
|
|
||||||
build->state = state_transition_text (build->state, text, &action.type, err);
|
build->state = state_transition_text (build->state, &action.type, err);
|
||||||
|
|
||||||
/* FIXME create acxtion/add to list */
|
/* FIXME create acxtion/add to list */
|
||||||
|
/* FIXME check that the text makes sense according to action.type */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_actions (Action *actions, int n_actions)
|
free_actions (Action *actions, int n_actions)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_actions; ++i)
|
||||||
|
{
|
||||||
|
Action *action = &(actions[i]);
|
||||||
|
|
||||||
|
if (action->name)
|
||||||
|
g_free (action->name);
|
||||||
|
|
||||||
|
if (action->type == STRING)
|
||||||
|
g_free (action->u.string.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Action *
|
static Action *
|
||||||
@ -728,24 +724,25 @@ build_actions (const char *contents, SFormat *format, int *n_actions, GError **e
|
|||||||
NULL, /* passthrough */
|
NULL, /* passthrough */
|
||||||
NULL, /* error */
|
NULL, /* error */
|
||||||
};
|
};
|
||||||
|
|
||||||
build.state = sformat_get_start_state (format);
|
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))
|
if (!sformat_is_end_state (format, build.state))
|
||||||
{
|
{
|
||||||
set_invalid_content_error (err, "Unexpected end of file\n");
|
set_invalid_content_error (err, "Unexpected end of file\n");
|
||||||
|
|
||||||
free_actions (build.actions, build.n_actions);
|
free_actions ((Action *)build.actions->data, build.actions->len);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_markup_parse_context_parse (parse_context, contents, -1, err))
|
if (!g_markup_parse_context_parse (parse_context, contents, -1, err))
|
||||||
{
|
{
|
||||||
free_actions (build.actions, build.n_actions);
|
free_actions ((Action *)build.actions->data, build.actions->len);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return build.actions;
|
*n_actions = build.actions->len;
|
||||||
|
return (Action *)g_array_free (build.actions, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SFileInput *
|
SFileInput *
|
||||||
@ -759,19 +756,132 @@ sfile_load (const char *filename,
|
|||||||
|
|
||||||
if (!g_file_get_contents (filename, &contents, &length, err))
|
if (!g_file_get_contents (filename, &contents, &length, err))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
input = g_new (SFileInput, 1);
|
input = g_new (SFileInput, 1);
|
||||||
|
|
||||||
input->actions = build_actions (contents, format, &input->n_actions, err);
|
input->actions = build_actions (contents, format, &input->n_actions, err);
|
||||||
|
|
||||||
if (!input->actions)
|
if (!input->actions)
|
||||||
{
|
{
|
||||||
g_free (input);
|
g_free (input);
|
||||||
g_free (contents);
|
g_free (contents);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (contents);
|
g_free (contents);
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Writing */
|
||||||
|
|
||||||
|
struct SFileOutput
|
||||||
|
{
|
||||||
|
SFormat *format;
|
||||||
|
const State *state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SFileOutput *
|
||||||
|
sfile_output_mew (SFormat *format)
|
||||||
|
{
|
||||||
|
SFileOutput *output = g_new (SFileOutput, 1);
|
||||||
|
|
||||||
|
output->format = format;
|
||||||
|
output->state = sformat_get_start_state (format);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sfile_begin_add_record (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
|
gpointer id)
|
||||||
|
{
|
||||||
|
TransitionType type;
|
||||||
|
|
||||||
|
file->state = state_transition_begin (file->state, name, &type, NULL);
|
||||||
|
|
||||||
|
g_return_if_fail (file->state && type == BEGIN_RECORD);
|
||||||
|
|
||||||
|
/* FIXME: add action including id */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sfile_begin_add_list (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
|
gpointer id)
|
||||||
|
{
|
||||||
|
TransitionType type;
|
||||||
|
|
||||||
|
file->state = state_transition_begin (file->state, name, &type, NULL);
|
||||||
|
|
||||||
|
g_return_if_fail (file->state && type == BEGIN_LIST);
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sfile_end_add (SFileOutput *file,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
TransitionType type;
|
||||||
|
|
||||||
|
file->state = state_transition_end (file->state, name, &type, NULL);
|
||||||
|
|
||||||
|
g_return_if_fail (file->state && (type == END_RECORD || type == END_LIST));
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sfile_add_string (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
|
const char *string)
|
||||||
|
{
|
||||||
|
TransitionType type;
|
||||||
|
|
||||||
|
file->state = state_transition_begin (file->state, name, &type, NULL);
|
||||||
|
|
||||||
|
g_return_if_fail (file->state && type == BEGIN_STRING);
|
||||||
|
|
||||||
|
file->state = state_transition_text (file->state, &type, NULL);
|
||||||
|
|
||||||
|
g_return_if_fail (file->state && type == STRING);
|
||||||
|
|
||||||
|
file->state = state_transition_end (file->state, name, &type, NULL);
|
||||||
|
|
||||||
|
g_return_if_fail (file->state && type == END_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sfile_add_integer (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
|
int integer)
|
||||||
|
{
|
||||||
|
TransitionType type;
|
||||||
|
|
||||||
|
/* FIXME: check intermediate states */
|
||||||
|
|
||||||
|
file->state = state_transition_begin (file->state, name, &type, NULL);
|
||||||
|
|
||||||
|
file->state = state_transition_text (file->state, &type, NULL);
|
||||||
|
|
||||||
|
file->state = state_transition_end (file->state, name, &type, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sfile_add_pointer (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
|
gpointer pointer)
|
||||||
|
{
|
||||||
|
/* FIMXE */
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
sfile_save (SFileOutput *sfile,
|
||||||
|
const char *filename,
|
||||||
|
GError **err)
|
||||||
|
{
|
||||||
|
return FALSE; /* FIXME */
|
||||||
|
}
|
||||||
|
|||||||
14
sfile.h
14
sfile.h
@ -44,17 +44,29 @@ void sfile_loader_free (SFileLoader *loader);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* - Writing - */
|
/* - Writing - */
|
||||||
|
|
||||||
|
/* FIXME: see if we can't get rid of the names. It should be
|
||||||
|
* possible to pass NULL to state_transition_check() and
|
||||||
|
* have it interprete that as "whatever"
|
||||||
|
*/
|
||||||
|
|
||||||
SFileOutput * sfile_output_mew (SFormat *format);
|
SFileOutput * sfile_output_mew (SFormat *format);
|
||||||
void sfile_begin_add_record (SFileOutput *file,
|
void sfile_begin_add_record (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
gpointer id);
|
gpointer id);
|
||||||
void sfile_begin_add_list (SFileOutput *file,
|
void sfile_begin_add_list (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
gpointer id);
|
gpointer id);
|
||||||
void sfile_end_add (SFileOutput *file);
|
void sfile_end_add (SFileOutput *file,
|
||||||
|
const char *name);
|
||||||
void sfile_add_string (SFileOutput *file,
|
void sfile_add_string (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
const char *string);
|
const char *string);
|
||||||
void sfile_add_integer (SFileOutput *file,
|
void sfile_add_integer (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
int integer);
|
int integer);
|
||||||
void sfile_add_pointer (SFileOutput *file,
|
void sfile_add_pointer (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
gpointer pointer);
|
gpointer pointer);
|
||||||
gboolean sfile_save (SFileOutput *sfile,
|
gboolean sfile_save (SFileOutput *sfile,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
|
|||||||
Reference in New Issue
Block a user