mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
CSun Mar 6 22:56:21 2005 Soeren Sandmann <sandmann@redhat.com>
* sfile.c: Generate id's for objects and pointers.
This commit is contained in:
@ -1,3 +1,7 @@
|
|||||||
|
Sun Mar 6 22:56:21 2005 Soeren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* sfile.c: Generate id's for objects and pointers.
|
||||||
|
|
||||||
Sat Mar 5 01:09:33 2005 Soeren Sandmann <sandmann@redhat.com>
|
Sat Mar 5 01:09:33 2005 Soeren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
* sfile.c: Bug fixes. Add actual generation.
|
* sfile.c: Bug fixes. Add actual generation.
|
||||||
|
|||||||
224
sfile.c
224
sfile.c
@ -473,7 +473,7 @@ struct Instruction
|
|||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int n_instructions;
|
int n_elements;
|
||||||
int id;
|
int id;
|
||||||
Instruction *end_instruction;
|
Instruction *end_instruction;
|
||||||
} begin;
|
} begin;
|
||||||
@ -488,8 +488,8 @@ struct Instruction
|
|||||||
{
|
{
|
||||||
int target_id;
|
int target_id;
|
||||||
Instruction *target_instruction;
|
Instruction *target_instruction;
|
||||||
|
gpointer target_object;
|
||||||
gpointer *location;
|
gpointer *location;
|
||||||
gpointer object;
|
|
||||||
} pointer;
|
} pointer;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -573,7 +573,7 @@ sfile_begin_get_list (SFileInput *file,
|
|||||||
g_return_val_if_fail (strcmp (instruction->name, name) == 0, 0);
|
g_return_val_if_fail (strcmp (instruction->name, name) == 0, 0);
|
||||||
g_return_val_if_fail (is_list_type (instruction->type), 0);
|
g_return_val_if_fail (is_list_type (instruction->type), 0);
|
||||||
|
|
||||||
return instruction->u.begin.n_instructions;
|
return instruction->u.begin.n_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -712,6 +712,7 @@ handle_begin_element (GMarkupParseContext *parse_context,
|
|||||||
|
|
||||||
build->state = state_transition_begin (build->state, element_name, &instruction.type, err);
|
build->state = state_transition_begin (build->state, element_name, &instruction.type, err);
|
||||||
instruction.name = g_strdup (element_name);
|
instruction.name = g_strdup (element_name);
|
||||||
|
instruction.kind = BEGIN;
|
||||||
|
|
||||||
g_array_append_val (build->instructions, instruction);
|
g_array_append_val (build->instructions, instruction);
|
||||||
}
|
}
|
||||||
@ -728,6 +729,7 @@ handle_end_element (GMarkupParseContext *context,
|
|||||||
build->state = state_transition_end (build->state, element_name, &instruction.type, err);
|
build->state = state_transition_end (build->state, element_name, &instruction.type, err);
|
||||||
|
|
||||||
instruction.name = g_strdup (element_name);
|
instruction.name = g_strdup (element_name);
|
||||||
|
instruction.kind = END;
|
||||||
|
|
||||||
g_array_append_val (build->instructions, instruction);
|
g_array_append_val (build->instructions, instruction);
|
||||||
}
|
}
|
||||||
@ -762,7 +764,8 @@ handle_text (GMarkupParseContext *context,
|
|||||||
build->state = state_transition_text (build->state, &instruction.type, err);
|
build->state = state_transition_text (build->state, &instruction.type, err);
|
||||||
|
|
||||||
instruction.name = NULL;
|
instruction.name = NULL;
|
||||||
|
instruction.kind = VALUE;
|
||||||
|
|
||||||
switch (instruction.type)
|
switch (instruction.type)
|
||||||
{
|
{
|
||||||
case TYPE_POINTER:
|
case TYPE_POINTER:
|
||||||
@ -824,13 +827,13 @@ static Instruction *
|
|||||||
post_process_instructions_recurse (Instruction *first, GHashTable *instructions_by_id, GError **err)
|
post_process_instructions_recurse (Instruction *first, GHashTable *instructions_by_id, GError **err)
|
||||||
{
|
{
|
||||||
Instruction *instruction;
|
Instruction *instruction;
|
||||||
int n_instructions;
|
int n_elements;
|
||||||
|
|
||||||
g_assert (first->kind == BEGIN);
|
g_assert (first->kind == BEGIN);
|
||||||
|
|
||||||
instruction = first + 1;
|
instruction = first + 1;
|
||||||
|
|
||||||
n_instructions = 0;
|
n_elements = 0;
|
||||||
while (instruction->kind != END)
|
while (instruction->kind != END)
|
||||||
{
|
{
|
||||||
if (instruction->kind == BEGIN)
|
if (instruction->kind == BEGIN)
|
||||||
@ -841,28 +844,52 @@ post_process_instructions_recurse (Instruction *first, GHashTable *instructions_
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (instruction->type == TYPE_POINTER)
|
|
||||||
{
|
|
||||||
int target_id = instruction->u.pointer.target_id;
|
|
||||||
Instruction *target = g_hash_table_lookup (instructions_by_id, GINT_TO_POINTER (target_id));
|
|
||||||
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
set_invalid_content_error (err, "Id %d doesn't reference any record or list\n",
|
|
||||||
instruction->u.pointer.target_id);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
instruction->u.pointer.target_instruction = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
instruction++;
|
instruction++;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_instructions++;
|
n_elements++;
|
||||||
}
|
}
|
||||||
|
|
||||||
first->u.begin.n_instructions = n_instructions;
|
first->u.begin.n_elements = n_elements;
|
||||||
|
first->u.begin.end_instruction = instruction;
|
||||||
|
|
||||||
|
instruction->u.end.begin_instruction = first;
|
||||||
|
|
||||||
|
return instruction + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This functions makes end instructions point to the corresponding
|
||||||
|
* begin instructions, and counts the number of instructions
|
||||||
|
* contained in a begin/end pair
|
||||||
|
*/
|
||||||
|
static Instruction *
|
||||||
|
process_instruction_pairs (Instruction *first)
|
||||||
|
{
|
||||||
|
Instruction *instruction;
|
||||||
|
int n_elements;
|
||||||
|
|
||||||
|
g_assert (first->kind == BEGIN);
|
||||||
|
|
||||||
|
instruction = first + 1;
|
||||||
|
|
||||||
|
n_elements = 0;
|
||||||
|
while (instruction->kind != END)
|
||||||
|
{
|
||||||
|
if (instruction->kind == BEGIN)
|
||||||
|
{
|
||||||
|
instruction = process_instruction_pairs (instruction);
|
||||||
|
if (!instruction)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instruction++;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_elements++;
|
||||||
|
}
|
||||||
|
|
||||||
|
first->u.begin.n_elements = n_elements;
|
||||||
first->u.begin.end_instruction = instruction;
|
first->u.begin.end_instruction = instruction;
|
||||||
|
|
||||||
instruction->u.end.begin_instruction = first;
|
instruction->u.end.begin_instruction = first;
|
||||||
@ -877,6 +904,9 @@ post_process_read_instructions (Instruction *instructions, int n_instructions, G
|
|||||||
GHashTable *instructions_by_id;
|
GHashTable *instructions_by_id;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* count list instructions, check pointers */
|
||||||
|
process_instruction_pairs (instructions);
|
||||||
|
|
||||||
/* Build id->instruction map */
|
/* Build id->instruction map */
|
||||||
instructions_by_id = g_hash_table_new (g_direct_hash, g_direct_equal);
|
instructions_by_id = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
for (i = 0; i < n_instructions; ++i)
|
for (i = 0; i < n_instructions; ++i)
|
||||||
@ -892,9 +922,27 @@ post_process_read_instructions (Instruction *instructions, int n_instructions, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count list instructions, check pointers */
|
/* Make pointer instructions point to the corresponding element */
|
||||||
if (!post_process_instructions_recurse (instructions, instructions_by_id, err))
|
for (i = 0; i < n_instructions; ++i)
|
||||||
retval = FALSE;
|
{
|
||||||
|
Instruction *instruction = &(instructions[i]);
|
||||||
|
|
||||||
|
if (instruction->type == TYPE_POINTER)
|
||||||
|
{
|
||||||
|
int target_id = instruction->u.pointer.target_id;
|
||||||
|
|
||||||
|
Instruction *target = g_hash_table_lookup (instructions_by_id,
|
||||||
|
GINT_TO_POINTER (target_id));
|
||||||
|
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
set_invalid_content_error (err, "Id %d doesn't reference any record or list\n",
|
||||||
|
instruction->u.pointer.target_id);
|
||||||
|
retval = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_hash_table_destroy (instructions_by_id);
|
g_hash_table_destroy (instructions_by_id);
|
||||||
|
|
||||||
@ -934,7 +982,8 @@ build_instructions (const char *contents, SFormat *format, int *n_instructions,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!post_process_read_instructions ((Instruction *)build.instructions->data, build.instructions->len, err))
|
if (!post_process_read_instructions ((Instruction *)build.instructions->data,
|
||||||
|
build.instructions->len, err))
|
||||||
{
|
{
|
||||||
free_instructions ((Instruction *)build.instructions->data, build.instructions->len);
|
free_instructions ((Instruction *)build.instructions->data, build.instructions->len);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -977,10 +1026,10 @@ struct SFileOutput
|
|||||||
{
|
{
|
||||||
SFormat *format;
|
SFormat *format;
|
||||||
GArray *instructions;
|
GArray *instructions;
|
||||||
|
GHashTable *objects;
|
||||||
const State *state;
|
const State *state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
SFileOutput *
|
SFileOutput *
|
||||||
sfile_output_new (SFormat *format)
|
sfile_output_new (SFormat *format)
|
||||||
{
|
{
|
||||||
@ -989,6 +1038,7 @@ sfile_output_new (SFormat *format)
|
|||||||
output->format = format;
|
output->format = format;
|
||||||
output->instructions = g_array_new (TRUE, TRUE, sizeof (Instruction));
|
output->instructions = g_array_new (TRUE, TRUE, sizeof (Instruction));
|
||||||
output->state = sformat_get_start_state (format);
|
output->state = sformat_get_start_state (format);
|
||||||
|
output->objects = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@ -1036,16 +1086,29 @@ sfile_end_add (SFileOutput *file,
|
|||||||
{
|
{
|
||||||
Instruction instruction;
|
Instruction instruction;
|
||||||
|
|
||||||
|
if (object && g_hash_table_lookup (file->objects, object))
|
||||||
|
{
|
||||||
|
g_warning ("Adding the same object (%p) twice", object);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
file->state = state_transition_end (
|
file->state = state_transition_end (
|
||||||
file->state, name, &instruction.type, NULL);
|
file->state, name, &instruction.type, NULL);
|
||||||
|
|
||||||
g_return_if_fail (file->state);
|
if (!file->state)
|
||||||
|
{
|
||||||
|
g_warning ("invalid call of sfile_end_add()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
instruction.kind = END;
|
instruction.kind = END;
|
||||||
instruction.name = g_strdup (name);
|
instruction.name = g_strdup (name);
|
||||||
instruction.u.end.object = object;
|
instruction.u.end.object = object;
|
||||||
|
|
||||||
g_array_append_val (file->instructions, instruction);
|
g_array_append_val (file->instructions, instruction);
|
||||||
|
|
||||||
|
if (object)
|
||||||
|
g_hash_table_insert (file->objects, object, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1113,11 +1176,80 @@ sfile_add_pointer (SFileOutput *file,
|
|||||||
instruction.kind = VALUE;
|
instruction.kind = VALUE;
|
||||||
instruction.type = TYPE_POINTER;
|
instruction.type = TYPE_POINTER;
|
||||||
instruction.name = g_strdup (name);
|
instruction.name = g_strdup (name);
|
||||||
instruction.u.pointer.object = pointer;
|
instruction.u.pointer.target_object = pointer;
|
||||||
|
|
||||||
g_array_append_val (file->instructions, instruction);
|
g_array_append_val (file->instructions, instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_process_write_instructions (SFileOutput *sfile)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Instruction *instructions = (Instruction *)sfile->instructions->data;
|
||||||
|
int n_instructions = sfile->instructions->len;
|
||||||
|
int id;
|
||||||
|
GHashTable *instructions_by_object;
|
||||||
|
|
||||||
|
process_instruction_pairs (instructions);
|
||||||
|
|
||||||
|
/* Set all id's to -1 and create map from objects to instructions */
|
||||||
|
|
||||||
|
instructions_by_object = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
|
||||||
|
for (i = 0; i < n_instructions; ++i)
|
||||||
|
{
|
||||||
|
Instruction *instruction = &(instructions[i]);
|
||||||
|
|
||||||
|
if (instruction->kind == BEGIN)
|
||||||
|
{
|
||||||
|
instruction->u.begin.id = -1;
|
||||||
|
}
|
||||||
|
else if (instruction->kind == END && instruction->u.end.object)
|
||||||
|
{
|
||||||
|
g_hash_table_insert (instructions_by_object,
|
||||||
|
instruction->u.end.object, instruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign an id to all pointed-to instructions */
|
||||||
|
id = 1;
|
||||||
|
for (i = 0; i < n_instructions; ++i)
|
||||||
|
{
|
||||||
|
Instruction *instruction = &(instructions[i]);
|
||||||
|
|
||||||
|
if (instruction->type == TYPE_POINTER)
|
||||||
|
{
|
||||||
|
if (instruction->u.pointer.target_object)
|
||||||
|
{
|
||||||
|
Instruction *target;
|
||||||
|
|
||||||
|
target =
|
||||||
|
g_hash_table_lookup (instructions_by_object,
|
||||||
|
instruction->u.pointer.target_object);
|
||||||
|
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
g_warning ("pointer has unknown target\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (target->kind == END);
|
||||||
|
|
||||||
|
if (target->u.end.begin_instruction->u.begin.id == -1)
|
||||||
|
target->u.end.begin_instruction->u.begin.id = id++;
|
||||||
|
|
||||||
|
instruction->u.pointer.target_id =
|
||||||
|
target->u.end.begin_instruction->u.begin.id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instruction->u.pointer.target_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_indent (GString *output, int indent)
|
add_indent (GString *output, int indent)
|
||||||
{
|
{
|
||||||
@ -1140,10 +1272,14 @@ add_string (GString *output, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_begin_tag (GString *output, int indent, const char *name)
|
add_begin_tag (GString *output, int indent, const char *name, int id)
|
||||||
{
|
{
|
||||||
add_indent (output, indent);
|
add_indent (output, indent);
|
||||||
g_string_append_printf (output, "<%s>", name);
|
|
||||||
|
if (id != -1)
|
||||||
|
g_string_append_printf (output, "<%s id=\"%d\">", name, id);
|
||||||
|
else
|
||||||
|
g_string_append_printf (output, "<%s>", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1168,11 +1304,14 @@ sfile_output_save (SFileOutput *sfile,
|
|||||||
Instruction *instructions;
|
Instruction *instructions;
|
||||||
GString *output;
|
GString *output;
|
||||||
int indent;
|
int indent;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
g_return_val_if_fail (sfile != NULL, FALSE);
|
g_return_val_if_fail (sfile != NULL, FALSE);
|
||||||
|
|
||||||
instructions = (Instruction *)sfile->instructions->data;
|
instructions = (Instruction *)sfile->instructions->data;
|
||||||
|
|
||||||
|
post_process_write_instructions (sfile);
|
||||||
|
|
||||||
indent = 0;
|
indent = 0;
|
||||||
output = g_string_new ("");
|
output = g_string_new ("");
|
||||||
for (i = 0; i < sfile->instructions->len; ++i)
|
for (i = 0; i < sfile->instructions->len; ++i)
|
||||||
@ -1182,7 +1321,8 @@ sfile_output_save (SFileOutput *sfile,
|
|||||||
switch (instruction->kind)
|
switch (instruction->kind)
|
||||||
{
|
{
|
||||||
case BEGIN:
|
case BEGIN:
|
||||||
add_begin_tag (output, indent, instruction->name);
|
add_begin_tag (output, indent, instruction->name,
|
||||||
|
instruction->u.begin.id);
|
||||||
add_nl (output);
|
add_nl (output);
|
||||||
indent += 4;
|
indent += 4;
|
||||||
break;
|
break;
|
||||||
@ -1194,7 +1334,7 @@ sfile_output_save (SFileOutput *sfile,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VALUE:
|
case VALUE:
|
||||||
add_begin_tag (output, indent, instruction->name);
|
add_begin_tag (output, indent, instruction->name, -1);
|
||||||
switch (instruction->type)
|
switch (instruction->type)
|
||||||
{
|
{
|
||||||
case TYPE_INTEGER:
|
case TYPE_INTEGER:
|
||||||
@ -1215,12 +1355,20 @@ sfile_output_save (SFileOutput *sfile,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: write to disk */
|
/* FIXME: don't dump this to stdout */
|
||||||
g_print (output->str);
|
g_print (output->str);
|
||||||
|
|
||||||
g_string_free (output, TRUE);
|
|
||||||
|
|
||||||
return TRUE; /* FIXME */
|
#if 0
|
||||||
|
/* FIXME, cut-and-paste the g_file_write() implementation
|
||||||
|
* as long as it isn't in glib
|
||||||
|
*/
|
||||||
|
retval = g_file_write (filename, output->str, - 1, err);
|
||||||
|
#endif
|
||||||
|
retval = TRUE;
|
||||||
|
|
||||||
|
g_string_free (output, TRUE);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
sfile.h
18
sfile.h
@ -3,6 +3,24 @@ typedef struct SFileInput SFileInput;
|
|||||||
typedef struct SFileOutput SFileOutput;
|
typedef struct SFileOutput SFileOutput;
|
||||||
typedef guint SType;
|
typedef guint SType;
|
||||||
|
|
||||||
|
|
||||||
|
/* A possibly better API/naming scheme
|
||||||
|
*
|
||||||
|
* Serializer *serializer_new (SerializerFormat *format);
|
||||||
|
*
|
||||||
|
* SerializerReadContext *serializer_begin_read (serializer *serialize,
|
||||||
|
* const char *filename,
|
||||||
|
* GError *err);
|
||||||
|
* serializer_get_blah (SerializerReadContext *);
|
||||||
|
* void serialzier_end_read (...);
|
||||||
|
*
|
||||||
|
* SerializerWritecontext *...;
|
||||||
|
* serializer_begin_write (context);
|
||||||
|
* serializer_write_int ();
|
||||||
|
* serializer_end_write (..., GError **err);
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
/* - Describing Types - */
|
/* - Describing Types - */
|
||||||
SFormat *sformat_new (gpointer f);
|
SFormat *sformat_new (gpointer f);
|
||||||
gpointer sformat_new_record (const char *name,
|
gpointer sformat_new_record (const char *name,
|
||||||
|
|||||||
@ -465,13 +465,14 @@ on_reset_clicked (gpointer widget, gpointer data)
|
|||||||
static void
|
static void
|
||||||
on_save_as_clicked (gpointer widget, gpointer data)
|
on_save_as_clicked (gpointer widget, gpointer data)
|
||||||
{
|
{
|
||||||
|
GError *err = NULL;
|
||||||
Application *app = data;
|
Application *app = data;
|
||||||
|
|
||||||
ensure_profile (app);
|
ensure_profile (app);
|
||||||
|
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
if (!profile_save (app->profile, "name.profile", NULL))
|
if (!profile_save (app->profile, "name.profile", &err))
|
||||||
sorry (NULL, "Couldn't save\n");
|
sorry (NULL, "Couldn't save: %s\n", err->message);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
sorry (NULL, "Saving profiles is not yet implemented.");
|
sorry (NULL, "Saving profiles is not yet implemented.");
|
||||||
|
|||||||
Reference in New Issue
Block a user