diff --git a/girepository/girepository.c b/girepository/girepository.c index e74622e60..0cf6da148 100644 --- a/girepository/girepository.c +++ b/girepository/girepository.c @@ -1232,13 +1232,16 @@ gi_repository_get_object_gtype_interfaces (GIRepository *repository, } static void -collect_namespaces (gpointer key, - gpointer value, - gpointer data) +collect_namespaces (GPtrArray *ordered_typelibs, + char **names, + size_t *inout_i) { - GList **list = data; - - *list = g_list_append (*list, key); + for (guint j = 0; j < ordered_typelibs->len; j++) + { + GITypelib *typelib = g_ptr_array_index (ordered_typelibs, j); + const char *namespace = gi_typelib_get_namespace (typelib); + names[(*inout_i)++] = g_strdup (namespace); + } } /** @@ -1260,20 +1263,18 @@ char ** gi_repository_get_loaded_namespaces (GIRepository *repository, size_t *n_namespaces_out) { - GList *l, *list = NULL; char **names; size_t i; + size_t n_typelibs; g_return_val_if_fail (GI_IS_REPOSITORY (repository), NULL); - g_hash_table_foreach (repository->typelibs, collect_namespaces, &list); - g_hash_table_foreach (repository->lazy_typelibs, collect_namespaces, &list); - - names = g_malloc0 (sizeof (char *) * (g_list_length (list) + 1)); + n_typelibs = repository->ordered_typelibs->len + repository->ordered_lazy_typelibs->len; + names = g_malloc0 (sizeof (char *) * (n_typelibs + 1)); i = 0; - for (l = list; l; l = l->next) - names[i++] = g_strdup (l->data); - g_list_free (list); + + collect_namespaces (repository->ordered_typelibs, names, &i); + collect_namespaces (repository->ordered_lazy_typelibs, names, &i); if (n_namespaces_out != NULL) *n_namespaces_out = i; diff --git a/girepository/tests/repository.c b/girepository/tests/repository.c index 55cbcb0ce..c79b0df9a 100644 --- a/girepository/tests/repository.c +++ b/girepository/tests/repository.c @@ -863,6 +863,35 @@ test_repository_find_by_gtype (RepositoryFixture *fx, } } +static void +test_repository_loaded_namespaces (RepositoryFixture *fx, + const void *unused) +{ + char **namespaces; + size_t n_namespaces; + + /* These should be in alphabetical order */ +#if defined(G_OS_UNIX) + const char *expected_namespaces[] = { "GLib", "GModule", "GObject", "Gio", "GioUnix", NULL }; +#elif defined(G_OS_WIN32) + const char *expected_namespaces[] = { "GLib", "GModule", "GObject", "Gio", "GioWin32", NULL }; +#else + const char *expected_namespaces[] = { "GLib", "GModule", "GObject", "Gio", NULL }; +#endif + + g_test_summary ("Test listing loaded namespaces"); + + namespaces = gi_repository_get_loaded_namespaces (fx->repository, &n_namespaces); + g_assert_cmpstrv (namespaces, expected_namespaces); + g_assert_cmpuint (n_namespaces, ==, g_strv_length ((char **) expected_namespaces)); + g_strfreev (namespaces); + + /* Test again but without passing `n_namespaces`. */ + namespaces = gi_repository_get_loaded_namespaces (fx->repository, NULL); + g_assert_cmpstrv (namespaces, expected_namespaces); + g_strfreev (namespaces); +} + int main (int argc, char *argv[]) @@ -891,6 +920,7 @@ main (int argc, ADD_REPOSITORY_TEST ("/repository/vfunc-info-with-invoker-on-interface", test_repository_vfunc_info_with_invoker_on_interface, &typelib_load_spec_gio); ADD_REPOSITORY_TEST ("/repository/vfunc-info-with-invoker-on-object", test_repository_vfunc_info_with_invoker_on_object, &typelib_load_spec_gio); ADD_REPOSITORY_TEST ("/repository/find-by-gtype", test_repository_find_by_gtype, &typelib_load_spec_gio_platform); + ADD_REPOSITORY_TEST ("/repository/loaded-namespaces", test_repository_loaded_namespaces, &typelib_load_spec_gio_platform); return g_test_run (); }