gobject-introspection r512 - in trunk: gir girepository tools



Author: walters
Date: Thu Aug 28 21:19:22 2008
New Revision: 512
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=512&view=rev

Log:
Expand aliases when generating typelibs

	* gir/Makefile.am: Use --includedir
	* girepository/girparser.c: Recursively parse
	includes to pull in aliases and expand them.
	We need this to	avoid putting unknown names in
	the typelibs.
	* tools/compiler.c: Add --includedir option.


Modified:
   trunk/gir/Makefile.am
   trunk/girepository/girparser.c
   trunk/tools/compiler.c

Modified: trunk/gir/Makefile.am
==============================================================================
--- trunk/gir/Makefile.am	(original)
+++ trunk/gir/Makefile.am	Thu Aug 28 21:19:22 2008
@@ -85,8 +85,8 @@
 girdir=$(datadir)/gir
 dist_gir_DATA = $(BUILT_SOURCES)
 
-%.typelib: %.gir $(top_builddir)/tools/g-ir-compiler$(EXEEXT)
-	$(DEBUG) $(top_builddir)/tools/g-ir-compiler$(EXEEXT) $< -o $@
+%.typelib: %.gir $(top_builddir)/tools/g-ir-compiler$(EXEEXT) Makefile
+	$(DEBUG) $(top_builddir)/tools/g-ir-compiler$(EXEEXT) --includedir=. $(G_IR_COMPILER_OPTS) $< -o $@
 
 typelibsdir = $(datadir)/girepository
 typelibs_DATA = GLib.typelib GObject.typelib Gio.typelib

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Thu Aug 28 21:19:22 2008
@@ -68,15 +68,94 @@
   ParseState state;
   ParseState prev_state;
 
+  const char **includes;
+  
   GList *modules;
+  gboolean prefix_aliases;
   GHashTable *aliases;
 
+  const char *namespace;
   GIrModule *current_module;
   GIrNode *current_node;
   GIrNode *current_typed;
   int type_depth;
 };
 
+static gboolean
+start_alias (GMarkupParseContext *context,
+	     const gchar         *element_name,
+	     const gchar        **attribute_names,
+	     const gchar        **attribute_values,
+	     ParseContext        *ctx,
+	     GError             **error);
+
+static void
+firstpass_start_element_handler (GMarkupParseContext *context,
+				 const gchar         *element_name,
+				 const gchar        **attribute_names,
+				 const gchar        **attribute_values,
+				 gpointer             user_data,
+				 GError             **error)
+{
+  ParseContext *ctx = user_data;
+
+  if (strcmp (element_name, "alias") == 0) 
+    {
+      start_alias (context, element_name, attribute_names, attribute_values,
+		   ctx, error);
+    }
+}
+
+static void
+firstpass_end_element_handler (GMarkupParseContext *context,
+			       const gchar         *element_name,
+			       gpointer             user_data,
+			       GError             **error)
+{
+  ParseContext *ctx = user_data;
+
+}
+
+static GMarkupParser firstpass_parser = 
+{
+  firstpass_start_element_handler,
+  firstpass_end_element_handler,
+  NULL,
+  NULL,
+  NULL,
+};
+
+static char *
+locate_gir (const char *name, const char **extra_paths)
+{
+  const gchar *const *datadirs;
+  const gchar *const *dir;
+  char *girname;
+  char *path = NULL;
+  GSList *link;
+  gboolean firstpass = TRUE;
+      
+  datadirs = g_get_system_data_dirs ();
+      
+  girname = g_strdup_printf ("%s.gir", name);
+  
+  for (dir = datadirs; *dir; dir++) 
+    {
+      path = g_build_filename (*dir, "gir", girname, NULL);
+      if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+	return path;
+      g_free (path);
+      path = NULL;
+      if (firstpass && !*dir)
+	{
+	  firstpass = FALSE;
+	  dir = extra_paths;
+	}
+    }
+  g_free (girname);
+  return path;
+}
+
 #define MISSING_ATTRIBUTE(ctx,error,element,attribute)			        \
   do {                                                                          \
     int line_number, char_number;                                                \
@@ -946,6 +1025,8 @@
   const gchar *name;
   const gchar *target;
   const gchar *type;
+  char *key;
+  char *value;
 
   name = find_attribute ("name", attribute_names, attribute_values);
   if (name == NULL)
@@ -961,7 +1042,12 @@
       return FALSE;
     }
 
-  g_hash_table_insert (ctx->aliases, g_strdup (name), g_strdup (target));
+  if (ctx->prefix_aliases)
+    key = g_strdup_printf ("%s.%s", ctx->namespace, name);
+  else
+    key = g_strdup (name);
+  
+  g_hash_table_insert (ctx->aliases, key, g_strdup (target));
 
   return TRUE;
 }
@@ -1847,6 +1933,63 @@
 
   return FALSE;
 }
+
+static gboolean
+parse_include (GMarkupParseContext *context,
+	       ParseContext        *ctx,
+	       const char          *name,
+	       GError             **error)
+{
+  ParseContext sub_ctx = { 0 };
+  GMarkupParseContext *sub_context;
+  gchar *buffer;
+  gsize length;
+  char *girpath;
+  
+  girpath = locate_gir (name, ctx->includes);
+
+  if (girpath == NULL)
+    {
+      g_set_error (error,
+		   G_MARKUP_ERROR,
+		   G_MARKUP_ERROR_INVALID_CONTENT,
+		   "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir",
+		   name);
+      return FALSE;
+    }
+
+  g_debug ("Parsing include %s", girpath);
+
+  if (!g_file_get_contents (girpath, &buffer, &length, error))
+    {
+      g_free (girpath);
+      return FALSE;
+    }
+  g_free (girpath);
+
+  sub_ctx.state = STATE_START;
+  sub_ctx.prefix_aliases = TRUE;
+  sub_ctx.namespace = name;
+  sub_ctx.aliases = ctx->aliases;
+  sub_ctx.type_depth = 0;
+
+  context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
+	  
+  if (!g_markup_parse_context_parse (context, buffer, length, error))
+    {
+      g_free (buffer);
+      return FALSE;
+    }
+	  
+  if (!g_markup_parse_context_end_parse (context, error))
+    {
+      g_free (buffer);
+      return FALSE;
+    }
+	  
+  g_markup_parse_context_free (context);
+  return TRUE;
+}
   
 extern GLogLevelFlags logged_levels;
 
@@ -1972,6 +2115,19 @@
       if (strcmp (element_name, "include") == 0 &&
 	  ctx->state == STATE_REPOSITORY)
 	{
+	  const gchar *name;
+	  
+	  name = find_attribute ("name", attribute_names, attribute_values);
+
+	  if (name == NULL)
+	    {
+	      MISSING_ATTRIBUTE (context, error, element_name, "name");
+	      break;
+	    }
+
+	  if (!parse_include (context, ctx, name, error))
+	    break;
+
 	  state_switch (ctx, STATE_INCLUDE);
 	  goto out;
 	}
@@ -2464,44 +2620,6 @@
   ctx->current_module = NULL;
 }
 
-static void
-firstpass_start_element_handler (GMarkupParseContext *context,
-				 const gchar         *element_name,
-				 const gchar        **attribute_names,
-				 const gchar        **attribute_values,
-				 gpointer             user_data,
-				 GError             **error)
-{
-  ParseContext *ctx = user_data;
-
-  if (strcmp (element_name, "alias") == 0) 
-    {
-      start_alias (context, element_name, attribute_names, attribute_values,
-		   ctx, error);
-    }
-}
-
-static void
-firstpass_end_element_handler (GMarkupParseContext *context,
-			       const gchar         *element_name,
-			       gpointer             user_data,
-			       GError             **error)
-{
-  ParseContext *ctx = user_data;
-
-}
-
-
-static GMarkupParser firstpass_parser = 
-{
-  firstpass_start_element_handler,
-  firstpass_end_element_handler,
-  NULL,
-  NULL,
-  NULL,
-};
-
-
 static GMarkupParser parser = 
 {
   start_element_handler,
@@ -2512,7 +2630,8 @@
 };
 
 GList * 
-g_ir_parse_string (const gchar  *buffer, 
+g_ir_parse_string (const char   *namespace,
+		   const gchar  *buffer, 
 		   gssize        length,
 		   GError      **error)
 {
@@ -2520,6 +2639,8 @@
   GMarkupParseContext *context;
 
   ctx.state = STATE_START;
+  ctx.prefix_aliases = FALSE;
+  ctx.namespace = namespace;
   ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
   ctx.type_depth = 0;
 
@@ -2530,6 +2651,8 @@
 
   if (!g_markup_parse_context_end_parse (context, error))
     goto out;
+
+  g_markup_parse_context_free (context);
   
   context = g_markup_parse_context_new (&parser, 0, &ctx, NULL);
   if (!g_markup_parse_context_parse (context, buffer, length, error))
@@ -2554,13 +2677,33 @@
   gchar *buffer;
   gsize length;
   GList *modules;
+  const char *slash;
+  char *namespace;
+
+  if (!g_str_has_suffix (filename, ".gir"))
+    {
+      g_set_error (error,
+		   G_MARKUP_ERROR,
+		   G_MARKUP_ERROR_INVALID_CONTENT,
+		   "Expected filename to end with '.gir'");
+      return NULL;
+    }
 
   g_debug ("[parsing] filename %s", filename);
 
+  slash = g_strrstr (filename, "/");
+  if (!slash)
+    namespace = g_strdup (filename);
+  else
+    namespace = g_strdup (slash+1);
+  namespace[strlen(namespace)-4] = '\0';
+
   if (!g_file_get_contents (filename, &buffer, &length, error))
     return NULL;
   
-  modules = g_ir_parse_string (buffer, length, error);
+  modules = g_ir_parse_string (namespace, buffer, length, error);
+
+  g_free (namespace);
 
   g_free (buffer);
 

Modified: trunk/tools/compiler.c
==============================================================================
--- trunk/tools/compiler.c	(original)
+++ trunk/tools/compiler.c	Thu Aug 28 21:19:22 2008
@@ -36,6 +36,7 @@
 
 gboolean code = FALSE;
 gboolean no_init = FALSE;
+gchar **includedirs = NULL;
 gchar **input = NULL;
 gchar *output = NULL;
 gchar *mname = NULL;
@@ -160,6 +161,7 @@
 {
   { "code", 0, 0, G_OPTION_ARG_NONE, &code, "emit C code", NULL },
   { "no-init", 0, 0, G_OPTION_ARG_NONE, &no_init, "do not create _init() function", NULL },
+  { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL }, 
   { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, 
   { "module", 'm', 0, G_OPTION_ARG_STRING, &mname, "module to compile", "NAME" }, 
   { "shared-library", 'l', 0, G_OPTION_ARG_FILENAME, &shlib, "shared library", "FILE" }, 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]