mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-28 21:22:11 +01:00
Remove g_irepository_unregister, add GIRepositoryLoadFlags
svn path=/trunk/; revision=543
This commit is contained in:
parent
e6a68106a2
commit
74651b01bd
182
girepository.c
182
girepository.c
@ -35,6 +35,7 @@ static GSList *search_path = NULL;
|
|||||||
struct _GIRepositoryPrivate
|
struct _GIRepositoryPrivate
|
||||||
{
|
{
|
||||||
GHashTable *typelibs; /* (string) namespace -> GTypelib */
|
GHashTable *typelibs; /* (string) namespace -> GTypelib */
|
||||||
|
GHashTable *lazy_typelibs; /* (string) namespace -> GTypelib */
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
|
||||||
@ -44,6 +45,12 @@ g_irepository_init (GIRepository *repository)
|
|||||||
{
|
{
|
||||||
repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY,
|
repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY,
|
||||||
GIRepositoryPrivate);
|
GIRepositoryPrivate);
|
||||||
|
repository->priv->typelibs
|
||||||
|
= g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
(GDestroyNotify) NULL,
|
||||||
|
(GDestroyNotify) g_typelib_free);
|
||||||
|
repository->priv->lazy_typelibs
|
||||||
|
= g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -76,10 +83,6 @@ init_globals ()
|
|||||||
if (default_repository == NULL)
|
if (default_repository == NULL)
|
||||||
{
|
{
|
||||||
default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL);
|
default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL);
|
||||||
default_repository->priv->typelibs
|
|
||||||
= g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
||||||
(GDestroyNotify) NULL,
|
|
||||||
(GDestroyNotify) g_typelib_free);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search_path == NULL)
|
if (search_path == NULL)
|
||||||
@ -135,13 +138,7 @@ static GIRepository *
|
|||||||
get_repository (GIRepository *repository)
|
get_repository (GIRepository *repository)
|
||||||
{
|
{
|
||||||
if (repository != NULL)
|
if (repository != NULL)
|
||||||
{
|
|
||||||
if (repository->priv->typelibs == NULL)
|
|
||||||
repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
||||||
(GDestroyNotify) NULL,
|
|
||||||
(GDestroyNotify) g_typelib_free);
|
|
||||||
return repository;
|
return repository;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
init_globals ();
|
init_globals ();
|
||||||
@ -149,26 +146,45 @@ get_repository (GIRepository *repository)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static GTypelib *
|
||||||
register_internal (GIRepository *repository,
|
get_registered_status (GIRepository *repository,
|
||||||
const char *source,
|
const char *namespace,
|
||||||
|
gboolean allow_lazy,
|
||||||
|
gboolean *lazy_status)
|
||||||
|
{
|
||||||
|
GTypelib *typelib;
|
||||||
|
repository = get_repository (repository);
|
||||||
|
if (lazy_status)
|
||||||
|
*lazy_status = FALSE;
|
||||||
|
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
||||||
|
if (typelib)
|
||||||
|
return typelib;
|
||||||
|
typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace);
|
||||||
|
if (!typelib)
|
||||||
|
return NULL;
|
||||||
|
if (lazy_status)
|
||||||
|
*lazy_status = TRUE;
|
||||||
|
if (!allow_lazy)
|
||||||
|
return NULL;
|
||||||
|
return typelib;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GTypelib *
|
||||||
|
get_registered (GIRepository *repository,
|
||||||
|
const char *namespace)
|
||||||
|
{
|
||||||
|
return get_registered_status (repository, namespace, TRUE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
load_dependencies_recurse (GIRepository *repository,
|
||||||
GTypelib *typelib,
|
GTypelib *typelib,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
Header *header;
|
|
||||||
const gchar *name;
|
|
||||||
const char *dependencies_glob;
|
|
||||||
char **dependencies;
|
char **dependencies;
|
||||||
|
|
||||||
g_return_val_if_fail (typelib != NULL, FALSE);
|
|
||||||
|
|
||||||
header = (Header *)typelib->data;
|
|
||||||
|
|
||||||
g_return_val_if_fail (header != NULL, FALSE);
|
|
||||||
|
|
||||||
name = g_typelib_get_string (typelib, header->namespace);
|
|
||||||
|
|
||||||
dependencies = get_typelib_dependencies (typelib);
|
dependencies = get_typelib_dependencies (typelib);
|
||||||
|
|
||||||
if (dependencies != NULL)
|
if (dependencies != NULL)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -177,23 +193,69 @@ register_internal (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
char *dependency = dependencies[i];
|
char *dependency = dependencies[i];
|
||||||
|
|
||||||
if (!g_irepository_require (repository, dependency, error))
|
if (!g_irepository_require (repository, dependency,
|
||||||
|
0, error))
|
||||||
{
|
{
|
||||||
g_strfreev (dependencies);
|
g_strfreev (dependencies);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_strfreev (dependencies);
|
g_strfreev (dependencies);
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
g_assert (g_hash_table_lookup (repository->priv->typelibs, name) == NULL);
|
static const char *
|
||||||
g_hash_table_insert (repository->priv->typelibs,
|
register_internal (GIRepository *repository,
|
||||||
build_typelib_key (name, source), (void *)typelib);
|
const char *source,
|
||||||
|
gboolean lazy,
|
||||||
|
GTypelib *typelib,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
Header *header;
|
||||||
|
const gchar *namespace;
|
||||||
|
gboolean was_loaded;
|
||||||
|
gboolean currently_lazy;
|
||||||
|
|
||||||
|
g_return_val_if_fail (typelib != NULL, FALSE);
|
||||||
|
|
||||||
|
header = (Header *)typelib->data;
|
||||||
|
|
||||||
|
g_return_val_if_fail (header != NULL, FALSE);
|
||||||
|
|
||||||
|
namespace = g_typelib_get_string (typelib, header->namespace);
|
||||||
|
|
||||||
|
if (lazy)
|
||||||
|
{
|
||||||
|
g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs,
|
||||||
|
namespace));
|
||||||
|
g_hash_table_insert (repository->priv->lazy_typelibs,
|
||||||
|
build_typelib_key (namespace, source), (void *)typelib);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpointer value;
|
||||||
|
char *key;
|
||||||
|
|
||||||
|
/* First, try loading all the dependencies */
|
||||||
|
if (!load_dependencies_recurse (repository, typelib, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Check if we are transitioning from lazily loaded state */
|
||||||
|
if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs,
|
||||||
|
namespace,
|
||||||
|
(gpointer)&key, &value))
|
||||||
|
g_hash_table_remove (repository->priv->lazy_typelibs, key);
|
||||||
|
else
|
||||||
|
key = build_typelib_key (namespace, source);
|
||||||
|
|
||||||
|
g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib);
|
||||||
|
}
|
||||||
|
|
||||||
if (typelib->module == NULL)
|
if (typelib->module == NULL)
|
||||||
typelib->module = g_module_open (NULL, 0);
|
typelib->module = g_module_open (NULL, 0);
|
||||||
|
|
||||||
return name;
|
return namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **
|
char **
|
||||||
@ -206,7 +268,7 @@ g_irepository_get_dependencies (GIRepository *repository,
|
|||||||
|
|
||||||
repository = get_repository (repository);
|
repository = get_repository (repository);
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
typelib = get_registered (repository, namespace);
|
||||||
g_return_val_if_fail (typelib != NULL, NULL);
|
g_return_val_if_fail (typelib != NULL, NULL);
|
||||||
|
|
||||||
return get_typelib_dependencies (typelib);
|
return get_typelib_dependencies (typelib);
|
||||||
@ -215,31 +277,23 @@ g_irepository_get_dependencies (GIRepository *repository,
|
|||||||
const char *
|
const char *
|
||||||
g_irepository_load_typelib (GIRepository *repository,
|
g_irepository_load_typelib (GIRepository *repository,
|
||||||
GTypelib *typelib,
|
GTypelib *typelib,
|
||||||
|
GIRepositoryLoadFlags flags,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
Header *header;
|
Header *header;
|
||||||
const char *namespace;
|
const char *namespace;
|
||||||
|
gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY;
|
||||||
|
gboolean is_lazy;
|
||||||
|
|
||||||
repository = get_repository (repository);
|
repository = get_repository (repository);
|
||||||
|
|
||||||
header = (Header *) typelib->data;
|
header = (Header *) typelib->data;
|
||||||
namespace = g_typelib_get_string (typelib, header->namespace);
|
namespace = g_typelib_get_string (typelib, header->namespace);
|
||||||
|
|
||||||
if (g_hash_table_lookup (repository->priv->typelibs, namespace))
|
if (get_registered_status (repository, namespace, allow_lazy, &is_lazy))
|
||||||
return namespace;
|
return namespace;
|
||||||
return register_internal (repository, "<builtin>", typelib, error);
|
return register_internal (repository, "<builtin>",
|
||||||
}
|
allow_lazy, typelib, error);
|
||||||
|
|
||||||
void
|
|
||||||
g_irepository_unregister (GIRepository *repository,
|
|
||||||
const gchar *namespace)
|
|
||||||
{
|
|
||||||
repository = get_repository (repository);
|
|
||||||
|
|
||||||
if (!g_hash_table_remove (repository->priv->typelibs, namespace))
|
|
||||||
{
|
|
||||||
g_printerr ("namespace '%s' not registered\n", namespace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -247,8 +301,7 @@ g_irepository_is_registered (GIRepository *repository,
|
|||||||
const gchar *namespace)
|
const gchar *namespace)
|
||||||
{
|
{
|
||||||
repository = get_repository (repository);
|
repository = get_repository (repository);
|
||||||
|
return get_registered (repository, namespace) != NULL;
|
||||||
return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GIRepository *
|
GIRepository *
|
||||||
@ -280,7 +333,7 @@ g_irepository_get_n_infos (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
typelib = get_registered (repository, namespace);
|
||||||
|
|
||||||
if (typelib)
|
if (typelib)
|
||||||
n_interfaces = ((Header *)typelib->data)->n_local_entries;
|
n_interfaces = ((Header *)typelib->data)->n_local_entries;
|
||||||
@ -289,6 +342,8 @@ g_irepository_get_n_infos (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
g_hash_table_foreach (repository->priv->typelibs,
|
g_hash_table_foreach (repository->priv->typelibs,
|
||||||
count_interfaces, &n_interfaces);
|
count_interfaces, &n_interfaces);
|
||||||
|
g_hash_table_foreach (repository->priv->lazy_typelibs,
|
||||||
|
count_interfaces, &n_interfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
return n_interfaces;
|
return n_interfaces;
|
||||||
@ -384,13 +439,16 @@ g_irepository_get_info (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
typelib = get_registered (repository, namespace);
|
||||||
|
|
||||||
if (typelib)
|
if (typelib)
|
||||||
find_interface ((void *)namespace, typelib, &data);
|
find_interface ((void *)namespace, typelib, &data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
||||||
|
g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
|
||||||
|
}
|
||||||
|
|
||||||
return data.iface;
|
return data.iface;
|
||||||
}
|
}
|
||||||
@ -409,6 +467,7 @@ g_irepository_find_by_gtype (GIRepository *repository,
|
|||||||
data.iface = NULL;
|
data.iface = NULL;
|
||||||
|
|
||||||
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
||||||
|
g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
|
||||||
|
|
||||||
return data.iface;
|
return data.iface;
|
||||||
}
|
}
|
||||||
@ -442,13 +501,16 @@ g_irepository_find_by_name (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
typelib = get_registered (repository, namespace);
|
||||||
|
|
||||||
if (typelib)
|
if (typelib)
|
||||||
find_interface ((void *)namespace, typelib, &data);
|
find_interface ((void *)namespace, typelib, &data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
||||||
|
g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
|
||||||
|
}
|
||||||
|
|
||||||
return data.iface;
|
return data.iface;
|
||||||
}
|
}
|
||||||
@ -483,6 +545,7 @@ g_irepository_get_namespaces (GIRepository *repository)
|
|||||||
repository = get_repository (repository);
|
repository = get_repository (repository);
|
||||||
|
|
||||||
g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list);
|
g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list);
|
||||||
|
g_hash_table_foreach (repository->priv->lazy_typelibs, collect_namespaces, &list);
|
||||||
|
|
||||||
names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1));
|
names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1));
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -502,7 +565,7 @@ g_irepository_get_shared_library (GIRepository *repository,
|
|||||||
|
|
||||||
repository = get_repository (repository);
|
repository = get_repository (repository);
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
typelib = get_registered (repository, namespace);
|
||||||
if (!typelib)
|
if (!typelib)
|
||||||
return NULL;
|
return NULL;
|
||||||
header = (Header *) typelib->data;
|
header = (Header *) typelib->data;
|
||||||
@ -535,7 +598,12 @@ g_irepository_get_typelib_path (GIRepository *repository,
|
|||||||
|
|
||||||
if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace,
|
if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace,
|
||||||
&orig_key, &value))
|
&orig_key, &value))
|
||||||
|
{
|
||||||
|
if (!g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace,
|
||||||
|
&orig_key, &value))
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return ((char*)orig_key) + strlen ((char *) orig_key) + 1;
|
return ((char*)orig_key) + strlen ((char *) orig_key) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,6 +611,7 @@ g_irepository_get_typelib_path (GIRepository *repository,
|
|||||||
* g_irepository_require
|
* g_irepository_require
|
||||||
* @repository: Repository, may be %NULL for the default
|
* @repository: Repository, may be %NULL for the default
|
||||||
* @namespace: GI namespace to use, e.g. "Gtk"
|
* @namespace: GI namespace to use, e.g. "Gtk"
|
||||||
|
* @flags: Set of %GIRepositoryLoadFlags, may be %0
|
||||||
* @error: a #GError.
|
* @error: a #GError.
|
||||||
*
|
*
|
||||||
* Force the namespace @namespace to be loaded if it isn't
|
* Force the namespace @namespace to be loaded if it isn't
|
||||||
@ -555,6 +624,7 @@ g_irepository_get_typelib_path (GIRepository *repository,
|
|||||||
gboolean
|
gboolean
|
||||||
g_irepository_require (GIRepository *repository,
|
g_irepository_require (GIRepository *repository,
|
||||||
const gchar *namespace,
|
const gchar *namespace,
|
||||||
|
GIRepositoryLoadFlags flags,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GSList *ldir;
|
GSList *ldir;
|
||||||
@ -566,13 +636,12 @@ g_irepository_require (GIRepository *repository,
|
|||||||
const gchar *typelib_namespace, *shlib_fname;
|
const gchar *typelib_namespace, *shlib_fname;
|
||||||
GModule *module;
|
GModule *module;
|
||||||
guint32 shlib;
|
guint32 shlib;
|
||||||
GHashTable *table;
|
gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY;
|
||||||
|
gboolean is_lazy;
|
||||||
|
|
||||||
repository = get_repository (repository);
|
repository = get_repository (repository);
|
||||||
table = repository->priv->typelibs;
|
|
||||||
|
|
||||||
/* don't bother loading a namespace if already registered */
|
if (get_registered_status (repository, namespace, allow_lazy, &is_lazy))
|
||||||
if (g_hash_table_lookup (table, namespace))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
fname = g_strconcat (namespace, ".typelib", NULL);
|
fname = g_strconcat (namespace, ".typelib", NULL);
|
||||||
@ -617,7 +686,8 @@ g_irepository_require (GIRepository *repository,
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_free (fname);
|
g_free (fname);
|
||||||
if (!register_internal (repository, full_path, typelib, error))
|
if (!register_internal (repository, full_path, allow_lazy,
|
||||||
|
typelib, error))
|
||||||
{
|
{
|
||||||
g_typelib_free (typelib);
|
g_typelib_free (typelib);
|
||||||
g_free (full_path);
|
g_free (full_path);
|
||||||
|
@ -67,6 +67,10 @@ struct _GIRepositoryClass
|
|||||||
GObjectClass parent;
|
GObjectClass parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
G_IREPOSITORY_LOAD_FLAG_LAZY = 1 << 0
|
||||||
|
} GIRepositoryLoadFlags;
|
||||||
|
|
||||||
/* Repository */
|
/* Repository */
|
||||||
|
|
||||||
@ -75,9 +79,8 @@ GIRepository *g_irepository_get_default (void);
|
|||||||
void g_irepository_prepend_search_path (const char *directory);
|
void g_irepository_prepend_search_path (const char *directory);
|
||||||
const char * g_irepository_load_typelib (GIRepository *repository,
|
const char * g_irepository_load_typelib (GIRepository *repository,
|
||||||
GTypelib *typelib,
|
GTypelib *typelib,
|
||||||
|
GIRepositoryLoadFlags flags,
|
||||||
GError **error);
|
GError **error);
|
||||||
void g_irepository_unregister (GIRepository *repository,
|
|
||||||
const gchar *namespace);
|
|
||||||
gboolean g_irepository_is_registered (GIRepository *repository,
|
gboolean g_irepository_is_registered (GIRepository *repository,
|
||||||
const gchar *namespace);
|
const gchar *namespace);
|
||||||
GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
|
GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
|
||||||
@ -85,6 +88,7 @@ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
|
|||||||
const gchar *name);
|
const gchar *name);
|
||||||
gboolean g_irepository_require (GIRepository *repository,
|
gboolean g_irepository_require (GIRepository *repository,
|
||||||
const char *namespace,
|
const char *namespace,
|
||||||
|
GIRepositoryLoadFlags flags,
|
||||||
GError **error);
|
GError **error);
|
||||||
gchar ** g_irepository_get_dependencies (GIRepository *repository,
|
gchar ** g_irepository_get_dependencies (GIRepository *repository,
|
||||||
const char *namespace);
|
const char *namespace);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user