diff options
Diffstat (limited to 'src/ld-library.c')
-rw-r--r-- | src/ld-library.c | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/src/ld-library.c b/src/ld-library.c deleted file mode 100644 index 37e2bc9..0000000 --- a/src/ld-library.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * ld-library.c - * - * This file is a part of logdiag. - * Copyright Přemysl Janouch 2010 - 2011. All rights reserved. - * - * See the file LICENSE for licensing information. - * - */ - -#include <string.h> - -#include "liblogdiag.h" -#include "config.h" - - -/** - * SECTION:ld-library - * @short_description: A symbol library. - * @see_also: #LdSymbol, #LdSymbolCategory - * - * #LdLibrary is used for loading symbols from their files. - */ - -/* - * LdLibraryPrivate: - * @lua: State of the scripting language. - * @children: Child objects of the library. - */ -struct _LdLibraryPrivate -{ - LdLua *lua; - GSList *children; -}; - -static void ld_library_finalize (GObject *gobject); - -static LdSymbolCategory *load_category (LdLibrary *self, - const gchar *path, const gchar *name); -static gboolean load_category_cb (const gchar *base, - const gchar *filename, gpointer userdata); -static void load_category_symbol_cb (LdSymbol *symbol, gpointer user_data); - -static gchar *read_human_name_from_file (const gchar *filename); - -static gboolean foreach_dir (const gchar *path, - gboolean (*callback) (const gchar *, const gchar *, gpointer), - gpointer userdata, GError **error); -static gboolean ld_library_load_cb - (const gchar *base, const gchar *filename, gpointer userdata); - - -G_DEFINE_TYPE (LdLibrary, ld_library, G_TYPE_OBJECT); - -static void -ld_library_class_init (LdLibraryClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->finalize = ld_library_finalize; - -/** - * LdLibrary::changed: - * @library: The library object. - * - * Contents of the library have changed. - */ - klass->changed_signal = g_signal_new - ("changed", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - g_type_class_add_private (klass, sizeof (LdLibraryPrivate)); -} - -static void -ld_library_init (LdLibrary *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE - (self, LD_TYPE_LIBRARY, LdLibraryPrivate); - - self->priv->lua = ld_lua_new (); - self->priv->children = NULL; -} - -static void -ld_library_finalize (GObject *gobject) -{ - LdLibrary *self; - - self = LD_LIBRARY (gobject); - - g_object_unref (self->priv->lua); - - g_slist_foreach (self->priv->children, (GFunc) g_object_unref, NULL); - g_slist_free (self->priv->children); - - /* Chain up to the parent class. */ - G_OBJECT_CLASS (ld_library_parent_class)->finalize (gobject); -} - -/** - * ld_library_new: - * - * Create an instance. - */ -LdLibrary * -ld_library_new (void) -{ - return g_object_new (LD_TYPE_LIBRARY, NULL); -} - -/* - * foreach_dir: - * - * Call a user-defined function for each file within a directory. - */ -static gboolean -foreach_dir (const gchar *path, - gboolean (*callback) (const gchar *, const gchar *, gpointer), - gpointer userdata, GError **error) -{ - GDir *dir; - const gchar *item; - - g_return_val_if_fail (path != NULL, FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - dir = g_dir_open (path, 0, error); - if (!dir) - return FALSE; - - while ((item = g_dir_read_name (dir))) - { - gchar *filename; - - filename = g_build_filename (path, item, NULL); - if (!callback (item, filename, userdata)) - break; - g_free (filename); - } - g_dir_close (dir); - return TRUE; -} - -/* - * LoadCategoryData: - * - * Data shared between load_category() and load_category_cb(). - */ -typedef struct -{ - LdLibrary *self; - LdSymbolCategory *cat; -} -LoadCategoryData; - -/* - * load_category: - * @self: An #LdLibrary object. - * @path: The path to the category. - * @name: The default name of the category. - * - * Loads a category into the library. - */ -static LdSymbolCategory * -load_category (LdLibrary *self, const gchar *path, const gchar *name) -{ - LdSymbolCategory *cat; - gchar *icon_file, *category_file; - gchar *human_name; - LoadCategoryData data; - - g_return_val_if_fail (LD_IS_LIBRARY (self), NULL); - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); - - if (!g_file_test (path, G_FILE_TEST_IS_DIR)) - goto load_category_fail_1; - - icon_file = g_build_filename (path, "icon.svg", NULL); - if (!g_file_test (icon_file, G_FILE_TEST_IS_REGULAR)) - { - g_warning ("The category in %s has no icon.", path); - goto load_category_fail_2; - } - - category_file = g_build_filename (path, "category.json", NULL); - human_name = read_human_name_from_file (category_file); - if (!human_name) - human_name = g_strdup (name); - - cat = ld_symbol_category_new (name, human_name); - ld_symbol_category_set_image_path (cat, icon_file); - - data.self = self; - data.cat = cat; - foreach_dir (path, load_category_cb, &data, NULL); - - g_free (human_name); - g_free (category_file); - g_free (icon_file); - return cat; - -load_category_fail_2: - g_free (icon_file); -load_category_fail_1: - return NULL; -} - -/* - * load_category_cb: - * - * Load script files from a directory into a symbol category. - */ -static gboolean -load_category_cb (const gchar *base, const gchar *filename, gpointer userdata) -{ - LoadCategoryData *data; - - g_return_val_if_fail (base != NULL, FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (userdata != NULL, FALSE); - - data = (LoadCategoryData *) userdata; - - if (ld_lua_check_file (data->self->priv->lua, filename)) - ld_lua_load_file (data->self->priv->lua, filename, - load_category_symbol_cb, data->cat); - return TRUE; -} - -/* - * load_category_symbol_cb: - * - * Insert newly registered symbols into the category. - */ -static void -load_category_symbol_cb (LdSymbol *symbol, gpointer user_data) -{ - const gchar *name; - LdSymbolCategory *cat; - const GSList *children, *iter; - - g_return_if_fail (LD_IS_SYMBOL (symbol)); - g_return_if_fail (LD_IS_SYMBOL_CATEGORY (user_data)); - - cat = LD_SYMBOL_CATEGORY (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) - { - 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" - " category '%s'.", name, ld_symbol_category_get_name (cat)); - return; - } - } - ld_symbol_category_insert_child (cat, G_OBJECT (symbol), -1); -} - -/* - * read_human_name_from_file: - * @filename: Location of the JSON file. - * - * Read the human name of the processed category. - */ -static gchar * -read_human_name_from_file (const gchar *filename) -{ - const gchar *const *lang; - JsonParser *parser; - JsonNode *root; - JsonObject *object; - GError *error; - - g_return_val_if_fail (filename != NULL, NULL); - - parser = json_parser_new (); - error = NULL; - if (!json_parser_load_from_file (parser, filename, &error)) - { - g_warning ("%s", error->message); - g_error_free (error); - goto read_human_name_from_file_end; - } - - root = json_parser_get_root (parser); - if (!JSON_NODE_HOLDS_OBJECT (root)) - { - g_warning ("Failed to parse '%s': %s", filename, - "The root node is not an object."); - goto read_human_name_from_file_end; - } - - object = json_node_get_object (root); - for (lang = g_get_language_names (); *lang; lang++) - { - const gchar *member; - - if (!json_object_has_member (object, *lang)) - continue; - member = json_object_get_string_member (object, *lang); - - if (member != NULL) - { - gchar *result; - - result = g_strdup (member); - g_object_unref (parser); - return result; - } - } - -read_human_name_from_file_end: - g_object_unref (parser); - return NULL; -} - -/* - * LibraryLoadData: - * - * Data shared between ld_library_load() and ld_library_load_cb(). - */ -typedef struct -{ - LdLibrary *self; - gboolean changed; -} -LibraryLoadData; - -/** - * ld_library_load: - * @self: An #LdLibrary object. - * @directory: A directory to be loaded. - * - * Load the contents of a directory into the library. - */ -gboolean -ld_library_load (LdLibrary *self, const gchar *directory) -{ - LibraryLoadData data; - - g_return_val_if_fail (LD_IS_LIBRARY (self), FALSE); - g_return_val_if_fail (directory != NULL, FALSE); - - data.self = self; - data.changed = FALSE; - foreach_dir (directory, ld_library_load_cb, &data, NULL); - - if (data.changed) - g_signal_emit (self, LD_LIBRARY_GET_CLASS (self)->changed_signal, 0); - - return TRUE; -} - -/* - * ld_library_load_cb: - * - * A callback that's called for each file in the root directory. - */ -static gboolean -ld_library_load_cb (const gchar *base, const gchar *filename, gpointer userdata) -{ - LdSymbolCategory *cat; - LibraryLoadData *data; - - g_return_val_if_fail (base != NULL, FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (userdata != NULL, FALSE); - - data = (LibraryLoadData *) userdata; - - cat = load_category (data->self, filename, base); - if (cat) - ld_library_insert_child (data->self, G_OBJECT (cat), -1); - - data->changed = TRUE; - return TRUE; -} - -/** - * ld_library_find_symbol: - * @self: An #LdLibrary object. - * @identifier: An identifier of the symbol to be searched for. - * - * Search for a symbol in the library. - * - * 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) -{ - gchar **id_el_start, **id_el; - const GSList *list, *list_el; - - g_return_val_if_fail (LD_IS_LIBRARY (self), NULL); - g_return_val_if_fail (identifier != NULL, NULL); - - id_el_start = g_strsplit (identifier, LD_LIBRARY_IDENTIFIER_SEPARATOR, 0); - if (!id_el_start) - return NULL; - - list = ld_library_get_children (self); - for (id_el = id_el_start; id_el[0]; id_el++) - { - LdSymbolCategory *cat; - LdSymbol *symbol; - gboolean found = FALSE; - - 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[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) - break; - } - g_strfreev (id_el_start); - return NULL; -} - -/** - * ld_library_clear: - * @self: An #LdLibrary object. - * - * Clear all the contents. - */ -void -ld_library_clear (LdLibrary *self) -{ - g_return_if_fail (LD_IS_LIBRARY (self)); - - g_slist_foreach (self->priv->children, (GFunc) g_object_unref, NULL); - g_slist_free (self->priv->children); - self->priv->children = NULL; - - g_signal_emit (self, - LD_LIBRARY_GET_CLASS (self)->changed_signal, 0); -} - -/** - * ld_library_insert_child: - * @self: An #LdLibrary object. - * @child: The child to be inserted. - * @pos: The position at which the child will be inserted. - * Negative values will append to the end of list. - * - * Insert a child into the library. - */ -void -ld_library_insert_child (LdLibrary *self, GObject *child, gint pos) -{ - g_return_if_fail (LD_IS_LIBRARY (self)); - g_return_if_fail (G_IS_OBJECT (child)); - - g_object_ref (child); - self->priv->children = g_slist_insert (self->priv->children, child, pos); -} - -/** - * ld_library_remove_child: - * @self: An #LdLibrary object. - * @child: The child to be removed. - * - * Remove a child from the library. - */ -void -ld_library_remove_child (LdLibrary *self, GObject *child) -{ - g_return_if_fail (LD_IS_LIBRARY (self)); - g_return_if_fail (G_IS_OBJECT (child)); - - if (g_slist_find (self->priv->children, child)) - { - g_object_unref (child); - self->priv->children = g_slist_remove (self->priv->children, child); - } -} - -/** - * ld_library_get_children: - * @self: An #LdLibrary object. - * - * Return value: The internal list of children. Do not modify. - */ -const GSList * -ld_library_get_children (LdLibrary *self) -{ - g_return_val_if_fail (LD_IS_LIBRARY (self), NULL); - return self->priv->children; -} - |