girepository: Return enumerated versions as a GStrv

Returning list of strings is a bad idea, so let's do not now since
we're exposing the API for the first time.
This commit is contained in:
Marco Trevisan (Treviño) 2023-12-20 05:11:38 +01:00
parent 30d6e911c4
commit cd8f511262
3 changed files with 38 additions and 9 deletions

View File

@ -1558,28 +1558,39 @@ find_namespace_latest (const gchar *namespace,
* @repository: (nullable): A #GIRepository, or `NULL` for the singleton * @repository: (nullable): A #GIRepository, or `NULL` for the singleton
* process-global default #GIRepository * process-global default #GIRepository
* @namespace_: GI namespace, e.g. `Gtk` * @namespace_: GI namespace, e.g. `Gtk`
* @n_versions_out: (optional) (out): The number of versions returned.
* *
* Obtain an unordered list of versions (either currently loaded or * Obtain an unordered list of versions (either currently loaded or
* available) for @namespace_ in this @repository. * available) for @namespace_ in this @repository.
* *
* Returns: (element-type utf8) (transfer full): the array of versions. * Returns: (element-type utf8) (transfer full) (array length=n_versions_out): the array of versions.
* Since: 2.80 * Since: 2.80
*/ */
GList * char **
gi_repository_enumerate_versions (GIRepository *repository, gi_repository_enumerate_versions (GIRepository *repository,
const gchar *namespace_) const gchar *namespace_,
size_t *n_versions_out)
{ {
GList *ret = NULL; GPtrArray *versions;
GSList *candidates, *link; GSList *candidates, *link;
const gchar *loaded_version; const gchar *loaded_version;
char **ret;
init_globals (); init_globals ();
candidates = enumerate_namespace_versions (namespace_, typelib_search_path); candidates = enumerate_namespace_versions (namespace_, typelib_search_path);
if (!candidates)
{
if (n_versions_out)
*n_versions_out = 0;
return g_strdupv ((char *[]) {NULL});
}
versions = g_ptr_array_new_null_terminated (1, g_free, TRUE);
for (link = candidates; link; link = link->next) for (link = candidates; link; link = link->next)
{ {
struct NamespaceVersionCandidadate *candidate = link->data; struct NamespaceVersionCandidadate *candidate = link->data;
ret = g_list_prepend (ret, g_strdup (candidate->version)); g_ptr_array_add (versions, g_steal_pointer (&candidate->version));
free_candidate (candidate); free_candidate (candidate);
} }
g_slist_free (candidates); g_slist_free (candidates);
@ -1591,10 +1602,14 @@ gi_repository_enumerate_versions (GIRepository *repository,
if (gi_repository_is_registered (repository, namespace_, NULL)) if (gi_repository_is_registered (repository, namespace_, NULL))
{ {
loaded_version = gi_repository_get_version (repository, namespace_); loaded_version = gi_repository_get_version (repository, namespace_);
if (loaded_version && !g_list_find_custom (ret, loaded_version, g_str_equal)) if (loaded_version &&
ret = g_list_prepend (ret, g_strdup (loaded_version)); !g_ptr_array_find_with_equal_func (versions, loaded_version, g_str_equal, NULL))
g_ptr_array_add (versions, g_strdup (loaded_version));
} }
ret = (char **) g_ptr_array_steal (versions, n_versions_out);
g_ptr_array_unref (g_steal_pointer (&versions));
return ret; return ret;
} }

View File

@ -128,8 +128,9 @@ GIBaseInfo * gi_repository_find_by_name (GIRepository *repository,
const gchar *name); const gchar *name);
GI_AVAILABLE_IN_ALL GI_AVAILABLE_IN_ALL
GList * gi_repository_enumerate_versions (GIRepository *repository, char ** gi_repository_enumerate_versions (GIRepository *repository,
const gchar *namespace_); const gchar *namespace_,
size_t *n_versions_out);
GI_AVAILABLE_IN_ALL GI_AVAILABLE_IN_ALL
GITypelib * gi_repository_require (GIRepository *repository, GITypelib * gi_repository_require (GIRepository *repository,

View File

@ -32,6 +32,8 @@ test_repository_basic (void)
char **namespaces = NULL; char **namespaces = NULL;
const char *expected_namespaces[] = { "GLib", NULL }; const char *expected_namespaces[] = { "GLib", NULL };
GError *local_error = NULL; GError *local_error = NULL;
char **versions;
size_t n_versions;
g_test_summary ("Test basic opening of a repository and requiring a typelib"); g_test_summary ("Test basic opening of a repository and requiring a typelib");
@ -42,6 +44,17 @@ test_repository_basic (void)
repository = gi_repository_new (); repository = gi_repository_new ();
g_assert_nonnull (repository); g_assert_nonnull (repository);
versions = gi_repository_enumerate_versions (repository, "SomeInvalidNamespace", &n_versions);
g_assert_nonnull (versions);
g_assert_cmpstrv (versions, ((char *[]){NULL}));
g_assert_cmpuint (n_versions, ==, 0);
g_clear_pointer (&versions, g_strfreev);
versions = gi_repository_enumerate_versions (repository, "GLib", NULL);
g_assert_nonnull (versions);
g_assert_cmpstrv (versions, ((char *[]){"2.0", NULL}));
g_clear_pointer (&versions, g_strfreev);
search_path = gi_repository_get_search_path (); search_path = gi_repository_get_search_path ();
g_assert_nonnull (search_path); g_assert_nonnull (search_path);
g_assert_cmpstr (search_path->data, ==, gobject_typelib_dir); g_assert_cmpstr (search_path->data, ==, gobject_typelib_dir);