From e97dcc792ae8173c318cd25ec9aed139251f041c Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Date: Sat, 22 Apr 2006 19:08:23 +0000 Subject: [PATCH] updates Various formatting fixes. Sat Apr 22 15:08:01 2006 Soeren Sandmann * TODO: updates * profile.c, sfile.c, sformat.c: Various formatting fixes. --- ChangeLog | 5 + TODO | 15 +- profile.c | 4 +- sfile.c | 207 ++++++++++---------- sformat.c | 577 +++++++++++++++++++++++++++--------------------------- 5 files changed, 416 insertions(+), 392 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba3bce4f..6f9f5fe3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Apr 22 15:08:01 2006 Soeren Sandmann + + * TODO: updates + * profile.c, sfile.c, sformat.c: Various formatting fixes. + Wed Apr 5 11:26:30 2006 Søren Sandmann * TODO: updates diff --git a/TODO b/TODO index 1bb6dc4e..dd498caa 100644 --- a/TODO +++ b/TODO @@ -30,8 +30,6 @@ Before 1.2: * commandline version should check that the output file is writable before starting the profiling. -* screenshot window must be cleared when you press start. - * Maybe report idle time? * Fix (deleted) problem. But more generally, whenever we can't display a @@ -138,7 +136,8 @@ Before 1.2: int id; -> for begins that are pointed to } perhaps even with iterators. Should be compact and suitable for both - input and output.. + input and output. As a first cut, perhaps just split out the + Instruction code. - make the api saner; add format/content structs @@ -312,11 +311,11 @@ Later: Profiling itself it appeared that most of the time was spent in the GMarkup parser - a newer version of sysprof with significantly more compact - Instructions took about 5 seconds, but the profile looked - about the same. + Instructions structure took about 5 seconds, but the profile + looked about the same. The difference between the two versions has to be in page faults/ - memory speed, but the profiles looked identically. - Try and reproduce this result in a more controlled experiment. + memory speed, but the profiles looked similar. + Try and reproduce this in a more controlled experiment. - See if it is possible to group the X server activity under the process that generated it. @@ -495,6 +494,8 @@ Later: DONE: +- screenshot window must be cleared when you press start. + - Formats should become first-class, stand-alone objects that offers help with parsing and nothing else. diff --git a/profile.c b/profile.c index f2bca46a..3dc5bc0b 100644 --- a/profile.c +++ b/profile.c @@ -31,7 +31,7 @@ typedef struct Node Node; struct Profile { - StackStash * stash; + StackStash *stash; }; static SFormat * @@ -470,7 +470,7 @@ profile_free (Profile *profile) } void -profile_descendant_free (ProfileDescendant *descendant) +profile_descendant_free (ProfileDescendant *descendant) { if (!descendant) return; diff --git a/sfile.c b/sfile.c index 9a4c84bc..7f45369b 100644 --- a/sfile.c +++ b/sfile.c @@ -29,60 +29,6 @@ #include "sfile.h" #include "sformat.h" -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); -} - -/* reading */ typedef struct BuildContext BuildContext; typedef struct Instruction Instruction; typedef enum @@ -137,6 +83,63 @@ struct BuildContext GArray *instructions; }; +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); +} + +/* reading */ static gboolean is_all_blank (const char *text) { @@ -212,8 +215,8 @@ sfile_get_pointer (SFileInput *file, instruction = file->current_instruction++; g_return_if_fail (stype_is_pointer (instruction->type)); - - instruction->u.pointer.location = location; + + instruction->u.pointer.location = location; *location = (gpointer) 0xFedeAbe; @@ -227,9 +230,9 @@ sfile_get_pointer (SFileInput *file, } void -sfile_get_integer (SFileInput *file, - const char *name, - gint32 *integer) +sfile_get_integer (SFileInput *file, + const char *name, + gint32 *integer) { Instruction *instruction; @@ -241,9 +244,9 @@ sfile_get_integer (SFileInput *file, } void -sfile_get_string (SFileInput *file, - const char *name, - char **string) +sfile_get_string (SFileInput *file, + const char *name, + char **string) { Instruction *instruction; @@ -259,15 +262,11 @@ hook_up_pointers (SFileInput *file) { int i; -#if 0 - g_print ("emfle\n"); -#endif for (i = 0; i < file->n_instructions; ++i) { Instruction *instruction = &(file->instructions[i]); - if (instruction->kind == VALUE && - stype_is_pointer (instruction->type)) + if (stype_is_pointer (instruction->type)) { gpointer target_object; Instruction *target_instruction; @@ -279,10 +278,6 @@ hook_up_pointers (SFileInput *file) else target_object = NULL; -#if 0 - g_print ("target object: %p\n", target_object); -#endif - *(instruction->u.pointer.location) = target_object; } } @@ -489,7 +484,7 @@ free_instructions (Instruction *instructions, int n_instructions) { Instruction *instruction = &(instructions[i]); - if (instruction->kind == VALUE && stype_is_string (instruction->type)) + if (stype_is_string (instruction->type)) g_free (instruction->u.string.value); } @@ -536,7 +531,9 @@ process_instruction_pairs (Instruction *first) } static gboolean -post_process_read_instructions (Instruction *instructions, int n_instructions, GError **err) +post_process_read_instructions (Instruction *instructions, + int n_instructions, + GError **err) { gboolean retval = TRUE; GHashTable *instructions_by_id; @@ -565,8 +562,7 @@ post_process_read_instructions (Instruction *instructions, int n_instructions, G { Instruction *instruction = &(instructions[i]); - if (instruction->kind == VALUE && - stype_is_pointer (instruction->type)) + if (stype_is_pointer (instruction->type)) { int target_id = instruction->u.pointer.target_id; @@ -610,7 +606,10 @@ post_process_read_instructions (Instruction *instructions, int n_instructions, G } static Instruction * -build_instructions (const char *contents, SFormat *format, int *n_instructions, GError **err) +build_instructions (const char *contents, + SFormat *format, + int *n_instructions, + GError **err) { BuildContext build; GMarkupParseContext *parse_context; @@ -791,9 +790,9 @@ sfile_check_value (SFileOutput *file, } void -sfile_add_string (SFileOutput *file, - const char *name, - const char *string) +sfile_add_string (SFileOutput *file, + const char *name, + const char *string) { Instruction instruction; @@ -812,9 +811,9 @@ sfile_add_string (SFileOutput *file, } void -sfile_add_integer (SFileOutput *file, - const char *name, - int integer) +sfile_add_integer (SFileOutput *file, + const char *name, + int integer) { Instruction instruction; @@ -831,9 +830,9 @@ sfile_add_integer (SFileOutput *file, } void -sfile_add_pointer (SFileOutput *file, - const char *name, - gpointer pointer) +sfile_add_pointer (SFileOutput *file, + const char *name, + gpointer pointer) { Instruction instruction; @@ -898,7 +897,7 @@ post_process_write_instructions (SFileOutput *sfile) if (!target) { g_warning ("pointer has unknown target\n"); - return; + goto out; } g_assert (target->kind == END); @@ -915,11 +914,14 @@ post_process_write_instructions (SFileOutput *sfile) } } } - + +out: + g_hash_table_destroy (instructions_by_object); } static void -add_indent (GString *output, int indent) +add_indent (GString *output, + int indent) { int i; @@ -928,13 +930,15 @@ add_indent (GString *output, int indent) } static void -add_integer (GString *output, int value) +add_integer (GString *output, + int value) { g_string_append_printf (output, "%d", value); } static void -add_string (GString *output, const char *str) +add_string (GString *output, + const char *str) { char *escaped = g_markup_escape_text (str, -1); g_string_append_c (output, '\"'); @@ -944,7 +948,10 @@ add_string (GString *output, const char *str) } static void -add_begin_tag (GString *output, int indent, const char *name, int id) +add_begin_tag (GString *output, + int indent, + const char *name, + int id) { add_indent (output, indent); @@ -955,7 +962,9 @@ add_begin_tag (GString *output, int indent, const char *name, int id) } static void -add_end_tag (GString *output, int indent, const char *name) +add_end_tag (GString *output, + int indent, + const char *name) { add_indent (output, indent); g_string_append_printf (output, "", name); @@ -968,10 +977,10 @@ add_nl (GString *output) } static gboolean -file_replace (const gchar *filename, - const gchar *contents, - gssize length, - GError **error); +file_replace (const gchar *filename, + const gchar *contents, + gssize length, + GError **error); #if 0 static void @@ -1101,8 +1110,10 @@ sfile_output_save (SFileOutput *sfile, { add_string (output, instruction->u.string.value); } + add_end_tag (output, 0, get_name (instruction)); - add_nl (output); + + add_nl (output); break; } } @@ -1127,7 +1138,7 @@ sfile_output_save (SFileOutput *sfile, void -sfile_input_free (SFileInput *file) +sfile_input_free (SFileInput *file) { free_instructions (file->instructions, file->n_instructions); diff --git a/sformat.c b/sformat.c index a98dab0f..08a18bd2 100644 --- a/sformat.c +++ b/sformat.c @@ -62,6 +62,296 @@ struct SType static void type_free (SType *type); +/* + * Transition + */ +typedef enum +{ + BEGIN, + VALUE, + END +} TransitionKind; + +struct Transition +{ + SType * type; + TransitionKind kind; + State * to; +}; + +static Transition *transition_new (SFormat *format, + TransitionKind kind, + SType *type, + State *from, + State *to); +static void transition_free (Transition *transition); +static void transition_set_to_state (Transition *transition, + State *to_state); + +/* + * State + */ + +struct State +{ + GQueue *transitions; +}; + +static State *state_new (SFormat *format); +static void state_add_transition (State *state, + Transition *transition); +static void state_free (State *state); + +/* + * Format + */ +SFormat * +sformat_new (void) +{ + /* FIXME: should probably be refcounted, and an SContext + * should have a ref on the format + */ + SFormat *format = g_new0 (SFormat, 1); + + format->begin = NULL; + format->end = NULL; + + format->types = g_queue_new (); + format->states = g_queue_new (); + format->transitions = g_queue_new (); + + return format; +} + +void +sformat_free (SFormat *format) +{ + GList *list; + + for (list = format->types->head; list; list = list->next) + { + SType *type = list->data; + + type_free (type); + } + g_queue_free (format->types); + + for (list = format->states->head; list; list = list->next) + { + State *state = list->data; + + state_free (state); + } + g_queue_free (format->states); + + for (list = format->transitions->head; list; list = list->next) + { + Transition *transition = list->data; + + transition_free (transition); + } + g_queue_free (format->transitions); + + g_free (format); +} + +void +sformat_set_type (SFormat *format, + SType *type) +{ + format->begin = state_new (format); + format->end = state_new (format); + + state_add_transition (format->begin, type->enter); + transition_set_to_state (type->exit, format->end); +} + +/* + * Type + */ +static SType * +type_new (SFormat *format, + TypeKind kind, + const char *name) +{ + SType *type = g_new0 (SType, 1); + + type->kind = kind; + type->name = name? g_strdup (name) : NULL; + type->enter = NULL; + type->exit = NULL; + type->target = NULL; + + g_queue_push_tail (format->types, type); + + return type; +} + +static SType * +type_new_from_forward (SFormat *format, + TypeKind kind, + const char *name, + SForward *forward) +{ + SType *type; + + if (forward) + { + type = (SType *)forward; + type->kind = kind; + type->name = g_strdup (name); + } + else + { + type = type_new (format, kind, name); + } + + return type; +} + + +static SType * +type_new_value (SFormat *format, TypeKind kind, const char *name) +{ + SType *type = type_new (format, kind, name); + State *before, *after; + Transition *value; + + before = state_new (format); + after = state_new (format); + + type->enter = transition_new (format, BEGIN, type, NULL, before); + type->exit = transition_new (format, END, type, after, NULL); + value = transition_new (format, VALUE, type, before, after); + + return type; +} + +static void +type_free (SType *type) +{ + g_free (type->name); + g_free (type); +} + +SForward * +sformat_declare_forward (SFormat *format) +{ + SType *type = type_new (format, TYPE_FORWARD, NULL); + + return (SForward *)type; +} + + +static GQueue * +expand_varargs (SType *content1, + va_list args) +{ + GQueue *types = g_queue_new (); + SType *type; + + g_queue_push_tail (types, content1); + + type = va_arg (args, SType *); + while (type) + { + g_queue_push_tail (types, type); + type = va_arg (args, SType *); + } + + return types; +} + +SType * +sformat_make_record (SFormat *format, + const char *name, + SForward *forward, + SType *content, + ...) +{ + SType *type; + va_list args; + GQueue *types; + GList *list; + State *begin, *state; + + /* Build queue of child types */ + va_start (args, content); + types = expand_varargs (content, args); + va_end (args); + + /* chain types together */ + state = begin = state_new (format); + + for (list = types->head; list != NULL; list = list->next) + { + SType *child_type = list->data; + + state_add_transition (state, child_type->enter); + + state = state_new (format); + + transition_set_to_state (child_type->exit, state); + } + + g_queue_free (types); + + /* create and return the new type */ + type = type_new_from_forward (format, TYPE_RECORD, name, forward); + type->enter = transition_new (format, BEGIN, type, NULL, begin); + type->exit = transition_new (format, END, type, state, NULL); + + return type; +} + +SType * +sformat_make_list (SFormat *format, + const char *name, + SForward *forward, + SType *child_type) +{ + SType *type; + State *list_state; + + type = type_new_from_forward (format, TYPE_LIST, name, forward); + + list_state = state_new (format); + + type->enter = transition_new (format, BEGIN, type, NULL, list_state); + type->exit = transition_new (format, END, type, list_state, NULL); + + state_add_transition (list_state, child_type->enter); + transition_set_to_state (child_type->exit, list_state); + + return type; +} + +SType * +sformat_make_pointer (SFormat *format, + const char *name, + SForward *forward) +{ + SType *type = type_new_value (format, TYPE_POINTER, name); + type->target = (SType *)forward; + + return type; +} + +SType * +sformat_make_integer (SFormat *format, + const char *name) +{ + return type_new_value (format, TYPE_INTEGER, name); +} + +SType * +sformat_make_string (SFormat *format, + const char *name) +{ + return type_new_value (format, TYPE_STRING, name); +} + + gboolean stype_is_record (SType *type) @@ -107,291 +397,6 @@ stype_get_name (SType *type) return type->name; } -/* - * Transition - */ -typedef enum -{ - BEGIN, - VALUE, - END -} TransitionKind; - -struct Transition -{ - SType * type; - TransitionKind kind; - State * to; -}; - -static Transition *transition_new (SFormat *format, - TransitionKind kind, - SType *type, - State *from, - State *to); -static void transition_free (Transition *transition); -static void transition_set_to_state (Transition *transition, - State *to_state); - -/* - * State - */ - -struct State -{ - GQueue *transitions; -}; - -static State *state_new (SFormat *format); -static void state_add_transition (State *state, - Transition *transition); -static void state_free (State *state); - -/* - * Format - */ -SFormat * -sformat_new (void) -{ - /* FIXME: should probably be refcounted, and an SContext - * should have a ref on the format - */ - SFormat *format = g_new0 (SFormat, 1); - - format->begin = NULL; - format->end = NULL; - - format->types = g_queue_new (); - format->states = g_queue_new (); - format->transitions = g_queue_new (); - - return format; -} - -void -sformat_free (SFormat *format) -{ - GList *list; - - for (list = format->types->head; list; list = list->next) - { - SType *type = list->data; - - type_free (type); - } - - for (list = format->states->head; list; list = list->next) - { - State *state = list->data; - - state_free (state); - } - - for (list = format->transitions->head; list; list = list->next) - { - Transition *transition = list->data; - - transition_free (transition); - } - - g_free (format); -} - -void -sformat_set_type (SFormat *format, - SType *type) -{ - format->begin = state_new (format); - format->end = state_new (format); - - state_add_transition (format->begin, type->enter); - transition_set_to_state (type->exit, format->end); - - /* Fix up pointer types */ -} - -/* - * Type - */ -static SType * -type_new (SFormat *format, - TypeKind kind, - const char *name) -{ - SType *type = g_new0 (SType, 1); - - type->kind = kind; - type->name = name? g_strdup (name) : NULL; - type->enter = NULL; - type->exit = NULL; - type->target = NULL; - - g_queue_push_tail (format->types, type); - - return type; -} - -static void -type_free (SType *type) -{ - g_free (type->name); - g_free (type); -} - -static GQueue * -type_queue (SType *content1, - va_list args) -{ - GQueue *types = g_queue_new (); - SType *type; - - g_queue_push_tail (types, content1); - - type = va_arg (args, SType *); - while (type) - { - g_queue_push_tail (types, type); - type = va_arg (args, SType *); - } - - return types; -} - -SForward * -sformat_declare_forward (SFormat *format) -{ - SType *type = type_new (format, TYPE_FORWARD, NULL); - - return (SForward *)type; -} - - -SType * -sformat_make_record (SFormat *format, - const char *name, - SForward *forward, - SType *content, - ...) -{ - SType *type; - va_list args; - GQueue *types; - GList *list; - State *begin, *state; - - /* Build queue of child types */ - va_start (args, content); - types = type_queue (content, args); - va_end (args); - - /* chain types together */ - state = begin = state_new (format); - - for (list = types->head; list != NULL; list = list->next) - { - SType *child_type = list->data; - - state_add_transition (state, child_type->enter); - - state = state_new (format); - - transition_set_to_state (child_type->exit, state); - } - - g_queue_free (types); - - /* Return resulting fragment */ - if (forward) - { - type = (SType *)forward; - type->kind = TYPE_RECORD; - type->name = g_strdup (name); - } - else - { - type = type_new (format, TYPE_RECORD, name); - } - - type->enter = transition_new (format, BEGIN, type, NULL, begin); - type->exit = transition_new (format, END, type, state, NULL); - - return type; -} - -SType * -sformat_make_list (SFormat *format, - const char *name, - SForward *forward, - SType *child_type) -{ - SType *type; - State *list_state; - - if (forward) - { - type = (SType *)forward; - type->kind = TYPE_LIST; - type->name = g_strdup (name); - } - else - { - type = type_new (format, TYPE_LIST, name); - } - - list_state = state_new (format); - - type->enter = transition_new (format, BEGIN, type, NULL, list_state); - type->exit = transition_new (format, END, type, list_state, NULL); - - state_add_transition (list_state, child_type->enter); - transition_set_to_state (child_type->exit, list_state); - - return type; -} - -static SType * -type_new_value (SFormat *format, TypeKind kind, const char *name) -{ - SType *type = type_new (format, kind, name); - State *before, *after; - Transition *value; - - before = state_new (format); - after = state_new (format); - - type->enter = transition_new (format, BEGIN, type, NULL, before); - type->exit = transition_new (format, END, type, after, NULL); - value = transition_new (format, VALUE, type, before, after); - - return type; -} - -SType * -sformat_make_pointer (SFormat *format, - const char *name, - SForward *forward) -{ - SType *type = type_new_value (format, TYPE_POINTER, name); - type->target = (SType *)forward; - - return type; -} - -SType * -sformat_make_integer (SFormat *format, - const char *name) -{ - return type_new_value (format, TYPE_INTEGER, name); -} - -SType * -sformat_make_string (SFormat *format, - const char *name) -{ - return type_new_value (format, TYPE_STRING, name); -} - - /* Consider adding unions at some point * * To be useful they should probably be anonymous, so that @@ -414,6 +419,8 @@ sformat_make_string (SFormat *format, * elements. That will make things a lot easier, and unions are * still pretty useful if you put big things like lists in them. * + * Or maybe just give them a name ... + * * 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