From b952082c5b59f123882a83c76bf0a8ee1c8dd4ee Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 25 Nov 2008 21:48:34 +0000 Subject: Bug 561137 - support multiple repositories This change makes us stop calling g_irepository_get_default inside ginfo.c, which won't work for non-default repositories. Change GIBaseInfo to not only keep track of its source repository, we hold a reference. This makes memmgt much clearer. svn path=/trunk/; revision=970 --- girepository/Makefile.am | 1 + girepository/ginfo.c | 61 ++++++++++++++++++++++++++++++--------------- girepository/ginfo.h | 42 +++++++++++++++++++++++++++++++ girepository/girepository.c | 11 ++++++-- 4 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 girepository/ginfo.h diff --git a/girepository/Makefile.am b/girepository/Makefile.am index f98dda29..4554d571 100644 --- a/girepository/Makefile.am +++ b/girepository/Makefile.am @@ -13,6 +13,7 @@ libgirepository_la_SOURCES = \ gtypelib.h \ gtypelib.c \ gfield.c \ + ginfo.h \ ginfo.c \ girffi.c \ girffi.h \ diff --git a/girepository/ginfo.c b/girepository/ginfo.c index 204583cd..0e39bcd0 100644 --- a/girepository/ginfo.c +++ b/girepository/ginfo.c @@ -24,13 +24,14 @@ #include #include -#include "girepository.h" #include "gtypelib.h" +#include "ginfo.h" struct _GIBaseInfo { gint type; gint ref_count; + GIRepository *repository; GIBaseInfo *container; GTypelib *typelib; @@ -135,13 +136,16 @@ struct _GIUnionInfo /* info creation */ GIBaseInfo * -g_info_new (GIInfoType type, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) +g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) { GIBaseInfo *info; + g_return_val_if_fail (container != NULL || repository != NULL, NULL); + info = g_new0 (GIBaseInfo, 1); info->ref_count = 1; @@ -153,38 +157,48 @@ g_info_new (GIInfoType type, if (container) info->container = g_base_info_ref (container); + info->repository = g_object_ref (repository); + return info; } +GIBaseInfo * +g_info_new (GIInfoType type, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + return g_info_new_full (type, container->repository, container, typelib, offset); +} + static GIBaseInfo * -g_info_from_entry (GTypelib *typelib, +g_info_from_entry (GIRepository *repository, + GTypelib *typelib, guint16 index) { GIBaseInfo *result; DirEntry *entry = g_typelib_get_dir_entry (typelib, index); - + if (entry->local) - result = g_info_new (entry->blob_type, NULL, typelib, entry->offset); - else + result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset); + else { const gchar *namespace = g_typelib_get_string (typelib, entry->offset); const gchar *name = g_typelib_get_string (typelib, entry->name); - - GIRepository *repository = g_irepository_get_default (); - + result = g_irepository_find_by_name (repository, namespace, name); if (result == NULL) { GIUnresolvedInfo *unresolved; unresolved = g_new0 (GIUnresolvedInfo, 1); - + unresolved->type = GI_INFO_TYPE_UNRESOLVED; unresolved->ref_count = 1; unresolved->container = NULL; unresolved->name = name; unresolved->namespace = namespace; - + return (GIBaseInfo*)unresolved; } return result; @@ -213,6 +227,8 @@ g_base_info_unref (GIBaseInfo *info) if (info->container) g_base_info_unref (info->container); + g_object_unref (info->repository); + g_free (info); } } @@ -804,7 +820,7 @@ g_type_info_get_interface (GITypeInfo *info) InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (base->typelib, blob->interface); + return g_info_from_entry (base->repository, base->typelib, blob->interface); } return NULL; @@ -896,7 +912,8 @@ g_type_info_get_error_domain (GITypeInfo *info, ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) g_info_from_entry (base->typelib, + return (GIErrorDomainInfo *) g_info_from_entry (base->repository, + base->typelib, blob->domains[n]); } @@ -920,7 +937,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->error_codes); + return (GIInterfaceInfo *) g_info_from_entry (base->repository, + base->typelib, blob->error_codes); } @@ -1182,7 +1200,8 @@ g_object_info_get_parent (GIObjectInfo *info) ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; if (blob->parent) - return (GIObjectInfo *) g_info_from_entry (base->typelib, blob->parent); + return (GIObjectInfo *) g_info_from_entry (base->repository, + base->typelib, blob->parent); else return NULL; } @@ -1229,7 +1248,8 @@ g_object_info_get_interface (GIObjectInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->interfaces[n]); + return (GIInterfaceInfo *) g_info_from_entry (base->repository, + base->typelib, blob->interfaces[n]); } gint @@ -1437,7 +1457,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; - return g_info_from_entry (base->typelib, blob->prerequisites[n]); + return g_info_from_entry (base->repository, + base->typelib, blob->prerequisites[n]); } diff --git a/girepository/ginfo.h b/girepository/ginfo.h new file mode 100644 index 00000000..15138cfb --- /dev/null +++ b/girepository/ginfo.h @@ -0,0 +1,42 @@ +/* GObject introspection: Typelib info functions + * + * Copyright (C) 2008 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GIRINFO_H__ +#define __GIRINFO_H__ + +#include "girepository.h" + +G_BEGIN_DECLS + +GITypeInfo * +g_type_info_new (GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + +GIBaseInfo * +g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + +G_END_DECLS + +#endif diff --git a/girepository/girepository.c b/girepository/girepository.c index e8a26474..8b37b696 100644 --- a/girepository/girepository.c +++ b/girepository/girepository.c @@ -30,6 +30,7 @@ #include #include "girepository.h" #include "gtypelib.h" +#include "ginfo.h" #include "config.h" @@ -333,6 +334,7 @@ register_internal (GIRepository *repository, else key = build_typelib_key (namespace, source); + g_printerr ("loaded: %s\n", key); g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); } @@ -487,6 +489,7 @@ g_irepository_get_n_infos (GIRepository *repository, typedef struct { + GIRepository *repo; gint index; const gchar *name; const gchar *type; @@ -556,8 +559,9 @@ find_interface (gpointer key, if (index != 0) { entry = g_typelib_get_dir_entry (typelib, index); - iface_data->iface = g_info_new (entry->blob_type, NULL, - typelib, entry->offset); + iface_data->iface = g_info_new_full (entry->blob_type, + iface_data->repo, + NULL, typelib, entry->offset); } } @@ -585,6 +589,7 @@ g_irepository_get_info (GIRepository *repository, repository = get_repository (repository); + data.repo = repository; data.name = NULL; data.type = NULL; data.index = index + 1; @@ -621,6 +626,7 @@ g_irepository_find_by_gtype (GIRepository *repository, repository = get_repository (repository); + data.repo = repository; data.name = NULL; data.type = g_type_name (type); data.index = -1; @@ -657,6 +663,7 @@ g_irepository_find_by_name (GIRepository *repository, repository = get_repository (repository); + data.repo = repository; data.name = name; data.type = NULL; data.index = -1; -- cgit v1.2.1