gobject-introspection r439 - in trunk: . girepository giscanner



Author: walters
Date: Thu Aug 21 16:15:55 2008
New Revision: 439
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=439&view=rev

Log:
2008-08-21  Colin Walters  <walters verbum org>

	* girepository/girnode.c (write_string): Tweak to
	use UINT instead of INT.  Not likely to matter.
	* girepository/girmodule.c (g_ir_module_build_typelib):
	Add to header_offset as well for header strings
	to match what write_string does.
	* girepository/gtypelib.c: Replace is_name with
	validate_name, which more strongly validates and
	handles errors in a better way.  Update all callers.
	* giscanner/glibtransformer.py: Handle constructors
	better.


Modified:
   trunk/ChangeLog
   trunk/girepository/girmodule.c
   trunk/girepository/girnode.c
   trunk/girepository/gtypelib.c
   trunk/giscanner/glibtransformer.py

Modified: trunk/girepository/girmodule.c
==============================================================================
--- trunk/girepository/girmodule.c	(original)
+++ trunk/girepository/girmodule.c	Thu Aug 21 16:15:55 2008
@@ -104,8 +104,12 @@
 
   /* Adjust size for strings allocated in header below specially */
   size += strlen (module->name);
-  if (module->shared_library)
-    size += strlen (module->shared_library);
+  header_size = ALIGN_VALUE (header_size + strlen (module->name) + 1, 4);
+  if (module->shared_library) 
+    {
+      size += strlen (module->shared_library);
+      header_size = ALIGN_VALUE (header_size + strlen (module->shared_library) + 1, 4);
+    }
 
   g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", 
 	  size, header_size, dir_size, size - header_size - dir_size);

Modified: trunk/girepository/girnode.c
==============================================================================
--- trunk/girepository/girnode.c	(original)
+++ trunk/girepository/girnode.c	Thu Aug 21 16:15:55 2008
@@ -2144,12 +2144,12 @@
   value = g_hash_table_lookup (strings, str);
   
   if (value)
-    return GPOINTER_TO_INT (value);
+    return GPOINTER_TO_UINT (value);
 
   unique_string_count += 1;
   unique_string_size += strlen (str);
 
-  g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
+  g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset));
 
   start = *offset;
   *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);

Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c	(original)
+++ trunk/girepository/gtypelib.c	Thu Aug 21 16:15:55 2008
@@ -81,17 +81,44 @@
 #define MAX_NAME_LEN 200
 
 static gboolean
-is_name (const guchar *data, guint32 offset)
+validate_name (GTypelib *typelib,
+	       const char *msg,
+	       const guchar *data, guint32 offset,
+	       GError **error)
 {
   gchar *name;
 
+  if (typelib->len < offset)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short for type %s",
+		   msg);
+      return FALSE;
+    }
+
   name = (gchar*)&data[offset];
   
-  if (!memchr (name, '\0', MAX_NAME_LEN))
-    return FALSE;
+  if (!memchr (name, '\0', MAX_NAME_LEN)) 
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The %s is too long: %s",
+		   msg, name);
+      return FALSE;
+    }
   
-  if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
-    return FALSE;
+  if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) 
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The %s is contains invalid characters: %s",
+		   msg, name);
+      return FALSE;
+    }
   
   return TRUE;
 }
@@ -204,14 +231,8 @@
       return FALSE; 
     }
 
-  if (!is_name (typelib->data, header->namespace))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_HEADER,
-		   "Invalid namespace name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
+    return FALSE; 
 
   return TRUE;
 }
@@ -470,14 +491,8 @@
 
   blob = (ArgBlob*) &typelib->data[offset];
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid argument name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "argument", typelib->data, blob->name, error))
+    return FALSE; 
  
   if (!validate_type_blob (typelib, 
 			   offset + G_STRUCT_OFFSET (ArgBlob, arg_type), 
@@ -557,23 +572,11 @@
       return FALSE;
     }
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid function name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "function", typelib->data, blob->name, error))
+    return FALSE; 
   
-  if (!is_name (typelib->data, blob->symbol))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid function symbol");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error))
+    return FALSE; 
   
   if (blob->constructor)
     {
@@ -657,14 +660,8 @@
       return FALSE;
     }
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid callback name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "callback", typelib->data, blob->name, error))
+    return FALSE; 
   
   if (!validate_signature_blob (typelib, blob->signature, error))
     return FALSE;
@@ -708,14 +705,8 @@
       return FALSE;
     }
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid constant name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "constant", typelib->data, blob->name, error))
+    return FALSE; 
   
   if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type), 
 			   0, FALSE, error))
@@ -775,14 +766,8 @@
 
   blob = (ValueBlob*) &typelib->data[offset];
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid value name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "value", typelib->data, blob->name, error))
+    return FALSE; 
   
   return TRUE;
 }
@@ -805,15 +790,9 @@
 
   blob = (FieldBlob*) &typelib->data[offset];
   
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid field name");
-      return FALSE; 
-    }
-    
+  if (!validate_name (typelib, "field", typelib->data, blob->name, error))
+    return FALSE; 
+  
   if (!validate_type_blob (typelib,
 			   offset + G_STRUCT_OFFSET (FieldBlob, type), 
 			   0, FALSE, error))
@@ -840,14 +819,8 @@
 
   blob = (PropertyBlob*) &typelib->data[offset];
   
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid property name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "property", typelib->data, blob->name, error))
+    return FALSE; 
     
   if (!validate_type_blob (typelib,
 			   offset + G_STRUCT_OFFSET (PropertyBlob, type), 
@@ -877,14 +850,8 @@
 
   blob = (SignalBlob*) &typelib->data[offset];
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid signal name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "signal", typelib->data, blob->name, error))
+    return FALSE; 
   
   if ((blob->run_first != 0) + 
       (blob->run_last != 0) + 
@@ -952,14 +919,8 @@
 
   blob = (VFuncBlob*) &typelib->data[offset];
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid vfunc name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "vfunc", typelib->data, blob->name, error))
+    return FALSE; 
   
   if (blob->class_closure)
     {
@@ -1035,34 +996,16 @@
       return FALSE;
     }
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid struct name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "struct", typelib->data, blob->name, error))
+    return FALSE; 
   
   if (blob_type == BLOB_TYPE_BOXED)
     {
-      if (!is_name (typelib->data, blob->gtype_name))
-	{
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID_BLOB,
-		       "Invalid boxed type name");
-	  return FALSE; 
-	}
+      if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error))
+	return FALSE; 
 
-      if (!is_name (typelib->data, blob->gtype_init))
-	{
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID_BLOB,
-		       "Invalid boxed type init");
-	  return FALSE; 
-	}
+      if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_init, error))
+	return FALSE; 
     }
   else
     {
@@ -1142,23 +1085,11 @@
   
   if (!blob->unregistered)
     {
-      if (!is_name (typelib->data, blob->gtype_name))
-	{
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID_BLOB,
-		       "Invalid enum type name");
-	  return FALSE; 
-	}
+      if (!validate_name (typelib, "enum", typelib->data, blob->gtype_name, error))
+	return FALSE; 
 
-      if (!is_name (typelib->data, blob->gtype_init))
-	{
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID_BLOB,
-		       "Invalid enum type init");
-	  return FALSE; 
-	}
+      if (!validate_name (typelib, "enum", typelib->data, blob->gtype_init, error))
+	return FALSE; 
     }
   else
     {
@@ -1172,14 +1103,8 @@
 	}
     }
 
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid enum name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "enum", typelib->data, blob->name, error))
+    return FALSE; 
   
   if (typelib->len < offset + sizeof (EnumBlob) + 
       blob->n_values * sizeof (ValueBlob))
@@ -1256,32 +1181,14 @@
       return FALSE;
     }
   
-  if (!is_name (typelib->data, blob->gtype_name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid object type name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "object", typelib->data, blob->gtype_name, error))
+    return FALSE; 
   
-  if (!is_name (typelib->data, blob->gtype_init))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid object type init");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "object", typelib->data, blob->gtype_init, error))
+    return FALSE; 
   
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid object name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "object", typelib->data, blob->name, error))
+    return FALSE; 
   
   if (blob->parent > header->n_entries)
     {
@@ -1428,32 +1335,14 @@
       return FALSE;
     }
   
-  if (!is_name (typelib->data, blob->gtype_name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid interface type name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "interface", typelib->data, blob->gtype_name, error))
+    return FALSE; 
   
-  if (!is_name (typelib->data, blob->gtype_init))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid interface type init");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "interface", typelib->data, blob->gtype_init, error))
+    return FALSE; 
   
-  if (!is_name (typelib->data, blob->name))
-    {
-      g_set_error (error,
-		   G_TYPELIB_ERROR,
-		   G_TYPELIB_ERROR_INVALID_BLOB,
-		   "Invalid interface name");
-      return FALSE; 
-    }
+  if (!validate_name (typelib, "interface", typelib->data, blob->name, error))
+    return FALSE; 
   
   if (typelib->len < offset + sizeof (InterfaceBlob) + 
             (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 +
@@ -1642,14 +1531,8 @@
     {
       entry = g_typelib_get_dir_entry (typelib, i + 1);
 
-      if (!is_name (typelib->data, entry->name))
-	{
-	  g_set_error (error,
-		       G_TYPELIB_ERROR,
-		       G_TYPELIB_ERROR_INVALID_DIRECTORY,
-		       "Invalid entry name");
-	  return FALSE; 
-	}
+      if (!validate_name (typelib, "entry", typelib->data, entry->name, error))
+	return FALSE; 
       
       if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) ||
 	  entry->blob_type > BLOB_TYPE_UNION)
@@ -1695,14 +1578,8 @@
 	      return FALSE;
 	    }
 
-	  if (!is_name (typelib->data, entry->offset))
-	    {
-	      g_set_error (error,
-			   G_TYPELIB_ERROR,
-			   G_TYPELIB_ERROR_INVALID_DIRECTORY,
-			   "Invalid namespace name");
-	      return FALSE; 
-	    }
+	  if (!validate_name (typelib, "namespace", typelib->data, entry->offset, error))
+	    return FALSE; 
 	}
     }
 

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Thu Aug 21 16:15:55 2008
@@ -178,10 +178,6 @@
     def _parse_function(self, func):
         if self._parse_get_type_function(func):
             return
-        elif self._parse_constructor(func):
-            return
-        elif self._parse_method(func):
-            return
 
         self._add_attribute(func)
 
@@ -245,25 +241,41 @@
             target_arg = func.retval
         else:
             target_arg = func.parameters[0]
+        target_arg.type = self._resolve_param_type(target_arg.type)
+
         klass = self._get_attribute(target_arg.type.name)
-        if klass is None or not isinstance(klass, (GLibObject, GLibBoxed)):
-            return False
+        if klass is None or not isinstance(klass, (GLibObject, GLibBoxed,
+                                                   GLibInterface)):
+            return None
 
-        # Look at the original C type (before namespace stripping), without
-        # pointers: GtkButton -> gtk_button_, so we can figure out the
-        # method name
         orig_type = target_arg.type.ctype.replace('*', '')
         prefix = to_underscores(orig_type).lower() + '_'
-        if not func.symbol.startswith(prefix):
-            return False
+        if not is_method:
+            # Interfaces can't have constructors, punt to global scope
+            # Constructors must have _new
+            new_idx = func.symbol.find('_new')
+            if (isinstance(klass, GLibInterface) or
+                new_idx < 0):
+                return None
+            # Just strip everything before _new
+            prefix = func.symbol[:new_idx+1]
+            # TODO - check that the return type is a subclass of the
+            # class from the prefix
+        else:
+            # Look at the original C type (before namespace stripping), without
+            # pointers: GtkButton -> gtk_button_, so we can figure out the
+            # method name
+            if not func.symbol.startswith(prefix):
+                return None
 
+        self._remove_attribute(func.name)
         # Strip namespace and object prefix: gtk_window_new -> new
         func.name = func.symbol[len(prefix):]
         if is_method:
             klass.methods.append(func)
         else:
             klass.constructors.append(func)
-        return True
+        return func
 
     def _parse_struct(self, struct):
         # This is a hack, but GObject is a rather fundamental piece so.
@@ -496,7 +508,10 @@
         return ptype
 
     def _resolve_node(self, node):
-        if isinstance(node, (Callback, Function)):
+        if isinstance(node, Function):
+            self._resolve_function_toplevel(node)
+
+        elif isinstance(node, Callback):
             self._resolve_function(node)
         elif isinstance(node, GLibObject):
             self._resolve_glib_object(node)
@@ -511,6 +526,15 @@
         elif isinstance(node, Alias):
             self._resolve_alias(node)
 
+    def _resolve_function_toplevel(self, func):
+        newfunc = self._parse_constructor(func)
+        if not newfunc:
+            newfunc = self._parse_method(func)
+            if not newfunc:
+                self._resolve_function(func)
+                return
+        self._resolve_function(newfunc)
+
     def _resolve_struct(self, node):
         for field in node.fields:
             self._resolve_field(field)



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