[gobject-introspection] Forbid GPtrArrays holding non-pointer types



commit 8a4e168dec871fca394f1bc24f80f9a6abb8ceec
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Jul 2 15:31:38 2011 +0200

    Forbid GPtrArrays holding non-pointer types
    
    It should be safe for bindings to assume that GPtrArrays hold only
    pointers (or values as big as it), so there is no need to go through
    hoops for converting smaller integers when marshalling.
    Libraries that need arrays of integers should use GArray.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=652753

 giscanner/ast.py             |    4 ++++
 giscanner/maintransformer.py |   14 ++++++++++++++
 tests/gimarshallingtests.c   |   33 ---------------------------------
 tests/gimarshallingtests.h   |    2 --
 4 files changed, 18 insertions(+), 35 deletions(-)
---
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 373daa9..d2975af 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -222,6 +222,10 @@ GIR_TYPES = [TYPE_NONE, TYPE_ANY]
 GIR_TYPES.extend(BASIC_GIR_TYPES)
 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME, TYPE_VALIST])
 
+# These are the only basic types that are guaranteed to
+# be as big as a pointer (and thus are allowed in GPtrArray)
+POINTER_TYPES = [TYPE_ANY, TYPE_INTPTR, TYPE_UINTPTR]
+
 INTROSPECTABLE_BASIC = list(GIR_TYPES)
 for v in [TYPE_NONE, TYPE_ANY,
           TYPE_LONG_LONG, TYPE_LONG_ULONG,
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 7900419..c89424f 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -318,6 +318,18 @@ usage is void (*_gtk_reserved1)(void);"""
 
         return block.position
 
+    def _check_array_element_type(self, array, options):
+        # GPtrArrays are allowed to contain non basic types
+        # (except enums and flags) or basic types that are
+        # as big as a gpointer
+        if array.array_type == ast.Array.GLIB_PTRARRAY and \
+           ((array.element_type in ast.BASIC_GIR_TYPES \
+             and not array.element_type in ast.POINTER_TYPES) or \
+            isinstance(array.element_type, ast.Enum) or \
+            isinstance(array.element_type, ast.Bitfield)):
+            message.warn("invalid (element-type) for a GPtrArray, "
+                        "must be a pointer", options.position)
+
     def _apply_annotations_array(self, parent, node, options):
         array_opt = options.get(OPT_ARRAY)
         if array_opt:
@@ -368,6 +380,7 @@ usage is void (*_gtk_reserved1)(void);"""
             except ValueError:
                 # Already warned in annotationparser.py
                 return
+        self._check_array_element_type(container_type, options)
         node.type = container_type
 
     def _apply_annotations_element_type(self, parent, node, options):
@@ -409,6 +422,7 @@ usage is void (*_gtk_reserved1)(void);"""
                 return
             node.type.element_type = self._resolve(element_type_opt.one(),
                                                    node.type, node, parent)
+            self._check_array_element_type(node.type, options)
         else:
             message.warn_node(parent,
                 "Unknown container %r for element-type annotation" % (node.type, ))
diff --git a/tests/gimarshallingtests.c b/tests/gimarshallingtests.c
index 10330b9..279831b 100644
--- a/tests/gimarshallingtests.c
+++ b/tests/gimarshallingtests.c
@@ -1782,25 +1782,6 @@ gi_marshalling_tests_garray_utf8_full_inout (GArray **array_)
 }
 
 /**
- * gi_marshalling_tests_gptrarray_int_none_return:
- * Returns: (element-type gint) (transfer none):
- */
-GPtrArray *
-gi_marshalling_tests_gptrarray_int_none_return (void)
-{
-    static GPtrArray *parray = NULL;
-    gint i;
-
-    if (parray == NULL) {
-        parray = g_ptr_array_new ();
-        for (i = 0; i < 4; i++) {
-            g_ptr_array_add (parray, GINT_TO_POINTER(i));
-        }
-    }
-
-    return parray;
-}
-/**
  * gi_marshalling_tests_gptrarray_utf8_none_return:
  * Returns: (element-type utf8) (transfer none):
  */
@@ -1859,20 +1840,6 @@ gi_marshalling_tests_gptrarray_utf8_full_return (void)
 }
 
 /**
- * gi_marshalling_tests_gptrarray_int_none_in:
- * @parray_: (element-type gint) (transfer none):
- */
-void
-gi_marshalling_tests_gptrarray_int_none_in (GPtrArray *parray_)
-{
-    g_assert (parray_->len == 4);
-    g_assert (g_ptr_array_index (parray_, 0) == GINT_TO_POINTER(0));
-    g_assert (g_ptr_array_index (parray_, 1) == GINT_TO_POINTER(1));
-    g_assert (g_ptr_array_index (parray_, 2) == GINT_TO_POINTER(2));
-    g_assert (g_ptr_array_index (parray_, 3) == GINT_TO_POINTER(3));
-}
-
-/**
  * gi_marshalling_tests_gptrarray_utf8_none_in:
  * @parray_: (element-type utf8) (transfer none):
  */
diff --git a/tests/gimarshallingtests.h b/tests/gimarshallingtests.h
index 63a4a6a..7d44d39 100644
--- a/tests/gimarshallingtests.h
+++ b/tests/gimarshallingtests.h
@@ -423,12 +423,10 @@ void gi_marshalling_tests_garray_utf8_container_inout (GArray **array_);
 void gi_marshalling_tests_garray_utf8_full_inout (GArray **array_);
 
 /* GPtrArray */
-GPtrArray *gi_marshalling_tests_gptrarray_int_none_return (void);
 GPtrArray *gi_marshalling_tests_gptrarray_utf8_none_return (void);
 GPtrArray *gi_marshalling_tests_gptrarray_utf8_container_return (void);
 GPtrArray *gi_marshalling_tests_gptrarray_utf8_full_return (void);
 
-void gi_marshalling_tests_gptrarray_int_none_in (GPtrArray *parray_);
 void gi_marshalling_tests_gptrarray_utf8_none_in (GPtrArray *parray_);
 
 void gi_marshalling_tests_gptrarray_utf8_none_out (GPtrArray **parray_);



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