From 01f97965329e5a45d036054032dde3d8f88639a0 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 7 Feb 2024 15:44:21 +0000 Subject: [PATCH] =?UTF-8?q?girepository:=20Add=20length=20=E2=80=98out?= =?UTF-8?q?=E2=80=99=20arguments=20to=20several=20getter=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes them consistent with the other getter methods in `GIRepository` which return lists/arrays. It’s useful to return the length, as that means the caller doesn’t have to work it out by iterating over the entire array. Signed-off-by: Philip Withnall Helps: #3155 --- docs/reference/girepository/migrating-gi.md | 1 + girepository/girepository.c | 43 +++++++++++++++++---- girepository/girepository.h | 9 +++-- girepository/girwriter.c | 2 +- girepository/tests/repository.c | 8 +++- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/docs/reference/girepository/migrating-gi.md b/docs/reference/girepository/migrating-gi.md index cca213fd7..54f12b227 100644 --- a/docs/reference/girepository/migrating-gi.md +++ b/docs/reference/girepository/migrating-gi.md @@ -64,6 +64,7 @@ your code if integer type warnings are enabled. | `g_irepository_get_default` | Singleton object removed; create separate [class@GIRepository.Repository] instances instead | | `g_irepository_get_search_path` and `g_irepository_get_library_path` | Now return arrays rather than linked lists | | `g_irepository_enumerate_versions` | Now returns an array rather than a linked list | +| `g_irepository_get_immediate_dependencies`, `g_irepository_get_dependencies` and `g_irepository_get_loaded_namespaces` | Now additionally return a length argument | | `g_irepository_dump` | Takes structured `input_filename` and `output_filename` arguments rather than a single formatted string | | `g_function_invoker_destroy` | `gi_function_invoker_clear()` | | `g_struct_info_get_copy_function` | [method@GIRepository.StructInfo.get_copy_function_name] | diff --git a/girepository/girepository.c b/girepository/girepository.c index 036484118..471213cc7 100644 --- a/girepository/girepository.c +++ b/girepository/girepository.c @@ -547,6 +547,8 @@ register_internal (GIRepository *repository, * gi_repository_get_immediate_dependencies: * @repository: A #GIRepository * @namespace_: Namespace of interest + * @n_dependencies_out: (optional) (out): Return location for the number of + * dependencies * * Return an array of the immediate versioned dependencies for @namespace_. * Returned strings are of the form `namespace-version`. @@ -558,13 +560,17 @@ register_internal (GIRepository *repository, * To get the transitive closure of dependencies for @namespace_, use * [method@GIRepository.Repository.get_dependencies]. * - * Returns: (transfer full) (array zero-terminated=1): `NULL`-terminated string - * array of immediate versioned dependencies + * The list is guaranteed to be `NULL` terminated. The `NULL` terminator is not + * counted in @n_dependencies_out. + * + * Returns: (transfer full) (array length=n_dependencies_out): String array of + * immediate versioned dependencies * Since: 2.80 */ char ** gi_repository_get_immediate_dependencies (GIRepository *repository, - const char *namespace) + const char *namespace, + size_t *n_dependencies_out) { GITypelib *typelib; char **deps; @@ -580,6 +586,9 @@ gi_repository_get_immediate_dependencies (GIRepository *repository, if (deps == NULL) deps = g_strsplit ("", "|", 0); + if (n_dependencies_out != NULL) + *n_dependencies_out = g_strv_length (deps); + return deps; } @@ -627,6 +636,8 @@ get_typelib_dependencies_transitive (GIRepository *repository, * gi_repository_get_dependencies: * @repository: A #GIRepository * @namespace_: Namespace of interest + * @n_dependencies_out: (optional) (out): Return location for the number of + * dependencies * * Retrieves all (transitive) versioned dependencies for * @namespace_. @@ -640,13 +651,17 @@ get_typelib_dependencies_transitive (GIRepository *repository, * To get only the immediate dependencies for @namespace_, use * [method@GIRepository.Repository.get_immediate_dependencies]. * - * Returns: (transfer full) (array zero-terminated=1): `NULL`-terminated string - * array of all versioned dependencies + * The list is guaranteed to be `NULL` terminated. The `NULL` terminator is not + * counted in @n_dependencies_out. + * + * Returns: (transfer full) (array length=n_dependencies_out): String array of + * all versioned dependencies * Since: 2.80 */ char ** gi_repository_get_dependencies (GIRepository *repository, - const char *namespace) + const char *namespace, + size_t *n_dependencies_out) { GITypelib *typelib; GHashTable *transitive_dependencies; /* set of owned utf8 */ @@ -679,6 +694,9 @@ gi_repository_get_dependencies (GIRepository *repository, g_hash_table_unref (transitive_dependencies); + if (n_dependencies_out != NULL) + *n_dependencies_out = out->len; + return (char **) g_ptr_array_free (out, FALSE); } @@ -1166,15 +1184,21 @@ collect_namespaces (gpointer key, /** * gi_repository_get_loaded_namespaces: * @repository: A #GIRepository + * @n_namespaces_out: (optional) (out): Return location for the number of + * namespaces * * Return the list of currently loaded namespaces. * - * Returns: (element-type utf8) (transfer full) (array zero-terminated=1): `NULL`-terminated + * The list is guaranteed to be `NULL` terminated. The `NULL` terminator is not + * counted in @n_namespaces_out. + * + * Returns: (element-type utf8) (transfer full) (array length=n_namespaces_out): * list of namespaces * Since: 2.80 */ char ** -gi_repository_get_loaded_namespaces (GIRepository *repository) +gi_repository_get_loaded_namespaces (GIRepository *repository, + size_t *n_namespaces_out) { GList *l, *list = NULL; char **names; @@ -1191,6 +1215,9 @@ gi_repository_get_loaded_namespaces (GIRepository *repository) names[i++] = g_strdup (l->data); g_list_free (list); + if (n_namespaces_out != NULL) + *n_namespaces_out = i; + return names; } diff --git a/girepository/girepository.h b/girepository/girepository.h index 8552730a1..ffe091928 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -133,14 +133,17 @@ GITypelib * gi_repository_require_private (GIRepository *repository GI_AVAILABLE_IN_ALL char ** gi_repository_get_immediate_dependencies (GIRepository *repository, - const char *namespace_); + const char *namespace_, + size_t *n_dependencies_out); GI_AVAILABLE_IN_ALL char ** gi_repository_get_dependencies (GIRepository *repository, - const char *namespace_); + const char *namespace_, + size_t *n_dependencies_out); GI_AVAILABLE_IN_ALL -char ** gi_repository_get_loaded_namespaces (GIRepository *repository); +char ** gi_repository_get_loaded_namespaces (GIRepository *repository, + size_t *n_namespaces_out); GI_AVAILABLE_IN_ALL GIBaseInfo * gi_repository_find_by_gtype (GIRepository *repository, diff --git a/girepository/girwriter.c b/girepository/girwriter.c index cb4a7a1e0..b55192ba1 100644 --- a/girepository/girwriter.c +++ b/girepository/girwriter.c @@ -1373,7 +1373,7 @@ gi_ir_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 = gi_repository_get_immediate_dependencies (repository, ns); + dependencies = gi_repository_get_immediate_dependencies (repository, ns, NULL); if (dependencies != NULL) { for (i = 0; dependencies[i]; i++) diff --git a/girepository/tests/repository.c b/girepository/tests/repository.c index 7870c6242..e5df0427a 100644 --- a/girepository/tests/repository.c +++ b/girepository/tests/repository.c @@ -41,6 +41,7 @@ test_repository_basic (RepositoryFixture *fx, { const char * const * search_paths; char **namespaces = NULL; + size_t n_namespaces; const char *expected_namespaces[] = { "GLib", NULL }; char **versions; size_t n_versions; @@ -64,8 +65,9 @@ test_repository_basic (RepositoryFixture *fx, g_assert_cmpuint (g_strv_length ((char **) search_paths), >, 0); g_assert_cmpstr (search_paths[0], ==, fx->gobject_typelib_dir); - namespaces = gi_repository_get_loaded_namespaces (fx->repository); + 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); prefix = gi_repository_get_c_prefix (fx->repository, "GLib"); @@ -142,11 +144,13 @@ test_repository_dependencies (RepositoryFixture *fx, { GError *error = NULL; char **dependencies; + size_t n_dependencies; g_test_summary ("Test ensures namespace dependencies are correctly exposed"); - dependencies = gi_repository_get_dependencies (fx->repository, "GObject"); + dependencies = gi_repository_get_dependencies (fx->repository, "GObject", &n_dependencies); g_assert_cmpuint (g_strv_length (dependencies), ==, 1); + g_assert_cmpuint (n_dependencies, ==, 1); g_assert_true (g_strv_contains ((const char **) dependencies, "GLib-2.0")); g_clear_error (&error);