mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +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:
		
							
								
								
									
										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);
 | 
			
		||||
      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;
 | 
			
		||||
 | 
			
		||||
	  result = (GIBaseInfo*)unresolved;
 | 
			
		||||
	  char **all_namespaces = g_irepository_get_namespaces (repository);
 | 
			
		||||
	  char *namespaces_str = g_strjoinv (", ", all_namespaces);
 | 
			
		||||
	  g_critical ("Failed to find namespace: %s name: %s (currently loaded namespaces: %s)", namespace,
 | 
			
		||||
		      name, namespaces_str);
 | 
			
		||||
	  g_strfreev (all_namespaces);
 | 
			
		||||
	  g_free (namespaces_str);
 | 
			
		||||
	}
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
@@ -294,14 +290,6 @@ g_base_info_get_name (GIBaseInfo *info)
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case GI_INFO_TYPE_UNRESOLVED:
 | 
			
		||||
      {
 | 
			
		||||
	GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
 | 
			
		||||
 | 
			
		||||
	return unresolved->name;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case GI_INFO_TYPE_TYPE:
 | 
			
		||||
    default: ;
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
@@ -318,13 +306,6 @@ g_base_info_get_namespace (GIBaseInfo *info)
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										221
									
								
								girepository.c
									
									
									
									
									
								
							
							
						
						
									
										221
									
								
								girepository.c
									
									
									
									
									
								
							@@ -30,12 +30,11 @@
 | 
			
		||||
 | 
			
		||||
static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT;
 | 
			
		||||
static GIRepository *default_repository = NULL;
 | 
			
		||||
static GHashTable *default_typelib = NULL;
 | 
			
		||||
static GSList *search_path = NULL;
 | 
			
		||||
 | 
			
		||||
struct _GIRepositoryPrivate 
 | 
			
		||||
{
 | 
			
		||||
  GHashTable *typelib; /* (string) namespace -> GTypelib */
 | 
			
		||||
  GHashTable *typelibs; /* (string) namespace -> GTypelib */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
 | 
			
		||||
@@ -52,7 +51,7 @@ g_irepository_finalize (GObject *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));
 | 
			
		||||
}
 | 
			
		||||
@@ -77,11 +76,10 @@ init_globals ()
 | 
			
		||||
  if (default_repository == NULL) 
 | 
			
		||||
    { 
 | 
			
		||||
      default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL);
 | 
			
		||||
      if (default_typelib == NULL)
 | 
			
		||||
	default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal,
 | 
			
		||||
                                                  (GDestroyNotify) NULL,
 | 
			
		||||
                                                  (GDestroyNotify) g_typelib_free);
 | 
			
		||||
      default_repository->priv->typelib = default_typelib;
 | 
			
		||||
      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)
 | 
			
		||||
@@ -102,6 +100,13 @@ init_globals ()
 | 
			
		||||
  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 *
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const gchar *
 | 
			
		||||
register_internal (GIRepository *repository,
 | 
			
		||||
		   const char   *source,
 | 
			
		||||
		   GTypelib     *typelib)
 | 
			
		||||
static char **
 | 
			
		||||
get_typelib_dependencies (GTypelib *typelib)
 | 
			
		||||
{
 | 
			
		||||
  Header *header;
 | 
			
		||||
  const gchar *name;
 | 
			
		||||
  GHashTable *table;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (typelib != NULL, NULL);
 | 
			
		||||
  
 | 
			
		||||
  const char *dependencies_glob;
 | 
			
		||||
 | 
			
		||||
  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->priv->typelib == NULL)
 | 
			
		||||
	repository->priv->typelib = g_hash_table_new_full (g_str_hash, g_str_equal,
 | 
			
		||||
      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);
 | 
			
		||||
      table = repository->priv->typelib;
 | 
			
		||||
      return repository;
 | 
			
		||||
    }
 | 
			
		||||
  else 
 | 
			
		||||
    {
 | 
			
		||||
      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);
 | 
			
		||||
 | 
			
		||||
  if (g_hash_table_lookup (table, name))
 | 
			
		||||
  dependencies = get_typelib_dependencies (typelib);
 | 
			
		||||
  if (dependencies != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_printerr ("typelib (%p) for '%s' already registered\n",
 | 
			
		||||
		 typelib, name);
 | 
			
		||||
 | 
			
		||||
      return NULL;
 | 
			
		||||
      int i;
 | 
			
		||||
	
 | 
			
		||||
      for (i = 0; dependencies[i]; i++)
 | 
			
		||||
	{
 | 
			
		||||
	  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)
 | 
			
		||||
      typelib->module = g_module_open (NULL, 0); 
 | 
			
		||||
@@ -158,28 +196,47 @@ register_internal (GIRepository *repository,
 | 
			
		||||
  return name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
g_irepository_register (GIRepository *repository,
 | 
			
		||||
                        GTypelib     *typelib)
 | 
			
		||||
char **
 | 
			
		||||
g_irepository_get_dependencies (GIRepository *repository,
 | 
			
		||||
				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
 | 
			
		||||
g_irepository_unregister (GIRepository *repository,
 | 
			
		||||
                          const gchar  *namespace)
 | 
			
		||||
{
 | 
			
		||||
  GHashTable *table;
 | 
			
		||||
  repository = get_repository (repository);
 | 
			
		||||
 | 
			
		||||
  if (repository != NULL)
 | 
			
		||||
    table = repository->priv->typelib;
 | 
			
		||||
  else 
 | 
			
		||||
    {
 | 
			
		||||
      init_globals ();
 | 
			
		||||
      table = default_typelib;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!g_hash_table_remove (table, namespace))
 | 
			
		||||
  if (!g_hash_table_remove (repository->priv->typelibs, namespace))
 | 
			
		||||
    {
 | 
			
		||||
      g_printerr ("namespace '%s' not registered\n", namespace);
 | 
			
		||||
    }
 | 
			
		||||
@@ -189,24 +246,15 @@ gboolean
 | 
			
		||||
g_irepository_is_registered (GIRepository *repository, 
 | 
			
		||||
			     const gchar *namespace)
 | 
			
		||||
{
 | 
			
		||||
  GHashTable *table;
 | 
			
		||||
  repository = get_repository (repository);
 | 
			
		||||
 | 
			
		||||
  if (repository != NULL)
 | 
			
		||||
    table = repository->priv->typelib;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      init_globals ();
 | 
			
		||||
      table = default_typelib;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return g_hash_table_lookup (table, namespace) != NULL;
 | 
			
		||||
  return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GIRepository * 
 | 
			
		||||
g_irepository_get_default (void)
 | 
			
		||||
{
 | 
			
		||||
  init_globals ();
 | 
			
		||||
  return default_repository; 
 | 
			
		||||
  return get_repository (NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
@@ -225,19 +273,21 @@ g_irepository_get_n_infos (GIRepository *repository,
 | 
			
		||||
			   const gchar  *namespace)
 | 
			
		||||
{
 | 
			
		||||
  gint n_interfaces = 0;
 | 
			
		||||
 | 
			
		||||
  repository = get_repository (repository);
 | 
			
		||||
  
 | 
			
		||||
  if (namespace)
 | 
			
		||||
    {
 | 
			
		||||
      GTypelib *typelib;
 | 
			
		||||
 | 
			
		||||
      typelib = g_hash_table_lookup (repository->priv->typelib, namespace);
 | 
			
		||||
      typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
 | 
			
		||||
 | 
			
		||||
      if (typelib)
 | 
			
		||||
	n_interfaces = ((Header *)typelib->data)->n_local_entries;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_hash_table_foreach (repository->priv->typelib, 
 | 
			
		||||
      g_hash_table_foreach (repository->priv->typelibs, 
 | 
			
		||||
			    count_interfaces, &n_interfaces);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -323,6 +373,8 @@ g_irepository_get_info (GIRepository *repository,
 | 
			
		||||
{
 | 
			
		||||
  IfaceData data;
 | 
			
		||||
 | 
			
		||||
  repository = get_repository (repository);
 | 
			
		||||
 | 
			
		||||
  data.name = NULL;
 | 
			
		||||
  data.type = NULL;
 | 
			
		||||
  data.index = index + 1;
 | 
			
		||||
@@ -332,13 +384,13 @@ g_irepository_get_info (GIRepository *repository,
 | 
			
		||||
    {
 | 
			
		||||
      GTypelib *typelib;
 | 
			
		||||
      
 | 
			
		||||
      typelib = g_hash_table_lookup (repository->priv->typelib, namespace);
 | 
			
		||||
      typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
 | 
			
		||||
      
 | 
			
		||||
      if (typelib)
 | 
			
		||||
	find_interface ((void *)namespace, typelib, &data);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    g_hash_table_foreach (repository->priv->typelib, find_interface, &data);
 | 
			
		||||
    g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
 | 
			
		||||
 | 
			
		||||
  return data.iface;  
 | 
			
		||||
}
 | 
			
		||||
@@ -349,12 +401,14 @@ g_irepository_find_by_gtype (GIRepository *repository,
 | 
			
		||||
{
 | 
			
		||||
  IfaceData data;
 | 
			
		||||
 | 
			
		||||
  repository = get_repository (repository);
 | 
			
		||||
 | 
			
		||||
  data.name = NULL;
 | 
			
		||||
  data.type = g_type_name (type);
 | 
			
		||||
  data.index = -1;
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
@@ -377,6 +431,8 @@ g_irepository_find_by_name (GIRepository *repository,
 | 
			
		||||
{
 | 
			
		||||
  IfaceData data;
 | 
			
		||||
 | 
			
		||||
  repository = get_repository (repository);
 | 
			
		||||
 | 
			
		||||
  data.name = name;
 | 
			
		||||
  data.type = NULL;
 | 
			
		||||
  data.index = -1;
 | 
			
		||||
@@ -386,13 +442,13 @@ g_irepository_find_by_name (GIRepository *repository,
 | 
			
		||||
    {
 | 
			
		||||
      GTypelib *typelib;
 | 
			
		||||
      
 | 
			
		||||
      typelib = g_hash_table_lookup (repository->priv->typelib, namespace);
 | 
			
		||||
      typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
 | 
			
		||||
      
 | 
			
		||||
      if (typelib)
 | 
			
		||||
	find_interface ((void *)namespace, typelib, &data);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    g_hash_table_foreach (repository->priv->typelib, find_interface, &data);
 | 
			
		||||
    g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
 | 
			
		||||
 | 
			
		||||
  return data.iface;
 | 
			
		||||
}
 | 
			
		||||
@@ -424,7 +480,9 @@ g_irepository_get_namespaces (GIRepository *repository)
 | 
			
		||||
  gchar **names;
 | 
			
		||||
  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));
 | 
			
		||||
  i = 0;
 | 
			
		||||
@@ -442,7 +500,9 @@ g_irepository_get_shared_library (GIRepository *repository,
 | 
			
		||||
  GTypelib *typelib;
 | 
			
		||||
  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)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  header = (Header *) typelib->data;
 | 
			
		||||
@@ -471,7 +531,9 @@ g_irepository_get_typelib_path (GIRepository *repository,
 | 
			
		||||
{
 | 
			
		||||
  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))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  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 
 | 
			
		||||
 * path.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: Namespace if successful, NULL otherwise
 | 
			
		||||
 * Returns: %TRUE if successful, %NULL otherwise
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
gboolean
 | 
			
		||||
g_irepository_require (GIRepository  *repository,
 | 
			
		||||
		       const gchar   *namespace,
 | 
			
		||||
		       GError       **error)
 | 
			
		||||
@@ -506,17 +568,12 @@ g_irepository_require (GIRepository  *repository,
 | 
			
		||||
  guint32 shlib;
 | 
			
		||||
  GHashTable *table;
 | 
			
		||||
 | 
			
		||||
  if (repository != NULL)
 | 
			
		||||
    table = repository->priv->typelib;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      init_globals ();
 | 
			
		||||
      table = default_typelib;
 | 
			
		||||
    }
 | 
			
		||||
  repository = get_repository (repository);
 | 
			
		||||
  table = repository->priv->typelibs;
 | 
			
		||||
 | 
			
		||||
  /* don't bother loading a namespace if already registered */
 | 
			
		||||
  if (g_hash_table_lookup (table, namespace))
 | 
			
		||||
    return namespace;
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  fname = g_strconcat (namespace, ".typelib", NULL);
 | 
			
		||||
 | 
			
		||||
@@ -544,7 +601,7 @@ g_irepository_require (GIRepository  *repository,
 | 
			
		||||
		       "namespace '%s' which doesn't match the file name",
 | 
			
		||||
		       full_path, namespace, typelib_namespace);
 | 
			
		||||
	  g_free (full_path);
 | 
			
		||||
	  return NULL; 
 | 
			
		||||
	  return FALSE; 
 | 
			
		||||
	}
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
@@ -556,14 +613,18 @@ g_irepository_require (GIRepository  *repository,
 | 
			
		||||
		   "Typelib file for namespace '%s' was not found in search"
 | 
			
		||||
		   " path or could not be openened", namespace);
 | 
			
		||||
      g_free (full_path);
 | 
			
		||||
      return NULL;
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (fname);
 | 
			
		||||
  g_hash_table_remove (table, namespace);
 | 
			
		||||
  register_internal (repository, full_path, typelib);
 | 
			
		||||
  if (!register_internal (repository, full_path, typelib, error))
 | 
			
		||||
    {
 | 
			
		||||
      g_typelib_free (typelib);
 | 
			
		||||
      g_free (full_path);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  g_free (full_path);
 | 
			
		||||
  return namespace; 
 | 
			
		||||
  return TRUE; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -72,8 +72,10 @@ struct _GIRepositoryClass
 | 
			
		||||
 | 
			
		||||
GType         g_irepository_get_type      (void) G_GNUC_CONST;
 | 
			
		||||
GIRepository *g_irepository_get_default   (void);
 | 
			
		||||
const gchar * g_irepository_register      (GIRepository *repository,
 | 
			
		||||
					   GTypelib    *typelib);
 | 
			
		||||
void          g_irepository_prepend_search_path (const char *directory);
 | 
			
		||||
const char *  g_irepository_load_typelib  (GIRepository *repository,
 | 
			
		||||
					   GTypelib     *typelib,
 | 
			
		||||
					   GError      **error);
 | 
			
		||||
void          g_irepository_unregister    (GIRepository *repository,
 | 
			
		||||
					   const gchar  *namespace);
 | 
			
		||||
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,
 | 
			
		||||
					   const gchar  *namespace,
 | 
			
		||||
					   const gchar  *name);
 | 
			
		||||
const char *  g_irepository_require       (GIRepository *repository,
 | 
			
		||||
gboolean      g_irepository_require       (GIRepository *repository,
 | 
			
		||||
					   const char   *namespace,
 | 
			
		||||
					   GError      **error);
 | 
			
		||||
gchar      ** g_irepository_get_dependencies (GIRepository *repository,
 | 
			
		||||
					      const char *namespace);
 | 
			
		||||
gchar      ** g_irepository_get_namespaces (GIRepository *repository);
 | 
			
		||||
GIBaseInfo *  g_irepository_find_by_gtype (GIRepository *repository,
 | 
			
		||||
					   GType         gtype);
 | 
			
		||||
@@ -142,8 +146,7 @@ typedef enum
 | 
			
		||||
  GI_INFO_TYPE_PROPERTY,
 | 
			
		||||
  GI_INFO_TYPE_FIELD,
 | 
			
		||||
  GI_INFO_TYPE_ARG,
 | 
			
		||||
  GI_INFO_TYPE_TYPE,
 | 
			
		||||
  GI_INFO_TYPE_UNRESOLVED
 | 
			
		||||
  GI_INFO_TYPE_TYPE
 | 
			
		||||
} GIInfoType;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								girmodule.c
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								girmodule.c
									
									
									
									
									
								
							@@ -33,13 +33,14 @@ g_ir_module_new (const gchar *name, const gchar *shared_library)
 | 
			
		||||
{
 | 
			
		||||
  GIrModule *module;
 | 
			
		||||
  
 | 
			
		||||
  module = g_new (GIrModule, 1);
 | 
			
		||||
  module = g_new0 (GIrModule, 1);
 | 
			
		||||
 | 
			
		||||
  module->name = g_strdup (name);
 | 
			
		||||
  if (shared_library)
 | 
			
		||||
      module->shared_library = g_strdup (shared_library);
 | 
			
		||||
  else
 | 
			
		||||
      module->shared_library = NULL;
 | 
			
		||||
  module->dependencies = NULL;
 | 
			
		||||
  module->entries = NULL;
 | 
			
		||||
 | 
			
		||||
  return module;
 | 
			
		||||
@@ -56,6 +57,7 @@ g_ir_module_free (GIrModule *module)
 | 
			
		||||
    g_ir_node_free ((GIrNode *)e->data);
 | 
			
		||||
 | 
			
		||||
  g_list_free (module->entries);
 | 
			
		||||
  /* Don't free dependencies, we inherit that from the parser */
 | 
			
		||||
 | 
			
		||||
  g_free (module);
 | 
			
		||||
}
 | 
			
		||||
@@ -77,18 +79,42 @@ g_ir_module_build_typelib (GIrModule  *module,
 | 
			
		||||
  guint32 size, offset, offset2, old_offset;
 | 
			
		||||
  GHashTable *strings;
 | 
			
		||||
  GHashTable *types;
 | 
			
		||||
  char *dependencies;
 | 
			
		||||
  guchar *data;
 | 
			
		||||
 | 
			
		||||
  header_size = ALIGN_VALUE (sizeof (Header), 4);
 | 
			
		||||
  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:
 | 
			
		||||
  init_stats ();
 | 
			
		||||
  strings = 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);
 | 
			
		||||
 | 
			
		||||
  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;  
 | 
			
		||||
  size = header_size + dir_size;
 | 
			
		||||
@@ -106,6 +132,8 @@ g_ir_module_build_typelib (GIrModule  *module,
 | 
			
		||||
  size += strlen (module->name);
 | 
			
		||||
  if (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", 
 | 
			
		||||
	  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_annotations = 0;
 | 
			
		||||
  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->namespace = write_string (module->name, strings, data, &header_size);
 | 
			
		||||
  header->shared_library = (module->shared_library?
 | 
			
		||||
@@ -180,9 +212,11 @@ g_ir_module_build_typelib (GIrModule  *module,
 | 
			
		||||
 | 
			
		||||
      if (node->type == G_IR_NODE_XREF)
 | 
			
		||||
	{
 | 
			
		||||
	  const char *namespace = ((GIrNodeXRef*)node)->namespace;
 | 
			
		||||
	  
 | 
			
		||||
	  entry->blob_type = 0;
 | 
			
		||||
	  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);
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ struct _GIrModule
 | 
			
		||||
{ 
 | 
			
		||||
  gchar *name;
 | 
			
		||||
  gchar *shared_library;
 | 
			
		||||
  GList *dependencies;
 | 
			
		||||
  GList *entries;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -72,6 +72,7 @@ struct _ParseContext
 | 
			
		||||
  
 | 
			
		||||
  GList *modules;
 | 
			
		||||
  gboolean prefix_aliases;
 | 
			
		||||
  GList *dependencies;
 | 
			
		||||
  GHashTable *aliases;
 | 
			
		||||
 | 
			
		||||
  const char *namespace;
 | 
			
		||||
@@ -2188,6 +2189,9 @@ start_element_handler (GMarkupParseContext *context,
 | 
			
		||||
	  if (!parse_include (context, ctx, name, error))
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
	  ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup (name));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	  state_switch (ctx, STATE_INCLUDE);
 | 
			
		||||
	  goto out;
 | 
			
		||||
	}
 | 
			
		||||
@@ -2226,6 +2230,7 @@ start_element_handler (GMarkupParseContext *context,
 | 
			
		||||
	    {
 | 
			
		||||
	      ctx->current_module = g_ir_module_new (name, shared_library);
 | 
			
		||||
	      ctx->modules = g_list_append (ctx->modules, ctx->current_module);
 | 
			
		||||
	      ctx->current_module->dependencies = ctx->dependencies;
 | 
			
		||||
 | 
			
		||||
	      state_switch (ctx, STATE_NAMESPACE);
 | 
			
		||||
	      goto out;
 | 
			
		||||
@@ -2704,6 +2709,7 @@ g_ir_parse_string (const gchar  *namespace,
 | 
			
		||||
  ctx.namespace = namespace;
 | 
			
		||||
  ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 | 
			
		||||
  ctx.type_depth = 0;
 | 
			
		||||
  ctx.dependencies = NULL;
 | 
			
		||||
  ctx.current_module = 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; \
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  CHECK_SIZE (Header, 100);
 | 
			
		||||
  CHECK_SIZE (Header, 104);
 | 
			
		||||
  CHECK_SIZE (DirEntry, 12);
 | 
			
		||||
  CHECK_SIZE (SimpleTypeBlob, 4);
 | 
			
		||||
  CHECK_SIZE (ArgBlob, 12);
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,8 @@ typedef struct
 | 
			
		||||
  guint32 n_annotations;
 | 
			
		||||
  guint32 annotations;
 | 
			
		||||
 | 
			
		||||
  guint32 dependencies;
 | 
			
		||||
 | 
			
		||||
  guint32 size;
 | 
			
		||||
  guint32 namespace;
 | 
			
		||||
  guint32 shared_library;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user