mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 19:22:11 +01:00
Put dependencies in typelibs, resolve them when loading
* gir/Makefile.am: Dep on Makefile * girepository/ginfo.c: Print out a nicer error message if we failed to load something. * girepository/girepository.c: Clean up default typelib handling; remove global default_typelib variable. Ensure we handle NULL repository in more places. Support dependency resolution. * tests/Makefile.am: Kill off gobject.gir, it conflicts with the real one. * tests/Object.gir: Depend on GObject. * tools/generate.c: Take --includedir argument to say which directories to search for typelibs. Print out dependencies. svn path=/trunk/; revision=541
This commit is contained in:
parent
2ee1470611
commit
6e656b4498
33
ginfo.c
33
ginfo.c
@ -174,18 +174,14 @@ g_info_from_entry (GTypelib *typelib,
|
|||||||
result = g_irepository_find_by_name (repository, namespace, name);
|
result = g_irepository_find_by_name (repository, namespace, name);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
{
|
{
|
||||||
GIUnresolvedInfo *unresolved;
|
char **all_namespaces = g_irepository_get_namespaces (repository);
|
||||||
|
char *namespaces_str = g_strjoinv (", ", all_namespaces);
|
||||||
unresolved = g_new0 (GIUnresolvedInfo, 1);
|
g_critical ("Failed to find namespace: %s name: %s (currently loaded namespaces: %s)", namespace,
|
||||||
|
name, namespaces_str);
|
||||||
unresolved->type = GI_INFO_TYPE_UNRESOLVED;
|
g_strfreev (all_namespaces);
|
||||||
unresolved->ref_count = 1;
|
g_free (namespaces_str);
|
||||||
unresolved->container = NULL;
|
|
||||||
unresolved->name = name;
|
|
||||||
unresolved->namespace = namespace;
|
|
||||||
|
|
||||||
result = (GIBaseInfo*)unresolved;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -294,14 +290,6 @@ g_base_info_get_name (GIBaseInfo *info)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GI_INFO_TYPE_UNRESOLVED:
|
|
||||||
{
|
|
||||||
GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
|
|
||||||
|
|
||||||
return unresolved->name;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GI_INFO_TYPE_TYPE:
|
case GI_INFO_TYPE_TYPE:
|
||||||
default: ;
|
default: ;
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
@ -318,13 +306,6 @@ g_base_info_get_namespace (GIBaseInfo *info)
|
|||||||
|
|
||||||
g_assert (info->ref_count > 0);
|
g_assert (info->ref_count > 0);
|
||||||
|
|
||||||
if (info->type == GI_INFO_TYPE_UNRESOLVED)
|
|
||||||
{
|
|
||||||
GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
|
|
||||||
|
|
||||||
return unresolved->namespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_typelib_get_string (info->typelib, header->namespace);
|
return g_typelib_get_string (info->typelib, header->namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
221
girepository.c
221
girepository.c
@ -30,12 +30,11 @@
|
|||||||
|
|
||||||
static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT;
|
static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT;
|
||||||
static GIRepository *default_repository = NULL;
|
static GIRepository *default_repository = NULL;
|
||||||
static GHashTable *default_typelib = NULL;
|
|
||||||
static GSList *search_path = NULL;
|
static GSList *search_path = NULL;
|
||||||
|
|
||||||
struct _GIRepositoryPrivate
|
struct _GIRepositoryPrivate
|
||||||
{
|
{
|
||||||
GHashTable *typelib; /* (string) namespace -> GTypelib */
|
GHashTable *typelibs; /* (string) namespace -> GTypelib */
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
|
||||||
@ -52,7 +51,7 @@ g_irepository_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
GIRepository *repository = G_IREPOSITORY (object);
|
GIRepository *repository = G_IREPOSITORY (object);
|
||||||
|
|
||||||
g_hash_table_destroy (repository->priv->typelib);
|
g_hash_table_destroy (repository->priv->typelibs);
|
||||||
|
|
||||||
(* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository));
|
(* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository));
|
||||||
}
|
}
|
||||||
@ -77,11 +76,10 @@ 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);
|
||||||
if (default_typelib == NULL)
|
default_repository->priv->typelibs
|
||||||
default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal,
|
= g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
(GDestroyNotify) NULL,
|
(GDestroyNotify) NULL,
|
||||||
(GDestroyNotify) g_typelib_free);
|
(GDestroyNotify) g_typelib_free);
|
||||||
default_repository->priv->typelib = default_typelib;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search_path == NULL)
|
if (search_path == NULL)
|
||||||
@ -102,6 +100,13 @@ init_globals ()
|
|||||||
g_static_mutex_unlock (&globals_lock);
|
g_static_mutex_unlock (&globals_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_irepository_prepend_search_path (const char *directory)
|
||||||
|
{
|
||||||
|
init_globals ();
|
||||||
|
search_path = g_slist_prepend (search_path, g_strdup (directory));
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
build_typelib_key (const char *name, const char *source)
|
build_typelib_key (const char *name, const char *source)
|
||||||
{
|
{
|
||||||
@ -111,46 +116,79 @@ build_typelib_key (const char *name, const char *source)
|
|||||||
return g_string_free (str, FALSE);
|
return g_string_free (str, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gchar *
|
static char **
|
||||||
register_internal (GIRepository *repository,
|
get_typelib_dependencies (GTypelib *typelib)
|
||||||
const char *source,
|
|
||||||
GTypelib *typelib)
|
|
||||||
{
|
{
|
||||||
Header *header;
|
Header *header;
|
||||||
const gchar *name;
|
const char *dependencies_glob;
|
||||||
GHashTable *table;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (typelib != NULL, NULL);
|
|
||||||
|
|
||||||
header = (Header *)typelib->data;
|
header = (Header *)typelib->data;
|
||||||
|
|
||||||
g_return_val_if_fail (header != NULL, NULL);
|
if (header->dependencies == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dependencies_glob = g_typelib_get_string (typelib, header->dependencies);
|
||||||
|
return g_strsplit (dependencies_glob, "|", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GIRepository *
|
||||||
|
get_repository (GIRepository *repository)
|
||||||
|
{
|
||||||
if (repository != NULL)
|
if (repository != NULL)
|
||||||
{
|
{
|
||||||
if (repository->priv->typelib == NULL)
|
if (repository->priv->typelibs == NULL)
|
||||||
repository->priv->typelib = g_hash_table_new_full (g_str_hash, g_str_equal,
|
repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
(GDestroyNotify) NULL,
|
(GDestroyNotify) NULL,
|
||||||
(GDestroyNotify) g_typelib_free);
|
(GDestroyNotify) g_typelib_free);
|
||||||
table = repository->priv->typelib;
|
return repository;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
init_globals ();
|
init_globals ();
|
||||||
table = default_typelib;
|
return default_repository;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
register_internal (GIRepository *repository,
|
||||||
|
const char *source,
|
||||||
|
GTypelib *typelib,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
Header *header;
|
||||||
|
const gchar *name;
|
||||||
|
const char *dependencies_glob;
|
||||||
|
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);
|
name = g_typelib_get_string (typelib, header->namespace);
|
||||||
|
|
||||||
if (g_hash_table_lookup (table, name))
|
dependencies = get_typelib_dependencies (typelib);
|
||||||
|
if (dependencies != NULL)
|
||||||
{
|
{
|
||||||
g_printerr ("typelib (%p) for '%s' already registered\n",
|
int i;
|
||||||
typelib, name);
|
|
||||||
|
for (i = 0; dependencies[i]; i++)
|
||||||
return NULL;
|
{
|
||||||
|
char *dependency = dependencies[i];
|
||||||
|
|
||||||
|
if (!g_irepository_require (repository, dependency, error))
|
||||||
|
{
|
||||||
|
g_strfreev (dependencies);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev (dependencies);
|
||||||
}
|
}
|
||||||
g_hash_table_insert (table, build_typelib_key (name, source), (void *)typelib);
|
|
||||||
|
g_assert (g_hash_table_lookup (repository->priv->typelibs, name) == NULL);
|
||||||
|
g_hash_table_insert (repository->priv->typelibs,
|
||||||
|
build_typelib_key (name, source), (void *)typelib);
|
||||||
|
|
||||||
if (typelib->module == NULL)
|
if (typelib->module == NULL)
|
||||||
typelib->module = g_module_open (NULL, 0);
|
typelib->module = g_module_open (NULL, 0);
|
||||||
@ -158,28 +196,47 @@ register_internal (GIRepository *repository,
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *
|
char **
|
||||||
g_irepository_register (GIRepository *repository,
|
g_irepository_get_dependencies (GIRepository *repository,
|
||||||
GTypelib *typelib)
|
const char *namespace)
|
||||||
{
|
{
|
||||||
return register_internal (repository, "<builtin>", typelib);
|
GTypelib *typelib;
|
||||||
|
|
||||||
|
g_return_val_if_fail (namespace != NULL, NULL);
|
||||||
|
|
||||||
|
repository = get_repository (repository);
|
||||||
|
|
||||||
|
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
||||||
|
g_return_val_if_fail (typelib != NULL, NULL);
|
||||||
|
|
||||||
|
return get_typelib_dependencies (typelib);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
g_irepository_load_typelib (GIRepository *repository,
|
||||||
|
GTypelib *typelib,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
Header *header;
|
||||||
|
const char *namespace;
|
||||||
|
|
||||||
|
repository = get_repository (repository);
|
||||||
|
|
||||||
|
header = (Header *) typelib->data;
|
||||||
|
namespace = g_typelib_get_string (typelib, header->namespace);
|
||||||
|
|
||||||
|
if (g_hash_table_lookup (repository->priv->typelibs, namespace))
|
||||||
|
return namespace;
|
||||||
|
return register_internal (repository, "<builtin>", typelib, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_irepository_unregister (GIRepository *repository,
|
g_irepository_unregister (GIRepository *repository,
|
||||||
const gchar *namespace)
|
const gchar *namespace)
|
||||||
{
|
{
|
||||||
GHashTable *table;
|
repository = get_repository (repository);
|
||||||
|
|
||||||
if (repository != NULL)
|
if (!g_hash_table_remove (repository->priv->typelibs, namespace))
|
||||||
table = repository->priv->typelib;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
init_globals ();
|
|
||||||
table = default_typelib;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_hash_table_remove (table, namespace))
|
|
||||||
{
|
{
|
||||||
g_printerr ("namespace '%s' not registered\n", namespace);
|
g_printerr ("namespace '%s' not registered\n", namespace);
|
||||||
}
|
}
|
||||||
@ -189,24 +246,15 @@ gboolean
|
|||||||
g_irepository_is_registered (GIRepository *repository,
|
g_irepository_is_registered (GIRepository *repository,
|
||||||
const gchar *namespace)
|
const gchar *namespace)
|
||||||
{
|
{
|
||||||
GHashTable *table;
|
repository = get_repository (repository);
|
||||||
|
|
||||||
if (repository != NULL)
|
return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL;
|
||||||
table = repository->priv->typelib;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
init_globals ();
|
|
||||||
table = default_typelib;
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_hash_table_lookup (table, namespace) != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GIRepository *
|
GIRepository *
|
||||||
g_irepository_get_default (void)
|
g_irepository_get_default (void)
|
||||||
{
|
{
|
||||||
init_globals ();
|
return get_repository (NULL);
|
||||||
return default_repository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -225,19 +273,21 @@ g_irepository_get_n_infos (GIRepository *repository,
|
|||||||
const gchar *namespace)
|
const gchar *namespace)
|
||||||
{
|
{
|
||||||
gint n_interfaces = 0;
|
gint n_interfaces = 0;
|
||||||
|
|
||||||
|
repository = get_repository (repository);
|
||||||
|
|
||||||
if (namespace)
|
if (namespace)
|
||||||
{
|
{
|
||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelib, namespace);
|
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
||||||
|
|
||||||
if (typelib)
|
if (typelib)
|
||||||
n_interfaces = ((Header *)typelib->data)->n_local_entries;
|
n_interfaces = ((Header *)typelib->data)->n_local_entries;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_hash_table_foreach (repository->priv->typelib,
|
g_hash_table_foreach (repository->priv->typelibs,
|
||||||
count_interfaces, &n_interfaces);
|
count_interfaces, &n_interfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +373,8 @@ g_irepository_get_info (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
IfaceData data;
|
IfaceData data;
|
||||||
|
|
||||||
|
repository = get_repository (repository);
|
||||||
|
|
||||||
data.name = NULL;
|
data.name = NULL;
|
||||||
data.type = NULL;
|
data.type = NULL;
|
||||||
data.index = index + 1;
|
data.index = index + 1;
|
||||||
@ -332,13 +384,13 @@ g_irepository_get_info (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelib, namespace);
|
typelib = g_hash_table_lookup (repository->priv->typelibs, 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->typelib, find_interface, &data);
|
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
||||||
|
|
||||||
return data.iface;
|
return data.iface;
|
||||||
}
|
}
|
||||||
@ -349,12 +401,14 @@ g_irepository_find_by_gtype (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
IfaceData data;
|
IfaceData data;
|
||||||
|
|
||||||
|
repository = get_repository (repository);
|
||||||
|
|
||||||
data.name = NULL;
|
data.name = NULL;
|
||||||
data.type = g_type_name (type);
|
data.type = g_type_name (type);
|
||||||
data.index = -1;
|
data.index = -1;
|
||||||
data.iface = NULL;
|
data.iface = NULL;
|
||||||
|
|
||||||
g_hash_table_foreach (repository->priv->typelib, find_interface, &data);
|
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
||||||
|
|
||||||
return data.iface;
|
return data.iface;
|
||||||
}
|
}
|
||||||
@ -377,6 +431,8 @@ g_irepository_find_by_name (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
IfaceData data;
|
IfaceData data;
|
||||||
|
|
||||||
|
repository = get_repository (repository);
|
||||||
|
|
||||||
data.name = name;
|
data.name = name;
|
||||||
data.type = NULL;
|
data.type = NULL;
|
||||||
data.index = -1;
|
data.index = -1;
|
||||||
@ -386,13 +442,13 @@ g_irepository_find_by_name (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelib, namespace);
|
typelib = g_hash_table_lookup (repository->priv->typelibs, 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->typelib, find_interface, &data);
|
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
|
||||||
|
|
||||||
return data.iface;
|
return data.iface;
|
||||||
}
|
}
|
||||||
@ -424,7 +480,9 @@ g_irepository_get_namespaces (GIRepository *repository)
|
|||||||
gchar **names;
|
gchar **names;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
g_hash_table_foreach (repository->priv->typelib, collect_namespaces, &list);
|
repository = get_repository (repository);
|
||||||
|
|
||||||
|
g_hash_table_foreach (repository->priv->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;
|
||||||
@ -442,7 +500,9 @@ g_irepository_get_shared_library (GIRepository *repository,
|
|||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
Header *header;
|
Header *header;
|
||||||
|
|
||||||
typelib = g_hash_table_lookup (repository->priv->typelib, namespace);
|
repository = get_repository (repository);
|
||||||
|
|
||||||
|
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
|
||||||
if (!typelib)
|
if (!typelib)
|
||||||
return NULL;
|
return NULL;
|
||||||
header = (Header *) typelib->data;
|
header = (Header *) typelib->data;
|
||||||
@ -471,7 +531,9 @@ g_irepository_get_typelib_path (GIRepository *repository,
|
|||||||
{
|
{
|
||||||
gpointer orig_key, value;
|
gpointer orig_key, value;
|
||||||
|
|
||||||
if (!g_hash_table_lookup_extended (repository->priv->typelib, namespace,
|
repository = get_repository (repository);
|
||||||
|
|
||||||
|
if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace,
|
||||||
&orig_key, &value))
|
&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;
|
||||||
@ -488,9 +550,9 @@ g_irepository_get_typelib_path (GIRepository *repository,
|
|||||||
* search for a ".typelib" file using the repository search
|
* search for a ".typelib" file using the repository search
|
||||||
* path.
|
* path.
|
||||||
*
|
*
|
||||||
* Returns: Namespace if successful, NULL otherwise
|
* Returns: %TRUE if successful, %NULL otherwise
|
||||||
*/
|
*/
|
||||||
const gchar *
|
gboolean
|
||||||
g_irepository_require (GIRepository *repository,
|
g_irepository_require (GIRepository *repository,
|
||||||
const gchar *namespace,
|
const gchar *namespace,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -506,17 +568,12 @@ g_irepository_require (GIRepository *repository,
|
|||||||
guint32 shlib;
|
guint32 shlib;
|
||||||
GHashTable *table;
|
GHashTable *table;
|
||||||
|
|
||||||
if (repository != NULL)
|
repository = get_repository (repository);
|
||||||
table = repository->priv->typelib;
|
table = repository->priv->typelibs;
|
||||||
else
|
|
||||||
{
|
|
||||||
init_globals ();
|
|
||||||
table = default_typelib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* don't bother loading a namespace if already registered */
|
/* don't bother loading a namespace if already registered */
|
||||||
if (g_hash_table_lookup (table, namespace))
|
if (g_hash_table_lookup (table, namespace))
|
||||||
return namespace;
|
return TRUE;
|
||||||
|
|
||||||
fname = g_strconcat (namespace, ".typelib", NULL);
|
fname = g_strconcat (namespace, ".typelib", NULL);
|
||||||
|
|
||||||
@ -544,7 +601,7 @@ g_irepository_require (GIRepository *repository,
|
|||||||
"namespace '%s' which doesn't match the file name",
|
"namespace '%s' which doesn't match the file name",
|
||||||
full_path, namespace, typelib_namespace);
|
full_path, namespace, typelib_namespace);
|
||||||
g_free (full_path);
|
g_free (full_path);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -556,14 +613,18 @@ g_irepository_require (GIRepository *repository,
|
|||||||
"Typelib file for namespace '%s' was not found in search"
|
"Typelib file for namespace '%s' was not found in search"
|
||||||
" path or could not be openened", namespace);
|
" path or could not be openened", namespace);
|
||||||
g_free (full_path);
|
g_free (full_path);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (fname);
|
g_free (fname);
|
||||||
g_hash_table_remove (table, namespace);
|
if (!register_internal (repository, full_path, typelib, error))
|
||||||
register_internal (repository, full_path, typelib);
|
{
|
||||||
|
g_typelib_free (typelib);
|
||||||
|
g_free (full_path);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
g_free (full_path);
|
g_free (full_path);
|
||||||
return namespace;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,8 +72,10 @@ struct _GIRepositoryClass
|
|||||||
|
|
||||||
GType g_irepository_get_type (void) G_GNUC_CONST;
|
GType g_irepository_get_type (void) G_GNUC_CONST;
|
||||||
GIRepository *g_irepository_get_default (void);
|
GIRepository *g_irepository_get_default (void);
|
||||||
const gchar * g_irepository_register (GIRepository *repository,
|
void g_irepository_prepend_search_path (const char *directory);
|
||||||
GTypelib *typelib);
|
const char * g_irepository_load_typelib (GIRepository *repository,
|
||||||
|
GTypelib *typelib,
|
||||||
|
GError **error);
|
||||||
void g_irepository_unregister (GIRepository *repository,
|
void g_irepository_unregister (GIRepository *repository,
|
||||||
const gchar *namespace);
|
const gchar *namespace);
|
||||||
gboolean g_irepository_is_registered (GIRepository *repository,
|
gboolean g_irepository_is_registered (GIRepository *repository,
|
||||||
@ -81,9 +83,11 @@ gboolean g_irepository_is_registered (GIRepository *repository,
|
|||||||
GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
|
GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
|
||||||
const gchar *namespace,
|
const gchar *namespace,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
const char * g_irepository_require (GIRepository *repository,
|
gboolean g_irepository_require (GIRepository *repository,
|
||||||
const char *namespace,
|
const char *namespace,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
gchar ** g_irepository_get_dependencies (GIRepository *repository,
|
||||||
|
const char *namespace);
|
||||||
gchar ** g_irepository_get_namespaces (GIRepository *repository);
|
gchar ** g_irepository_get_namespaces (GIRepository *repository);
|
||||||
GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository,
|
GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository,
|
||||||
GType gtype);
|
GType gtype);
|
||||||
@ -142,8 +146,7 @@ typedef enum
|
|||||||
GI_INFO_TYPE_PROPERTY,
|
GI_INFO_TYPE_PROPERTY,
|
||||||
GI_INFO_TYPE_FIELD,
|
GI_INFO_TYPE_FIELD,
|
||||||
GI_INFO_TYPE_ARG,
|
GI_INFO_TYPE_ARG,
|
||||||
GI_INFO_TYPE_TYPE,
|
GI_INFO_TYPE_TYPE
|
||||||
GI_INFO_TYPE_UNRESOLVED
|
|
||||||
} GIInfoType;
|
} GIInfoType;
|
||||||
|
|
||||||
|
|
||||||
|
40
girmodule.c
40
girmodule.c
@ -33,13 +33,14 @@ g_ir_module_new (const gchar *name, const gchar *shared_library)
|
|||||||
{
|
{
|
||||||
GIrModule *module;
|
GIrModule *module;
|
||||||
|
|
||||||
module = g_new (GIrModule, 1);
|
module = g_new0 (GIrModule, 1);
|
||||||
|
|
||||||
module->name = g_strdup (name);
|
module->name = g_strdup (name);
|
||||||
if (shared_library)
|
if (shared_library)
|
||||||
module->shared_library = g_strdup (shared_library);
|
module->shared_library = g_strdup (shared_library);
|
||||||
else
|
else
|
||||||
module->shared_library = NULL;
|
module->shared_library = NULL;
|
||||||
|
module->dependencies = NULL;
|
||||||
module->entries = NULL;
|
module->entries = NULL;
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
@ -56,6 +57,7 @@ g_ir_module_free (GIrModule *module)
|
|||||||
g_ir_node_free ((GIrNode *)e->data);
|
g_ir_node_free ((GIrNode *)e->data);
|
||||||
|
|
||||||
g_list_free (module->entries);
|
g_list_free (module->entries);
|
||||||
|
/* Don't free dependencies, we inherit that from the parser */
|
||||||
|
|
||||||
g_free (module);
|
g_free (module);
|
||||||
}
|
}
|
||||||
@ -77,18 +79,42 @@ g_ir_module_build_typelib (GIrModule *module,
|
|||||||
guint32 size, offset, offset2, old_offset;
|
guint32 size, offset, offset2, old_offset;
|
||||||
GHashTable *strings;
|
GHashTable *strings;
|
||||||
GHashTable *types;
|
GHashTable *types;
|
||||||
|
char *dependencies;
|
||||||
guchar *data;
|
guchar *data;
|
||||||
|
|
||||||
header_size = ALIGN_VALUE (sizeof (Header), 4);
|
header_size = ALIGN_VALUE (sizeof (Header), 4);
|
||||||
n_local_entries = g_list_length (module->entries);
|
n_local_entries = g_list_length (module->entries);
|
||||||
|
|
||||||
|
/* Serialize dependencies into one string; this is convenient
|
||||||
|
* and not a major change to the typelib format. */
|
||||||
|
{
|
||||||
|
GString *dependencies_str = g_string_new ("");
|
||||||
|
GList *link;
|
||||||
|
for (link = module->dependencies; link; link = link->next)
|
||||||
|
{
|
||||||
|
const char *dependency = link->data;
|
||||||
|
if (!strcmp (dependency, module->name))
|
||||||
|
continue;
|
||||||
|
g_string_append (dependencies_str, dependency);
|
||||||
|
if (link->next)
|
||||||
|
g_string_append_c (dependencies_str, '|');
|
||||||
|
}
|
||||||
|
dependencies = g_string_free (dependencies_str, FALSE);
|
||||||
|
if (!dependencies[0])
|
||||||
|
{
|
||||||
|
g_free (dependencies);
|
||||||
|
dependencies = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
init_stats ();
|
init_stats ();
|
||||||
strings = g_hash_table_new (g_str_hash, g_str_equal);
|
strings = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
types = g_hash_table_new (g_str_hash, g_str_equal);
|
types = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
n_entries = g_list_length (module->entries);
|
n_entries = g_list_length (module->entries);
|
||||||
|
|
||||||
g_message ("%d entries (%d local)\n", n_entries, n_local_entries);
|
g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries,
|
||||||
|
g_list_length (module->dependencies));
|
||||||
|
|
||||||
dir_size = n_entries * 12;
|
dir_size = n_entries * 12;
|
||||||
size = header_size + dir_size;
|
size = header_size + dir_size;
|
||||||
@ -106,6 +132,8 @@ g_ir_module_build_typelib (GIrModule *module,
|
|||||||
size += strlen (module->name);
|
size += strlen (module->name);
|
||||||
if (module->shared_library)
|
if (module->shared_library)
|
||||||
size += strlen (module->shared_library);
|
size += strlen (module->shared_library);
|
||||||
|
if (dependencies != NULL)
|
||||||
|
size += strlen (dependencies);
|
||||||
|
|
||||||
g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n",
|
g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n",
|
||||||
size, header_size, dir_size, size - header_size - dir_size);
|
size, header_size, dir_size, size - header_size - dir_size);
|
||||||
@ -122,6 +150,10 @@ g_ir_module_build_typelib (GIrModule *module,
|
|||||||
header->n_local_entries = n_local_entries;
|
header->n_local_entries = n_local_entries;
|
||||||
header->n_annotations = 0;
|
header->n_annotations = 0;
|
||||||
header->annotations = 0; /* filled in later */
|
header->annotations = 0; /* filled in later */
|
||||||
|
if (dependencies != NULL)
|
||||||
|
header->dependencies = write_string (dependencies, strings, data, &header_size);
|
||||||
|
else
|
||||||
|
header->dependencies = 0;
|
||||||
header->size = 0; /* filled in later */
|
header->size = 0; /* filled in later */
|
||||||
header->namespace = write_string (module->name, strings, data, &header_size);
|
header->namespace = write_string (module->name, strings, data, &header_size);
|
||||||
header->shared_library = (module->shared_library?
|
header->shared_library = (module->shared_library?
|
||||||
@ -180,9 +212,11 @@ g_ir_module_build_typelib (GIrModule *module,
|
|||||||
|
|
||||||
if (node->type == G_IR_NODE_XREF)
|
if (node->type == G_IR_NODE_XREF)
|
||||||
{
|
{
|
||||||
|
const char *namespace = ((GIrNodeXRef*)node)->namespace;
|
||||||
|
|
||||||
entry->blob_type = 0;
|
entry->blob_type = 0;
|
||||||
entry->local = FALSE;
|
entry->local = FALSE;
|
||||||
entry->offset = write_string (((GIrNodeXRef*)node)->namespace, strings, data, &offset2);
|
entry->offset = write_string (namespace, strings, data, &offset2);
|
||||||
entry->name = write_string (node->name, strings, data, &offset2);
|
entry->name = write_string (node->name, strings, data, &offset2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -33,6 +33,7 @@ struct _GIrModule
|
|||||||
{
|
{
|
||||||
gchar *name;
|
gchar *name;
|
||||||
gchar *shared_library;
|
gchar *shared_library;
|
||||||
|
GList *dependencies;
|
||||||
GList *entries;
|
GList *entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ struct _ParseContext
|
|||||||
|
|
||||||
GList *modules;
|
GList *modules;
|
||||||
gboolean prefix_aliases;
|
gboolean prefix_aliases;
|
||||||
|
GList *dependencies;
|
||||||
GHashTable *aliases;
|
GHashTable *aliases;
|
||||||
|
|
||||||
const char *namespace;
|
const char *namespace;
|
||||||
@ -2188,6 +2189,9 @@ start_element_handler (GMarkupParseContext *context,
|
|||||||
if (!parse_include (context, ctx, name, error))
|
if (!parse_include (context, ctx, name, error))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup (name));
|
||||||
|
|
||||||
|
|
||||||
state_switch (ctx, STATE_INCLUDE);
|
state_switch (ctx, STATE_INCLUDE);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -2226,6 +2230,7 @@ start_element_handler (GMarkupParseContext *context,
|
|||||||
{
|
{
|
||||||
ctx->current_module = g_ir_module_new (name, shared_library);
|
ctx->current_module = g_ir_module_new (name, shared_library);
|
||||||
ctx->modules = g_list_append (ctx->modules, ctx->current_module);
|
ctx->modules = g_list_append (ctx->modules, ctx->current_module);
|
||||||
|
ctx->current_module->dependencies = ctx->dependencies;
|
||||||
|
|
||||||
state_switch (ctx, STATE_NAMESPACE);
|
state_switch (ctx, STATE_NAMESPACE);
|
||||||
goto out;
|
goto out;
|
||||||
@ -2704,6 +2709,7 @@ g_ir_parse_string (const gchar *namespace,
|
|||||||
ctx.namespace = namespace;
|
ctx.namespace = namespace;
|
||||||
ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
ctx.type_depth = 0;
|
ctx.type_depth = 0;
|
||||||
|
ctx.dependencies = NULL;
|
||||||
ctx.current_module = NULL;
|
ctx.current_module = NULL;
|
||||||
|
|
||||||
context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
|
context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
|
||||||
|
@ -152,7 +152,7 @@ g_typelib_check_sanity (void)
|
|||||||
size_check_ok = FALSE; \
|
size_check_ok = FALSE; \
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_SIZE (Header, 100);
|
CHECK_SIZE (Header, 104);
|
||||||
CHECK_SIZE (DirEntry, 12);
|
CHECK_SIZE (DirEntry, 12);
|
||||||
CHECK_SIZE (SimpleTypeBlob, 4);
|
CHECK_SIZE (SimpleTypeBlob, 4);
|
||||||
CHECK_SIZE (ArgBlob, 12);
|
CHECK_SIZE (ArgBlob, 12);
|
||||||
|
@ -57,6 +57,8 @@ typedef struct
|
|||||||
guint32 n_annotations;
|
guint32 n_annotations;
|
||||||
guint32 annotations;
|
guint32 annotations;
|
||||||
|
|
||||||
|
guint32 dependencies;
|
||||||
|
|
||||||
guint32 size;
|
guint32 size;
|
||||||
guint32 namespace;
|
guint32 namespace;
|
||||||
guint32 shared_library;
|
guint32 shared_library;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user