Make ld_library_find_symbol() easier to read

As well as shorter, strangely.

Symbols may technically exist directly in the root category now.
This commit is contained in:
Přemysl Eric Janouch 2021-10-29 01:28:52 +02:00
parent ee7be81434
commit 9dcef6a14f
Signed by: p
GPG Key ID: A0420B94F92B9493
1 changed files with 33 additions and 42 deletions

View File

@ -49,6 +49,8 @@ static gboolean foreach_dir (const gchar *path,
gboolean (*callback) (const gchar *, const gchar *, gpointer), gboolean (*callback) (const gchar *, const gchar *, gpointer),
gpointer userdata, GError **error); gpointer userdata, GError **error);
static LdSymbol *traverse_path (LdCategory *category, gchar **path);
G_DEFINE_TYPE (LdLibrary, ld_library, G_TYPE_OBJECT) G_DEFINE_TYPE (LdLibrary, ld_library, G_TYPE_OBJECT)
@ -356,62 +358,51 @@ ld_library_load (LdLibrary *self, const gchar *directory)
LdSymbol * LdSymbol *
ld_library_find_symbol (LdLibrary *self, const gchar *identifier) ld_library_find_symbol (LdLibrary *self, const gchar *identifier)
{ {
gchar **id_el_start, **id_el; gchar **path;
const GSList *list, *list_el; LdSymbol *symbol = NULL;
LdCategory *cat;
g_return_val_if_fail (LD_IS_LIBRARY (self), NULL); g_return_val_if_fail (LD_IS_LIBRARY (self), NULL);
g_return_val_if_fail (identifier != NULL, NULL); g_return_val_if_fail (identifier != NULL, NULL);
id_el_start = g_strsplit (identifier, LD_LIBRARY_IDENTIFIER_SEPARATOR, 0); path = g_strsplit (identifier, LD_LIBRARY_IDENTIFIER_SEPARATOR, 0);
if (!id_el_start) if (path)
return NULL;
/* We need at least one category name plus the symbol name. */
id_el = id_el_start;
if (!id_el[0] || !id_el[1])
goto ld_library_find_symbol_error;
/* Find the category where the symbol is in. */
cat = self->priv->root;
while (1)
{ {
gboolean found = FALSE; symbol = traverse_path (self->priv->root, path);
g_strfreev (path);
list = ld_category_get_children (cat);
for (list_el = list; list_el; list_el = g_slist_next (list_el))
{
cat = LD_CATEGORY (list_el->data);
if (!strcmp (*id_el, ld_category_get_name (cat)))
{
found = TRUE;
break;
}
} }
return symbol;
}
if (!found) static LdSymbol *
goto ld_library_find_symbol_error; traverse_path (LdCategory *category, gchar **path)
{
if (!(id_el++)[2]) const GSList *list, *iter;
break;
}
/* And then the actual symbol. */
list = ld_category_get_symbols (cat);
for (list_el = list; list_el; list_el = g_slist_next (list_el))
{
LdSymbol *symbol; LdSymbol *symbol;
symbol = LD_SYMBOL (list_el->data); g_return_val_if_fail (*path != NULL, NULL);
if (!strcmp (*id_el, ld_symbol_get_name (symbol)))
/* Walk the category tree to where the symbol is supposed to be. */
for (; path[1]; path++)
{ {
g_strfreev (id_el_start); list = ld_category_get_children (category);
return symbol; for (iter = list; iter; iter = g_slist_next (iter))
{
category = LD_CATEGORY (iter->data);
if (!strcmp (*path, ld_category_get_name (category)))
break;
} }
if (!iter)
return NULL;
} }
ld_library_find_symbol_error: /* And look up the actual symbol at the leaf. */
g_strfreev (id_el_start); list = ld_category_get_symbols (category);
for (iter = list; iter; iter = g_slist_next (iter))
{
symbol = LD_SYMBOL (iter->data);
if (!strcmp (*path, ld_symbol_get_name (symbol)))
return symbol;
}
return NULL; return NULL;
} }