gobject-introspection r872 - in trunk: girepository giscanner



Author: otaylor
Date: Mon Nov 10 23:58:49 2008
New Revision: 872
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=872&view=rev

Log:
Bug 560248 â "disguised structures"

Certain types like GIConv and GdkAtom are pointers internally but don't
look like pointers when referenced. They have the form.

 typedef struct _X *X;

Parse these as structures/records but mark them in the gir with a 'disguised'
attribute so that we know that they need special handling.

In the typelib treat them like any other structure.

Modified:
   trunk/girepository/girnode.h
   trunk/girepository/girparser.c
   trunk/giscanner/ast.py
   trunk/giscanner/girparser.py
   trunk/giscanner/girwriter.py
   trunk/giscanner/transformer.py

Modified: trunk/girepository/girnode.h
==============================================================================
--- trunk/girepository/girnode.h	(original)
+++ trunk/girepository/girnode.h	Mon Nov 10 23:58:49 2008
@@ -278,6 +278,7 @@
   GIrNode node;
 
   gboolean deprecated;
+  gboolean disguised;
 
   gchar *gtype_name;
   gchar *gtype_init;

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Mon Nov 10 23:58:49 2008
@@ -75,6 +75,7 @@
   gboolean prefix_aliases;
   GList *dependencies;
   GHashTable *aliases;
+  GHashTable *disguised_structures;
 
   const char *namespace;
   GIrModule *current_module;
@@ -94,6 +95,10 @@
 	     ParseContext        *ctx,
 	     GError             **error);
 
+static const gchar *find_attribute (const gchar  *name, 
+				    const gchar **attribute_names,
+				    const gchar **attribute_values);
+
 static void
 firstpass_start_element_handler (GMarkupParseContext *context,
 				 const gchar         *element_name,
@@ -109,6 +114,30 @@
       start_alias (context, element_name, attribute_names, attribute_values,
 		   ctx, error);
     }
+  else if (strcmp (element_name, "record") == 0)
+    {
+      const gchar *name;
+      const gchar *disguised;
+
+      name = find_attribute ("name", attribute_names, attribute_values);
+      disguised = find_attribute ("disguised", attribute_names, attribute_values);
+
+      if (disguised && strcmp (disguised, "1") == 0)
+	{
+	  char *key;
+
+	  if (ctx->prefix_aliases)
+	    {
+	      key = g_strdup_printf ("%s.%s", ctx->namespace, name);
+	    }
+	  else
+	    {
+	      key = g_strdup (name);
+	    }
+
+	  g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
+	}
+    }
 }
 
 static void
@@ -1549,6 +1578,13 @@
 
       typenode = parse_type (ctx, name);
 
+      /* A 'disguised' structure is one where the c:type is a typedef that
+       * doesn't look like a pointer, but is internally.
+       */
+      if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
+	  g_hash_table_lookup (ctx->disguised_structures, typenode->interface) != NULL)
+	is_pointer = TRUE;
+
       if (is_pointer)
 	typenode->is_pointer = is_pointer;
     }
@@ -1936,12 +1972,14 @@
     {
       const gchar *name;
       const gchar *deprecated;
+      const gchar *disguised;
       const gchar *gtype_name;
       const gchar *gtype_init;
       GIrNodeStruct *struct_;
       
       name = find_attribute ("name", attribute_names, attribute_values);
       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
+      disguised = find_attribute ("disguised", attribute_names, attribute_values);
       gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
       gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
 
@@ -1969,6 +2007,9 @@
       else
 	struct_->deprecated = FALSE;
 
+      if (disguised && strcmp (disguised, "1") == 0)
+	struct_->disguised = TRUE;
+
       struct_->gtype_name = g_strdup (gtype_name);
       struct_->gtype_init = g_strdup (gtype_init);
       
@@ -2102,6 +2143,7 @@
   sub_ctx.prefix_aliases = TRUE;
   sub_ctx.namespace = name;
   sub_ctx.aliases = ctx->aliases;
+  sub_ctx.disguised_structures = ctx->disguised_structures;
   sub_ctx.type_depth = 0;
 
   context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
@@ -2862,6 +2904,7 @@
   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.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
   ctx.type_depth = 0;
   ctx.dependencies = NULL;
   ctx.current_module = NULL;
@@ -2886,6 +2929,7 @@
  out:
 
   g_hash_table_destroy (ctx.aliases);
+  g_hash_table_destroy (ctx.disguised_structures);
   
   g_markup_parse_context_free (context);
   

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Mon Nov 10 23:58:49 2008
@@ -324,11 +324,12 @@
 
 class Struct(Node):
 
-    def __init__(self, name, symbol):
+    def __init__(self, name, symbol, disguised=False):
         Node.__init__(self, name)
         self.fields = []
         self.constructors = []
         self.symbol = symbol
+        self.disguised = disguised
 
 
 class Field(Node):

Modified: trunk/giscanner/girparser.py
==============================================================================
--- trunk/giscanner/girparser.py	(original)
+++ trunk/giscanner/girparser.py	Mon Nov 10 23:58:49 2008
@@ -212,8 +212,10 @@
                                      node.attrib[_glibns('get-type')],
                                      node.attrib.get(_cns('type')))
         else:
+            disguised = node.attrib.get('disguised') == '1'
             struct = Struct(node.attrib['name'],
-                            node.attrib.get(_cns('type')))
+                            node.attrib.get(_cns('type')),
+                            disguised=disguised)
         self._add_node(struct)
 
         if self._include_parsing:

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Mon Nov 10 23:58:49 2008
@@ -309,6 +309,8 @@
     def _write_record(self, record):
         attrs = [('name', record.name),
                  ('c:type', record.symbol)]
+        if record.disguised:
+            attrs.append(('disguised', '1'))
         self._append_deprecated(record, attrs)
         if isinstance(record, GLibBoxed):
             attrs.extend(self._boxed_attrs(record))

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Mon Nov 10 23:58:49 2008
@@ -343,6 +343,9 @@
         if (ctype == CTYPE_POINTER and
             symbol.base_type.base_type.type == CTYPE_FUNCTION):
             node = self._create_callback(symbol)
+        elif (ctype == CTYPE_POINTER and
+            symbol.base_type.base_type.type == CTYPE_STRUCT):
+            node = self._create_typedef_struct(symbol, disguised=True)
         elif ctype == CTYPE_STRUCT:
             node = self._create_typedef_struct(symbol)
         elif ctype == CTYPE_UNION:
@@ -567,9 +570,9 @@
         const = Constant(name, type_name, value)
         return const
 
-    def _create_typedef_struct(self, symbol):
+    def _create_typedef_struct(self, symbol, disguised=False):
         name = self.remove_prefix(symbol.ident)
-        struct = Struct(name, symbol.ident)
+        struct = Struct(name, symbol.ident, disguised)
         self._typedefs_ns[symbol.ident] = struct
         self._create_struct(symbol)
         return struct



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