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:
415
sfile.c
415
sfile.c
@ -9,7 +9,6 @@
|
|||||||
typedef struct State State;
|
typedef struct State State;
|
||||||
typedef struct Transition Transition;
|
typedef struct Transition Transition;
|
||||||
typedef struct Fragment Fragment;
|
typedef struct Fragment Fragment;
|
||||||
typedef struct Action Action;
|
|
||||||
|
|
||||||
struct SFormat
|
struct SFormat
|
||||||
{
|
{
|
||||||
@ -60,44 +59,6 @@ struct Fragment
|
|||||||
Transition *enter, *exit;
|
Transition *enter, *exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Action
|
|
||||||
{
|
|
||||||
TransitionType type;
|
|
||||||
|
|
||||||
char *name;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int n_items;
|
|
||||||
int id;
|
|
||||||
Action *end_action;
|
|
||||||
} begin;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
gpointer object;
|
|
||||||
} end;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int target_id;
|
|
||||||
Action *target_action;
|
|
||||||
gpointer *location;
|
|
||||||
} pointer;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
} integer;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
char *value;
|
|
||||||
} string;
|
|
||||||
} u;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_error (GError **err, gint code, const char *format, va_list args)
|
set_error (GError **err, gint code, const char *format, va_list args)
|
||||||
{
|
{
|
||||||
@ -476,13 +437,51 @@ state_transition_text (const State *state, TransitionType *type, GError **err)
|
|||||||
|
|
||||||
/* reading */
|
/* reading */
|
||||||
typedef struct BuildContext BuildContext;
|
typedef struct BuildContext BuildContext;
|
||||||
typedef struct ParseNode ParseNode;
|
typedef struct ReadItem ReadItem;
|
||||||
|
|
||||||
|
struct ReadItem
|
||||||
|
{
|
||||||
|
TransitionType type;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int n_items;
|
||||||
|
int id;
|
||||||
|
ReadItem *end_item;
|
||||||
|
} begin;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
gpointer object;
|
||||||
|
} end;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int target_id;
|
||||||
|
ReadItem *target_item;
|
||||||
|
gpointer *location;
|
||||||
|
} pointer;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
} integer;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *value;
|
||||||
|
} string;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
struct BuildContext
|
struct BuildContext
|
||||||
{
|
{
|
||||||
const State *state;
|
const State *state;
|
||||||
|
|
||||||
GArray *actions;
|
GArray *items;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -507,32 +506,32 @@ get_number (const char *text, int *number)
|
|||||||
|
|
||||||
struct SFileInput
|
struct SFileInput
|
||||||
{
|
{
|
||||||
int n_actions;
|
int n_items;
|
||||||
Action *actions;
|
ReadItem *items;
|
||||||
Action *current_action;
|
ReadItem *current_item;
|
||||||
GHashTable *actions_by_location;
|
GHashTable *items_by_location;
|
||||||
GHashTable *objects_by_id;
|
GHashTable *objects_by_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
sfile_begin_get_record (SFileInput *file, const char *name)
|
sfile_begin_get_record (SFileInput *file, const char *name)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
ReadItem *item = file->current_item++;
|
||||||
|
|
||||||
g_return_if_fail (action->type == BEGIN_RECORD &&
|
g_return_if_fail (item->type == BEGIN_RECORD &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (item->name, name) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sfile_begin_get_list (SFileInput *file,
|
sfile_begin_get_list (SFileInput *file,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
ReadItem *item = file->current_item++;
|
||||||
|
|
||||||
g_return_val_if_fail (action->type == BEGIN_LIST &&
|
g_return_val_if_fail (item->type == BEGIN_LIST &&
|
||||||
strcmp (action->name, name) == 0, 0);
|
strcmp (item->name, name) == 0, 0);
|
||||||
|
|
||||||
return action->u.begin.n_items;
|
return item->u.begin.n_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -540,20 +539,20 @@ sfile_get_pointer (SFileInput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
gpointer *location)
|
gpointer *location)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
ReadItem *item = file->current_item++;
|
||||||
g_return_if_fail (action->type == POINTER &&
|
g_return_if_fail (item->type == POINTER &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (item->name, name) == 0);
|
||||||
|
|
||||||
action->u.pointer.location = location;
|
item->u.pointer.location = location;
|
||||||
|
|
||||||
*location = (gpointer) 0xFedeAbe;
|
*location = (gpointer) 0xFedeAbe;
|
||||||
|
|
||||||
if (location)
|
if (location)
|
||||||
{
|
{
|
||||||
if (g_hash_table_lookup (file->actions_by_location, location))
|
if (g_hash_table_lookup (file->items_by_location, location))
|
||||||
g_warning ("Reading into the same location twice\n");
|
g_warning ("Reading into the same location twice\n");
|
||||||
|
|
||||||
g_hash_table_insert (file->actions_by_location, location, action);
|
g_hash_table_insert (file->items_by_location, location, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,12 +561,12 @@ sfile_get_integer (SFileInput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
int *integer)
|
int *integer)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
ReadItem *item = file->current_item++;
|
||||||
g_return_if_fail (action->type == INTEGER &&
|
g_return_if_fail (item->type == INTEGER &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (item->name, name) == 0);
|
||||||
|
|
||||||
if (integer)
|
if (integer)
|
||||||
*integer = action->u.integer.value;
|
*integer = item->u.integer.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -575,12 +574,12 @@ sfile_get_string (SFileInput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
char **string)
|
char **string)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
ReadItem *item = file->current_item++;
|
||||||
g_return_if_fail (action->type == STRING &&
|
g_return_if_fail (item->type == STRING &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (item->name, name) == 0);
|
||||||
|
|
||||||
if (string)
|
if (string)
|
||||||
*string = g_strdup (action->u.string.value);
|
*string = g_strdup (item->u.string.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -588,16 +587,16 @@ hook_up_pointers (SFileInput *file)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < file->n_actions; ++i)
|
for (i = 0; i < file->n_items; ++i)
|
||||||
{
|
{
|
||||||
Action *action = &(file->actions[i]);
|
ReadItem *item = &(file->items[i]);
|
||||||
|
|
||||||
if (action->type == POINTER)
|
if (item->type == POINTER)
|
||||||
{
|
{
|
||||||
gpointer target_object =
|
gpointer target_object =
|
||||||
action->u.pointer.target_action->u.begin.end_action->u.end.object;
|
item->u.pointer.target_item->u.begin.end_item->u.end.object;
|
||||||
|
|
||||||
*(action->u.pointer.location) = target_object;
|
*(item->u.pointer.location) = target_object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,15 +606,15 @@ sfile_end_get (SFileInput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
gpointer object)
|
gpointer object)
|
||||||
{
|
{
|
||||||
Action *action = file->current_action++;
|
ReadItem *item = file->current_item++;
|
||||||
|
|
||||||
g_return_if_fail ((action->type == END_LIST ||
|
g_return_if_fail ((item->type == END_LIST ||
|
||||||
action->type == END_RECORD) &&
|
item->type == END_RECORD) &&
|
||||||
strcmp (action->name, name) == 0);
|
strcmp (item->name, name) == 0);
|
||||||
|
|
||||||
action->u.end.object = object;
|
item->u.end.object = object;
|
||||||
|
|
||||||
if (file->current_action == file->actions + file->n_actions)
|
if (file->current_item == file->items + file->n_items)
|
||||||
hook_up_pointers (file);
|
hook_up_pointers (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,17 +662,17 @@ handle_begin_element (GMarkupParseContext *parse_context,
|
|||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
Action action;
|
ReadItem item;
|
||||||
|
|
||||||
action.u.begin.id = get_id (attribute_names, attribute_values, err);
|
item.u.begin.id = get_id (attribute_names, attribute_values, err);
|
||||||
|
|
||||||
if (action.u.begin.id == -1)
|
if (item.u.begin.id == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
build->state = state_transition_begin (build->state, element_name, &action.type, err);
|
build->state = state_transition_begin (build->state, element_name, &item.type, err);
|
||||||
action.name = g_strdup (element_name);
|
item.name = g_strdup (element_name);
|
||||||
|
|
||||||
g_array_append_val (build->actions, action);
|
g_array_append_val (build->items, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -683,13 +682,13 @@ handle_end_element (GMarkupParseContext *context,
|
|||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
Action action;
|
ReadItem item;
|
||||||
|
|
||||||
build->state = state_transition_end (build->state, element_name, &action.type, err);
|
build->state = state_transition_end (build->state, element_name, &item.type, err);
|
||||||
|
|
||||||
action.name = g_strdup (element_name);
|
item.name = g_strdup (element_name);
|
||||||
|
|
||||||
g_array_append_val (build->actions, action);
|
g_array_append_val (build->items, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -717,16 +716,16 @@ handle_text (GMarkupParseContext *context,
|
|||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
BuildContext *build = user_data;
|
BuildContext *build = user_data;
|
||||||
Action action;
|
ReadItem item;
|
||||||
|
|
||||||
build->state = state_transition_text (build->state, &action.type, err);
|
build->state = state_transition_text (build->state, &item.type, err);
|
||||||
|
|
||||||
action.name = NULL;
|
item.name = NULL;
|
||||||
|
|
||||||
switch (action.type)
|
switch (item.type)
|
||||||
{
|
{
|
||||||
case POINTER:
|
case POINTER:
|
||||||
if (!get_number (text, &action.u.pointer.target_id))
|
if (!get_number (text, &item.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);
|
||||||
return;
|
return;
|
||||||
@ -734,7 +733,7 @@ handle_text (GMarkupParseContext *context,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
if (!get_number (text, &action.u.integer.value))
|
if (!get_number (text, &item.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);
|
||||||
return;
|
return;
|
||||||
@ -742,7 +741,7 @@ handle_text (GMarkupParseContext *context,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
if (!decode_text (text, &action.u.string.value))
|
if (!decode_text (text, &item.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);
|
||||||
return;
|
return;
|
||||||
@ -754,117 +753,117 @@ handle_text (GMarkupParseContext *context,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_append_val (build->actions, action);
|
g_array_append_val (build->items, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_actions (Action *actions, int n_actions)
|
free_items (ReadItem *items, int n_items)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < n_actions; ++i)
|
for (i = 0; i < n_items; ++i)
|
||||||
{
|
{
|
||||||
Action *action = &(actions[i]);
|
ReadItem *item = &(items[i]);
|
||||||
|
|
||||||
if (action->name)
|
if (item->name)
|
||||||
g_free (action->name);
|
g_free (item->name);
|
||||||
|
|
||||||
if (action->type == STRING)
|
if (item->type == STRING)
|
||||||
g_free (action->u.string.value);
|
g_free (item->u.string.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (actions);
|
g_free (items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This functions counts the number of items in a list, and
|
/* This functions counts the number of items in each list, and
|
||||||
* matches up pointers with the lists/records they point to.
|
* matches up pointers with the lists/records they point to.
|
||||||
* FIMXE: think of a better name
|
* FIMXE: think of a better name
|
||||||
*/
|
*/
|
||||||
static Action *
|
static ReadItem *
|
||||||
post_process_actions_recurse (Action *first, GHashTable *actions_by_id, GError **err)
|
post_process_items_recurse (ReadItem *first, GHashTable *items_by_id, GError **err)
|
||||||
{
|
{
|
||||||
Action *action;
|
ReadItem *item;
|
||||||
int n_items;
|
int n_items;
|
||||||
|
|
||||||
g_assert (first->type >= FIRST_BEGIN_TRANSITION &&
|
g_assert (first->type >= FIRST_BEGIN_TRANSITION &&
|
||||||
first->type <= LAST_BEGIN_TRANSITION);
|
first->type <= LAST_BEGIN_TRANSITION);
|
||||||
|
|
||||||
action = first + 1;
|
item = first + 1;
|
||||||
|
|
||||||
n_items = 0;
|
n_items = 0;
|
||||||
while (action->type < FIRST_END_TRANSITION ||
|
while (item->type < FIRST_END_TRANSITION ||
|
||||||
action->type > LAST_END_TRANSITION)
|
item->type > LAST_END_TRANSITION)
|
||||||
{
|
{
|
||||||
if (action->type >= FIRST_BEGIN_TRANSITION &&
|
if (item->type >= FIRST_BEGIN_TRANSITION &&
|
||||||
action->type <= LAST_BEGIN_TRANSITION)
|
item->type <= LAST_BEGIN_TRANSITION)
|
||||||
{
|
{
|
||||||
action = post_process_actions_recurse (action, actions_by_id, err);
|
item = post_process_items_recurse (item, items_by_id, err);
|
||||||
if (!action)
|
if (!item)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (action->type == POINTER)
|
if (item->type == POINTER)
|
||||||
{
|
{
|
||||||
int target_id = action->u.pointer.target_id;
|
int target_id = item->u.pointer.target_id;
|
||||||
Action *target = g_hash_table_lookup (actions_by_id, GINT_TO_POINTER (target_id));
|
ReadItem *target = g_hash_table_lookup (items_by_id, GINT_TO_POINTER (target_id));
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
set_invalid_content_error (err, "Id %d doesn't reference any record or list\n",
|
set_invalid_content_error (err, "Id %d doesn't reference any record or list\n",
|
||||||
action->u.pointer.target_id);
|
item->u.pointer.target_id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
action->u.pointer.target_action = target;
|
item->u.pointer.target_item = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
action++;
|
item++;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_items++;
|
n_items++;
|
||||||
}
|
}
|
||||||
|
|
||||||
first->u.begin.n_items = n_items;
|
first->u.begin.n_items = n_items;
|
||||||
first->u.begin.end_action = action;
|
first->u.begin.end_item = item;
|
||||||
|
|
||||||
return action + 1;
|
return item + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
post_process_actions (Action *actions, int n_actions, GError **err)
|
post_process_items (ReadItem *items, int n_items, GError **err)
|
||||||
{
|
{
|
||||||
gboolean retval = TRUE;
|
gboolean retval = TRUE;
|
||||||
GHashTable *actions_by_id;
|
GHashTable *items_by_id;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Build id->action map */
|
/* Build id->item map */
|
||||||
actions_by_id = g_hash_table_new (g_direct_hash, g_direct_equal);
|
items_by_id = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
for (i = 0; i < n_actions; ++i)
|
for (i = 0; i < n_items; ++i)
|
||||||
{
|
{
|
||||||
Action *action = &(actions[i]);
|
ReadItem *item = &(items[i]);
|
||||||
|
|
||||||
if (action->type >= FIRST_BEGIN_TRANSITION &&
|
if (item->type >= FIRST_BEGIN_TRANSITION &&
|
||||||
action->type <= LAST_BEGIN_TRANSITION)
|
item->type <= LAST_BEGIN_TRANSITION)
|
||||||
{
|
{
|
||||||
int id = action->u.begin.id;
|
int id = item->u.begin.id;
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
g_hash_table_insert (actions_by_id, GINT_TO_POINTER (id), action);
|
g_hash_table_insert (items_by_id, GINT_TO_POINTER (id), item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count list items, check pointers */
|
/* count list items, check pointers */
|
||||||
if (!post_process_actions_recurse (actions, actions_by_id, err))
|
if (!post_process_items_recurse (items, items_by_id, err))
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
|
|
||||||
g_hash_table_destroy (actions_by_id);
|
g_hash_table_destroy (items_by_id);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Action *
|
static ReadItem *
|
||||||
build_actions (const char *contents, SFormat *format, int *n_actions, GError **err)
|
build_items (const char *contents, SFormat *format, int *n_items, GError **err)
|
||||||
{
|
{
|
||||||
BuildContext build;
|
BuildContext build;
|
||||||
GMarkupParseContext *parse_context;
|
GMarkupParseContext *parse_context;
|
||||||
@ -878,30 +877,31 @@ build_actions (const char *contents, SFormat *format, int *n_actions, GError **e
|
|||||||
};
|
};
|
||||||
|
|
||||||
build.state = sformat_get_start_state (format);
|
build.state = sformat_get_start_state (format);
|
||||||
|
build.items = g_array_new (TRUE, TRUE, sizeof (ReadItem));
|
||||||
|
|
||||||
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 ((Action *)build.actions->data, build.actions->len);
|
free_items ((ReadItem *)build.items->data, build.items->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 ((Action *)build.actions->data, build.actions->len);
|
free_items ((ReadItem *)build.items->data, build.items->len);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!post_process_actions ((Action *)build.actions->data, build.actions->len, err))
|
if (!post_process_items ((ReadItem *)build.items->data, build.items->len, err))
|
||||||
{
|
{
|
||||||
free_actions ((Action *)build.actions->data, build.actions->len);
|
free_items ((ReadItem *)build.items->data, build.items->len);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*n_actions = build.actions->len;
|
*n_items = build.items->len;
|
||||||
return (Action *)g_array_free (build.actions, FALSE);
|
return (ReadItem *)g_array_free (build.items, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SFileInput *
|
SFileInput *
|
||||||
@ -918,9 +918,9 @@ sfile_load (const char *filename,
|
|||||||
|
|
||||||
input = g_new (SFileInput, 1);
|
input = g_new (SFileInput, 1);
|
||||||
|
|
||||||
input->actions = build_actions (contents, format, &input->n_actions, err);
|
input->items = build_items (contents, format, &input->n_items, err);
|
||||||
|
|
||||||
if (!input->actions)
|
if (!input->items)
|
||||||
{
|
{
|
||||||
g_free (input);
|
g_free (input);
|
||||||
g_free (contents);
|
g_free (contents);
|
||||||
@ -933,10 +933,48 @@ sfile_load (const char *filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Writing */
|
/* Writing */
|
||||||
|
typedef struct WriteItem WriteItem;
|
||||||
|
|
||||||
|
struct WriteItem
|
||||||
|
{
|
||||||
|
TransitionType type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
int id;
|
||||||
|
} begin;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
} end;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
gpointer object;
|
||||||
|
} pointer;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
int value;
|
||||||
|
} integer;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *value;
|
||||||
|
} string;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
struct SFileOutput
|
struct SFileOutput
|
||||||
{
|
{
|
||||||
SFormat *format;
|
SFormat *format;
|
||||||
|
GArray *items;
|
||||||
const State *state;
|
const State *state;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -947,6 +985,7 @@ sfile_output_mew (SFormat *format)
|
|||||||
SFileOutput *output = g_new (SFileOutput, 1);
|
SFileOutput *output = g_new (SFileOutput, 1);
|
||||||
|
|
||||||
output->format = format;
|
output->format = format;
|
||||||
|
output->items = g_array_new (TRUE, TRUE, sizeof (WriteItem));
|
||||||
output->state = sformat_get_start_state (format);
|
output->state = sformat_get_start_state (format);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
@ -956,28 +995,33 @@ void
|
|||||||
sfile_begin_add_record (SFileOutput *file,
|
sfile_begin_add_record (SFileOutput *file,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
Action action;
|
WriteItem item;
|
||||||
TransitionType type;
|
|
||||||
|
|
||||||
file->state = state_transition_begin (file->state, name, &type, NULL);
|
file->state = state_transition_begin (
|
||||||
|
file->state, name, &item.type, NULL);
|
||||||
|
|
||||||
g_return_if_fail (file->state && type == BEGIN_RECORD);
|
g_return_if_fail (file->state && item.type == BEGIN_RECORD);
|
||||||
|
|
||||||
/* FIXME: add action */
|
item.u.begin.name = g_strdup (name);
|
||||||
|
|
||||||
|
g_array_append_val (file->items, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sfile_begin_add_list (SFileOutput *file,
|
sfile_begin_add_list (SFileOutput *file,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
Action action;
|
WriteItem item;
|
||||||
TransitionType type;
|
TransitionType type;
|
||||||
|
|
||||||
file->state = state_transition_begin (file->state, name, &action.type, NULL);
|
file->state = state_transition_begin (
|
||||||
|
file->state, name, &item.type, NULL);
|
||||||
|
|
||||||
g_return_if_fail (file->state && type == BEGIN_LIST);
|
g_return_if_fail (file->state && type == BEGIN_LIST);
|
||||||
|
|
||||||
/* FIXME */
|
item.u.begin.name = g_strdup (name);
|
||||||
|
|
||||||
|
g_array_append_val (file->items, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -985,13 +1029,39 @@ sfile_end_add (SFileOutput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
gpointer object)
|
gpointer object)
|
||||||
{
|
{
|
||||||
|
WriteItem item;
|
||||||
|
|
||||||
|
file->state = state_transition_end (
|
||||||
|
file->state, name, &item.type, NULL);
|
||||||
|
|
||||||
|
g_return_if_fail (file->state &&
|
||||||
|
(item.type == END_RECORD || item.type == END_LIST));
|
||||||
|
|
||||||
|
item.u.end.name = g_strdup (name);
|
||||||
|
|
||||||
|
g_array_append_val (file->items, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TransitionType
|
||||||
|
sfile_add_value (SFileOutput *file,
|
||||||
|
const char *name,
|
||||||
|
TransitionType begin,
|
||||||
|
TransitionType value,
|
||||||
|
TransitionType end)
|
||||||
|
{
|
||||||
|
TransitionType tmp_type;
|
||||||
TransitionType type;
|
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 */
|
file->state = state_transition_begin (file->state, name, &tmp_type, NULL);
|
||||||
|
g_return_if_fail (file->state && tmp_type == begin);
|
||||||
|
|
||||||
|
file->state = state_transition_text (file->state, &type, NULL);
|
||||||
|
g_return_if_fail (file->state && type == value);
|
||||||
|
|
||||||
|
file->state = state_transition_end (file->state, name, &tmp_type, NULL);
|
||||||
|
g_return_if_fail (file->state && tmp_type == end);
|
||||||
|
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -999,22 +1069,7 @@ sfile_add_string (SFileOutput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
const char *string)
|
const char *string)
|
||||||
{
|
{
|
||||||
TransitionType type;
|
sfile_add_value (file, name, BEGIN_STRING, STRING, END_STRING);
|
||||||
|
|
||||||
/* Strings must be utf-8 */
|
|
||||||
g_return_if_fail (g_utf8_validate (string, -1, NULL));
|
|
||||||
|
|
||||||
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
|
void
|
||||||
@ -1022,15 +1077,7 @@ sfile_add_integer (SFileOutput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
int integer)
|
int integer)
|
||||||
{
|
{
|
||||||
TransitionType type;
|
sfile_add_value (file, name, BEGIN_INTEGER, INTEGER, END_INTEGER);
|
||||||
|
|
||||||
/* 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
|
void
|
||||||
@ -1038,7 +1085,7 @@ sfile_add_pointer (SFileOutput *file,
|
|||||||
const char *name,
|
const char *name,
|
||||||
gpointer pointer)
|
gpointer pointer)
|
||||||
{
|
{
|
||||||
/* FIMXE */
|
sfile_add_value (file, name, BEGIN_POINTER, POINTER, END_POINTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|||||||
3
sfile.h
3
sfile.h
@ -47,7 +47,8 @@ void sfile_loader_free (SFileLoader *loader);
|
|||||||
|
|
||||||
/* FIXME: see if we can't get rid of the names. It should be
|
/* FIXME: see if we can't get rid of the names. It should be
|
||||||
= * possible to pass NULL to state_transition_check() and
|
= * possible to pass NULL to state_transition_check() and
|
||||||
* have it interprete that as "whatever"
|
* have it interprete that as "whatever". We would need
|
||||||
|
* a way to get the name back then, though.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SFileOutput * sfile_output_mew (SFormat *format);
|
SFileOutput * sfile_output_mew (SFormat *format);
|
||||||
|
|||||||
@ -304,7 +304,7 @@ on_timer(unsigned long dong)
|
|||||||
{
|
{
|
||||||
struct task_struct *p;
|
struct task_struct *p;
|
||||||
|
|
||||||
static const int cpu_profiler = 1; /* set to 0 to profile disk */
|
static const int cpu_profiler = 0; /* set to 0 to profile disk */
|
||||||
|
|
||||||
for_each_process (p) {
|
for_each_process (p) {
|
||||||
if (p->state == (cpu_profiler? TASK_RUNNING : TASK_UNINTERRUPTIBLE)) {
|
if (p->state == (cpu_profiler? TASK_RUNNING : TASK_UNINTERRUPTIBLE)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user