girepository: Add g_irepository_get_immediate_dependencies()

g_irepository_get_dependencies() is supposed to return the transitive
closure of all dependencies of the given namespace. However, it just
loads the dependencies field from the typelib, which is supposed to only
list immediate dependencies.

Introduce a new g_irepository_get_immediate_dependencies() which does
this, and rewrite g_irepository_get_dependencies() to build the
transitive closure of all its namespace dependencies. This does not
require loading any new typelibs, as the transitive closure of
dependencies should already have been loaded by g_irepository_require()
or g_irepository_load_typelib().

https://bugzilla.gnome.org/show_bug.cgi?id=743782
This commit is contained in:
Philip Withnall 2015-01-31 22:48:56 +00:00 committed by Philip Withnall
parent 5389e87a29
commit e222ca2ef2
4 changed files with 132 additions and 11 deletions

View File

@ -432,24 +432,28 @@ register_internal (GIRepository *repository,
}
/**
* g_irepository_get_dependencies:
* @repository: (allow-none): A #GIRepository or %NULL for the singleton
* 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 all (transitive) versioned dependencies for
* @namespace_. Returned strings are of the form
* <code>namespace-version</code>.
* 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.
*
* Returns: (transfer full): Zero-terminated string array of versioned
* 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_dependencies (GIRepository *repository,
const char *namespace)
g_irepository_get_immediate_dependencies (GIRepository *repository,
const char *namespace)
{
GITypelib *typelib;
gchar **deps;
@ -469,6 +473,105 @@ g_irepository_get_dependencies (GIRepository *repository,
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
* @namespace_: Namespace of interest
*
* Return an array of all (transitive) 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 only the immediate dependencies for @namespace_, use
* g_irepository_get_immediate_dependencies().
*
* Returns: (transfer full): Zero-terminated string array of all versioned
* dependencies
*/
char **
g_irepository_get_dependencies (GIRepository *repository,
const char *namespace)
{
GITypelib *typelib;
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);
/* 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);
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);
}
/**
* g_irepository_load_typelib:
* @repository: (allow-none): A #GIRepository or %NULL for the singleton

View File

@ -143,6 +143,10 @@ GITypelib * g_irepository_require_private (GIRepository *repository,
GIRepositoryLoadFlags flags,
GError **error);
GI_AVAILABLE_IN_1_44
gchar ** g_irepository_get_immediate_dependencies (GIRepository *repository,
const gchar *namespace_);
GI_AVAILABLE_IN_ALL
gchar ** g_irepository_get_dependencies (GIRepository *repository,
const gchar *namespace_);

View File

@ -1307,8 +1307,8 @@ gir_writer_write (const char *filename,
" xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
" xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
dependencies = g_irepository_get_dependencies (repository,
namespace);
dependencies = g_irepository_get_immediate_dependencies (repository,
namespace);
if (dependencies != NULL)
{
for (i = 0; dependencies[i]; i++)

View File

@ -125,4 +125,18 @@
# define GI_AVAILABLE_IN_1_42 _GI_EXTERN
#endif
#endif /* __GIVERSIONMACROS_H__ */
#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_44
# define GI_DEPRECATED_IN_1_44 GLIB_DEPRECATED
# define GI_DEPRECATED_IN_1_44_FOR(f) GLIB_DEPRECATED_FOR(f)
#else
# define GI_DEPRECATED_IN_1_44 _GI_EXTERN
# define GI_DEPRECATED_IN_1_44_FOR(f) _GI_EXTERN
#endif
#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_44
# define GI_AVAILABLE_IN_1_44 GLIB_UNAVAILABLE(2, 44)
#else
# define GI_AVAILABLE_IN_1_44 _GI_EXTERN
#endif
#endif /* __GIVERSIONMACROS_H__ */