summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@src.gnome.org>2008-11-25 21:48:34 +0000
committerColin Walters <walters@src.gnome.org>2008-11-25 21:48:34 +0000
commitb952082c5b59f123882a83c76bf0a8ee1c8dd4ee (patch)
treefdbc8cb70899dd88a18c575c0315cbcb7549ec74
parentaa42015592ee8c15bc32812d8570d52fbd66e7da (diff)
downloadgobject-introspection-b952082c5b59f123882a83c76bf0a8ee1c8dd4ee.tar.gz
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
-rw-r--r--girepository/Makefile.am1
-rw-r--r--girepository/ginfo.c61
-rw-r--r--girepository/ginfo.h42
-rw-r--r--girepository/girepository.c11
4 files changed, 93 insertions, 22 deletions
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 <glib.h>
#include <glib-object.h>
-#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 <gmodule.h>
#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;