summaryrefslogtreecommitdiff
path: root/girepository/girepository.c
diff options
context:
space:
mode:
Diffstat (limited to 'girepository/girepository.c')
-rw-r--r--girepository/girepository.c117
1 files changed, 110 insertions, 7 deletions
diff --git a/girepository/girepository.c b/girepository/girepository.c
index fb91afaa..efc3bded 100644
--- a/girepository/girepository.c
+++ b/girepository/girepository.c
@@ -432,6 +432,89 @@ register_internal (GIRepository *repository,
}
/**
+ * g_irepository_get_immediate_dependencies:
+ * @repository: (nullable): A #GIRepository or %NULL for the singleton
+ * process-global default #GIRepository
+ * @namespace_: Namespace of interest
+ *
+ * Return an array of the immediate versioned dependencies for @namespace_.
+ * Returned strings are of the form <code>namespace-version</code>.
+ *
+ * Note: @namespace_ must have already been loaded using a function
+ * such as g_irepository_require() before calling this function.
+ *
+ * To get the transitive closure of dependencies for @namespace_, use
+ * g_irepository_get_dependencies().
+ *
+ * Returns: (transfer full): Zero-terminated string array of immediate versioned
+ * dependencies
+ *
+ * Since: 1.44
+ */
+char **
+g_irepository_get_immediate_dependencies (GIRepository *repository,
+ const char *namespace)
+{
+ GITypelib *typelib;
+ gchar **deps;
+
+ g_return_val_if_fail (namespace != NULL, NULL);
+
+ repository = get_repository (repository);
+
+ typelib = get_registered (repository, namespace, NULL);
+ g_return_val_if_fail (typelib != NULL, NULL);
+
+ /* Ensure we always return a non-%NULL vector. */
+ deps = get_typelib_dependencies (typelib);
+ if (deps == NULL)
+ deps = g_strsplit ("", "|", 0);
+
+ return deps;
+}
+
+/* Load the transitive closure of dependency namespace-version strings for the
+ * given @typelib. @repository must be non-%NULL. @transitive_dependencies must
+ * be a pre-existing GHashTable<owned utf8, owned utf8> set for storing the
+ * dependencies. */
+static void
+get_typelib_dependencies_transitive (GIRepository *repository,
+ GITypelib *typelib,
+ GHashTable *transitive_dependencies)
+{
+ gchar **immediate_dependencies;
+ guint i;
+
+ immediate_dependencies = get_typelib_dependencies (typelib);
+
+ for (i = 0; immediate_dependencies != NULL && immediate_dependencies[i]; i++)
+ {
+ gchar *dependency;
+ const gchar *last_dash;
+ gchar *dependency_namespace;
+
+ dependency = immediate_dependencies[i];
+
+ /* Steal from the strv. */
+ g_hash_table_add (transitive_dependencies, dependency);
+ immediate_dependencies[i] = NULL;
+
+ /* Recurse for this namespace. */
+ last_dash = strrchr (dependency, '-');
+ dependency_namespace = g_strndup (dependency, last_dash - dependency);
+
+ typelib = get_registered (repository, dependency_namespace, NULL);
+ g_return_if_fail (typelib != NULL);
+ get_typelib_dependencies_transitive (repository, typelib,
+ transitive_dependencies);
+
+ g_free (dependency_namespace);
+ }
+
+ g_free (immediate_dependencies);
+}
+
+/**
* g_irepository_get_dependencies:
* @repository: (allow-none): A #GIRepository or %NULL for the singleton
* process-global default #GIRepository
@@ -444,7 +527,10 @@ register_internal (GIRepository *repository,
* Note: @namespace_ must have already been loaded using a function
* such as g_irepository_require() before calling this function.
*
- * Returns: (transfer full): Zero-terminated string array of versioned
+ * To get only the immediate dependencies for @namespace_, use
+ * g_irepository_get_immediate_dependencies().
+ *
+ * Returns: (transfer full): Zero-terminated string array of all versioned
* dependencies
*/
char **
@@ -452,21 +538,38 @@ g_irepository_get_dependencies (GIRepository *repository,
const char *namespace)
{
GITypelib *typelib;
- gchar **deps;
+ GHashTable *transitive_dependencies; /* set of owned utf8 */
+ GHashTableIter iter;
+ gchar *dependency;
+ GPtrArray *out; /* owned utf8 elements */
g_return_val_if_fail (namespace != NULL, NULL);
repository = get_repository (repository);
+ transitive_dependencies = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ /* Load the dependencies. */
typelib = get_registered (repository, namespace, NULL);
g_return_val_if_fail (typelib != NULL, NULL);
+ get_typelib_dependencies_transitive (repository, typelib,
+ transitive_dependencies);
- /* Ensure we always return a non-%NULL vector. */
- deps = get_typelib_dependencies (typelib);
- if (deps == NULL)
- deps = g_strsplit ("", "|", 0);
+ /* Convert to a string array. */
+ out = g_ptr_array_new_full (g_hash_table_size (transitive_dependencies),
+ g_free);
+ g_hash_table_iter_init (&iter, transitive_dependencies);
- return deps;
+ while (g_hash_table_iter_next (&iter, (gpointer) &dependency, NULL))
+ {
+ g_ptr_array_add (out, dependency);
+ g_hash_table_iter_steal (&iter);
+ }
+
+ /* Add a NULL terminator. */
+ g_ptr_array_add (out, NULL);
+
+ return (gchar **) g_ptr_array_free (out, FALSE);
}
/**