summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagna@src.gnome.org>2011-07-02 15:31:38 +0200
committerGiovanni Campagna <gcampagna@src.gnome.org>2011-08-18 15:15:04 +0200
commit8a4e168dec871fca394f1bc24f80f9a6abb8ceec (patch)
tree58e1a594ef66fb78bf76814aabbfe8dd0cafd626
parente9b0c8013dd15d643e46dd6e763585d5fe1b5b45 (diff)
downloadgobject-introspection-8a4e168dec871fca394f1bc24f80f9a6abb8ceec.tar.gz
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
-rw-r--r--giscanner/ast.py4
-rw-r--r--giscanner/maintransformer.py14
-rw-r--r--tests/gimarshallingtests.c33
-rw-r--r--tests/gimarshallingtests.h2
4 files changed, 18 insertions, 35 deletions
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 373daa9f..d2975afc 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 79004199..c89424fd 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 10330b99..279831be 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 63a4a6a3..7d44d393 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_);