From f55afb6542b9eb39e56a32dc8a18002ad680ad41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Sat, 11 Aug 2012 07:37:40 +0200 Subject: [PATCH] Put subcategories and symbols in different lists. Removes some ugliness from the code. --- liblogdiag/ld-library-toolbar.c | 10 +-- liblogdiag/ld-library.c | 123 ++++++++++++++++++-------------- liblogdiag/ld-library.h | 10 +-- liblogdiag/ld-symbol-category.c | 110 +++++++++++++++++++++------- liblogdiag/ld-symbol-category.h | 16 +++-- 5 files changed, 175 insertions(+), 94 deletions(-) diff --git a/liblogdiag/ld-library-toolbar.c b/liblogdiag/ld-library-toolbar.c index bd1baae..a4fa383 100644 --- a/liblogdiag/ld-library-toolbar.c +++ b/liblogdiag/ld-library-toolbar.c @@ -391,7 +391,7 @@ reload_library (LdLibraryToolbar *self) { GSList *categories; - categories = (GSList *) ld_library_get_children (self->priv->library); + categories = (GSList *) ld_library_get_categories (self->priv->library); g_slist_foreach (categories, load_category_cb, self); } } @@ -560,7 +560,7 @@ on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data) } else { - const GSList *children, *symbol_iter; + const GSList *symbols, *symbol_iter; SymbolMenuItem *item; gint x, y, menu_width; @@ -576,15 +576,15 @@ on_category_toggle (GtkToggleButton *toggle_button, gpointer user_data) g_object_ref (data->active_button); category_name = ld_symbol_category_get_name (cat); - children = ld_symbol_category_get_children (cat); + symbols = ld_symbol_category_get_symbols (cat); - data->n_items = g_slist_length ((GSList *) children); + data->n_items = g_slist_length ((GSList *) symbols); data->items = g_new (SymbolMenuItem, data->n_items); data->active_item = -1; item = data->items; menu_width = 0; - for (symbol_iter = children; symbol_iter; + for (symbol_iter = symbols; symbol_iter; symbol_iter = symbol_iter->next) { LdRectangle area; diff --git a/liblogdiag/ld-library.c b/liblogdiag/ld-library.c index 31c3797..13242a1 100644 --- a/liblogdiag/ld-library.c +++ b/liblogdiag/ld-library.c @@ -2,7 +2,7 @@ * ld-library.c * * This file is a part of logdiag. - * Copyright Přemysl Janouch 2010 - 2011. All rights reserved. + * Copyright Přemysl Janouch 2010, 2011, 2012. All rights reserved. * * See the file LICENSE for licensing information. * @@ -19,13 +19,15 @@ * @short_description: A symbol library * @see_also: #LdSymbol, #LdSymbolCategory * - * #LdLibrary is used for loading symbols from their files. + * #LdLibrary is used for loading symbols from their files. The library object + * itself is a container for categories, which in turn contain other + * subcategories and the actual symbols. */ /* * LdLibraryPrivate: * @lua: state of the scripting language. - * @children: child objects of the library. + * @children: categories in the library. */ struct _LdLibraryPrivate { @@ -238,7 +240,7 @@ load_category_symbol_cb (LdSymbol *symbol, gpointer user_data) { const gchar *name; LdSymbolCategory *cat; - const GSList *children, *iter; + const GSList *symbols, *iter; g_return_if_fail (LD_IS_SYMBOL (symbol)); g_return_if_fail (LD_IS_SYMBOL_CATEGORY (user_data)); @@ -247,11 +249,11 @@ load_category_symbol_cb (LdSymbol *symbol, gpointer user_data) name = ld_symbol_get_name (symbol); /* Check for name collisions with other symbols. */ - children = ld_symbol_category_get_children (cat); - for (iter = children; iter; iter = iter->next) + /* XXX: This check should probably be in _insert_symbol() and _category(). + * And the warning should show the full path. */ + symbols = ld_symbol_category_get_symbols (cat); + for (iter = symbols; iter; iter = iter->next) { - if (!LD_IS_SYMBOL (iter->data)) - continue; if (!strcmp (name, ld_symbol_get_name (LD_SYMBOL (iter->data)))) { g_warning ("attempted to insert multiple `%s' symbols into" @@ -259,7 +261,7 @@ load_category_symbol_cb (LdSymbol *symbol, gpointer user_data) return; } } - ld_symbol_category_insert_child (cat, G_OBJECT (symbol), -1); + ld_symbol_category_insert_symbol (cat, symbol, -1); } /* @@ -376,7 +378,7 @@ ld_library_load_cb (const gchar *base, const gchar *filename, gpointer userdata) cat = load_category (data->self, filename, base); if (cat) - ld_library_insert_child (data->self, G_OBJECT (cat), -1); + ld_library_insert_category (data->self, cat, -1); data->changed = TRUE; return TRUE; @@ -391,7 +393,6 @@ ld_library_load_cb (const gchar *base, const gchar *filename, gpointer userdata) * * Return value: a symbol object if found, %NULL otherwise. */ -/* XXX: With this level of indentation, this function is really ugly. */ LdSymbol * ld_library_find_symbol (LdLibrary *self, const gchar *identifier) { @@ -405,45 +406,55 @@ ld_library_find_symbol (LdLibrary *self, const gchar *identifier) if (!id_el_start) return NULL; - list = ld_library_get_children (self); - for (id_el = id_el_start; id_el[0]; id_el++) + id_el = id_el_start; + list = self->priv->children; + + /* We need at least one category name plus the symbol name. */ + if (!id_el[0] || !id_el[1]) + goto ld_library_find_symbol_error; + + /* Find the category where the symbol is in. */ + while (1) { - LdSymbolCategory *cat; - LdSymbol *symbol; gboolean found = FALSE; + LdSymbolCategory *cat; for (list_el = list; list_el; list_el = g_slist_next (list_el)) { - /* If the current identifier element is a category (not last) - * and this list element is a category. - */ - if (id_el[1] && LD_IS_SYMBOL_CATEGORY (list_el->data)) + cat = LD_SYMBOL_CATEGORY (list_el->data); + if (!strcmp (*id_el, ld_symbol_category_get_name (cat))) { - cat = LD_SYMBOL_CATEGORY (list_el->data); - if (strcmp (id_el[0], ld_symbol_category_get_name (cat))) - continue; - - list = ld_symbol_category_get_children (cat); found = TRUE; break; } - /* If the current identifier element is a symbol (last) - * and this list element is a symbol. - */ - else if (!id_el[1] && LD_IS_SYMBOL (list_el->data)) - { - symbol = LD_SYMBOL (list_el->data); - if (strcmp (id_el[0], ld_symbol_get_name (symbol))) - continue; - - g_strfreev (id_el_start); - return symbol; - } } if (!found) + goto ld_library_find_symbol_error; + + if (!(id_el++)[2]) + { + list = ld_symbol_category_get_symbols (cat); break; + } + + list = ld_symbol_category_get_subcategories (cat); } + + /* And then the actual symbol. */ + for (list_el = list; list_el; list_el = g_slist_next (list_el)) + { + LdSymbol *symbol; + + symbol = LD_SYMBOL (list_el->data); + if (!strcmp (*id_el, ld_symbol_get_name (symbol))) + { + g_strfreev (id_el_start); + return symbol; + } + } + +ld_library_find_symbol_error: g_strfreev (id_el_start); return NULL; } @@ -468,52 +479,54 @@ ld_library_clear (LdLibrary *self) } /** - * ld_library_insert_child: + * ld_library_insert_category: * @self: an #LdLibrary object. - * @child: the child to be inserted. - * @pos: the position at which the child will be inserted. + * @category: the category to be inserted. + * @pos: the position at which the category will be inserted. * Negative values will append to the end of list. * - * Insert a child into the library. + * Insert a child category into the library. */ void -ld_library_insert_child (LdLibrary *self, GObject *child, gint pos) +ld_library_insert_category (LdLibrary *self, + LdSymbolCategory *category, gint pos) { g_return_if_fail (LD_IS_LIBRARY (self)); - g_return_if_fail (G_IS_OBJECT (child)); + g_return_if_fail (LD_IS_SYMBOL_CATEGORY (category)); - g_object_ref (child); - self->priv->children = g_slist_insert (self->priv->children, child, pos); + g_object_ref (category); + self->priv->children = g_slist_insert (self->priv->children, category, pos); } /** - * ld_library_remove_child: + * ld_library_remove_category: * @self: an #LdLibrary object. - * @child: the child to be removed. + * @category: the category to be removed. * - * Remove a child from the library. + * Remove a child category from the library. */ void -ld_library_remove_child (LdLibrary *self, GObject *child) +ld_library_remove_category (LdLibrary *self, LdSymbolCategory *category) { g_return_if_fail (LD_IS_LIBRARY (self)); - g_return_if_fail (G_IS_OBJECT (child)); + g_return_if_fail (LD_IS_SYMBOL_CATEGORY (category)); - if (g_slist_find (self->priv->children, child)) + if (g_slist_find (self->priv->children, category)) { - g_object_unref (child); - self->priv->children = g_slist_remove (self->priv->children, child); + g_object_unref (category); + self->priv->children = g_slist_remove (self->priv->children, category); } } /** - * ld_library_get_children: + * ld_library_get_categories: * @self: an #LdLibrary object. * - * Return value: (element-type GObject): a list of children. Do not modify. + * Return value: (element-type LdSymbolCategory *): + * a list of child categories. Do not modify. */ const GSList * -ld_library_get_children (LdLibrary *self) +ld_library_get_categories (LdLibrary *self) { g_return_val_if_fail (LD_IS_LIBRARY (self), NULL); return self->priv->children; diff --git a/liblogdiag/ld-library.h b/liblogdiag/ld-library.h index 26521ed..dd05efa 100644 --- a/liblogdiag/ld-library.h +++ b/liblogdiag/ld-library.h @@ -2,7 +2,7 @@ * ld-library.h * * This file is a part of logdiag. - * Copyright Přemysl Janouch 2010. All rights reserved. + * Copyright Přemysl Janouch 2010, 2012. All rights reserved. * * See the file LICENSE for licensing information. * @@ -62,9 +62,11 @@ gboolean ld_library_load (LdLibrary *self, const gchar *directory); LdSymbol *ld_library_find_symbol (LdLibrary *self, const gchar *identifier); void ld_library_clear (LdLibrary *self); -void ld_library_insert_child (LdLibrary *self, GObject *child, gint pos); -void ld_library_remove_child (LdLibrary *self, GObject *child); -const GSList *ld_library_get_children (LdLibrary *self); +void ld_library_insert_category (LdLibrary *self, + LdSymbolCategory *category, gint pos); +void ld_library_remove_category (LdLibrary *self, + LdSymbolCategory *category); +const GSList *ld_library_get_categories (LdLibrary *self); G_END_DECLS diff --git a/liblogdiag/ld-symbol-category.c b/liblogdiag/ld-symbol-category.c index 4ca51de..d8150dc 100644 --- a/liblogdiag/ld-symbol-category.c +++ b/liblogdiag/ld-symbol-category.c @@ -24,14 +24,16 @@ * LdSymbolCategoryPrivate: * @name: the name of this category. * @image_path: path to the image for this category. - * @children: children of this category. + * @symbols: (element-type LdSymbol *): symbols in this category. + * @subcategories: (element-type LdSymbolCategory *) children of this category. */ struct _LdSymbolCategoryPrivate { gchar *name; gchar *human_name; gchar *image_path; - GSList *children; + GSList *symbols; + GSList *subcategories; }; enum @@ -162,8 +164,11 @@ ld_symbol_category_finalize (GObject *gobject) if (self->priv->image_path) g_free (self->priv->image_path); - g_slist_foreach (self->priv->children, (GFunc) g_object_unref, NULL); - g_slist_free (self->priv->children); + g_slist_foreach (self->priv->symbols, (GFunc) g_object_unref, NULL); + g_slist_free (self->priv->symbols); + + g_slist_foreach (self->priv->subcategories, (GFunc) g_object_unref, NULL); + g_slist_free (self->priv->subcategories); /* Chain up to the parent class. */ G_OBJECT_CLASS (ld_symbol_category_parent_class)->finalize (gobject); @@ -287,53 +292,108 @@ ld_symbol_category_get_image_path (LdSymbolCategory *self) } /** - * ld_symbol_category_insert_child: + * ld_symbol_category_insert_symbol: * @self: an #LdSymbolCategory object. - * @child: the child to be inserted. - * @pos: the position at which the child will be inserted. + * @symbol: the symbol to be inserted. + * @pos: the position at which the symbol will be inserted. * Negative values will append to the end of list. * - * Insert a child into the category. + * Insert a symbol into the category. Doesn't check for duplicates. */ void -ld_symbol_category_insert_child (LdSymbolCategory *self, - GObject *child, gint pos) +ld_symbol_category_insert_symbol (LdSymbolCategory *self, + LdSymbol *symbol, gint pos) { g_return_if_fail (LD_IS_SYMBOL_CATEGORY (self)); - g_return_if_fail (G_IS_OBJECT (child)); + g_return_if_fail (LD_IS_SYMBOL (symbol)); - g_object_ref (child); - self->priv->children = g_slist_insert (self->priv->children, child, pos); + g_object_ref (symbol); + self->priv->symbols = g_slist_insert (self->priv->symbols, symbol, pos); } /** - * ld_symbol_category_remove_child: + * ld_symbol_category_remove_symbol: * @self: an #LdSymbolCategory object. - * @child: the child to be removed. + * @symbol: the symbol to be removed. * - * Removes a child from the category. + * Removes a symbol from the category. */ void -ld_symbol_category_remove_child (LdSymbolCategory *self, - GObject *child) +ld_symbol_category_remove_symbol (LdSymbolCategory *self, + LdSymbol *symbol) { g_return_if_fail (LD_IS_SYMBOL_CATEGORY (self)); - g_return_if_fail (G_IS_OBJECT (child)); + g_return_if_fail (LD_IS_SYMBOL (symbol)); - g_object_unref (child); - self->priv->children = g_slist_remove (self->priv->children, child); + g_object_unref (symbol); + self->priv->symbols = g_slist_remove (self->priv->symbols, symbol); } /** - * ld_symbol_category_get_children: + * ld_symbol_category_get_symbols: * @self: an #LdSymbolCategory object. * - * Return value: (element-type GObject): a list of children. Do not modify. + * Return value: (element-type LdSymbol *): a list of symbols. Do not modify. */ const GSList * -ld_symbol_category_get_children (LdSymbolCategory *self) +ld_symbol_category_get_symbols (LdSymbolCategory *self) { g_return_val_if_fail (LD_IS_SYMBOL_CATEGORY (self), NULL); - return self->priv->children; + return self->priv->symbols; +} + + +/** + * ld_symbol_category_insert_subcategory: + * @self: an #LdSymbolCategory object. + * @category: the category to be inserted. + * @pos: the position at which the category will be inserted. + * Negative values will append to the end of list. + * + * Insert a subcategory into the category. Doesn't check for duplicates. + */ +void +ld_symbol_category_insert_subcategory (LdSymbolCategory *self, + LdSymbolCategory *category, gint pos) +{ + g_return_if_fail (LD_IS_SYMBOL_CATEGORY (self)); + g_return_if_fail (LD_IS_SYMBOL_CATEGORY (category)); + + g_object_ref (category); + self->priv->subcategories + = g_slist_insert (self->priv->subcategories, category, pos); +} + +/** + * ld_symbol_category_remove_subcategory: + * @self: an #LdSymbolCategory object. + * @category: the category to be removed. + * + * Removes a subcategory from the category. + */ +void +ld_symbol_category_remove_subcategory (LdSymbolCategory *self, + LdSymbolCategory *category) +{ + g_return_if_fail (LD_IS_SYMBOL_CATEGORY (self)); + g_return_if_fail (LD_IS_SYMBOL_CATEGORY (category)); + + g_object_unref (category); + self->priv->subcategories + = g_slist_remove (self->priv->subcategories, category); +} + +/** + * ld_symbol_category_get_subcategories: + * @self: an #LdSymbolCategory object. + * + * Return value: (element-type LdSymbolCategory *): + * a list of subcategories. Do not modify. + */ +const GSList * +ld_symbol_category_get_subcategories (LdSymbolCategory *self) +{ + g_return_val_if_fail (LD_IS_SYMBOL_CATEGORY (self), NULL); + return self->priv->subcategories; } diff --git a/liblogdiag/ld-symbol-category.h b/liblogdiag/ld-symbol-category.h index 3b1f05b..6913a86 100644 --- a/liblogdiag/ld-symbol-category.h +++ b/liblogdiag/ld-symbol-category.h @@ -66,11 +66,17 @@ void ld_symbol_category_set_image_path (LdSymbolCategory *self, const gchar *image_path); const gchar *ld_symbol_category_get_image_path (LdSymbolCategory *self); -void ld_symbol_category_insert_child (LdSymbolCategory *self, - GObject *child, gint pos); -void ld_symbol_category_remove_child (LdSymbolCategory *self, - GObject *child); -const GSList *ld_symbol_category_get_children (LdSymbolCategory *self); +void ld_symbol_category_insert_symbol (LdSymbolCategory *self, + LdSymbol *symbol, gint pos); +void ld_symbol_category_remove_symbol (LdSymbolCategory *self, + LdSymbol *symbol); +const GSList *ld_symbol_category_get_symbols (LdSymbolCategory *self); + +void ld_symbol_category_insert_subcategory (LdSymbolCategory *self, + LdSymbolCategory *category, gint pos); +void ld_symbol_category_remove_subcategory (LdSymbolCategory *self, + LdSymbolCategory *category); +const GSList *ld_symbol_category_get_subcategories (LdSymbolCategory *self); G_END_DECLS