[gobject-introspection] Fix marshalling of GStrv.



commit b7804cc7114657f367f6371ddfe9805dad8c67ff
Author: Tomeu Vizoso <tomeu vizoso collabora co uk>
Date:   Wed Jun 2 19:36:59 2010 +0200

    Fix marshalling of GStrv.
    
    * gir/gimarshallingtests.[hc]: Add a test for GStrv in function args and
    as struct fields.
    
    * girepository/giroffsets.c: Correctly compute the size of structs with
      array fields
    
    * girepository/girparser.c: Set is_pointer to FALSE for arrays with
      fixed size that are inside structs.
    
    * giscanner/glibtransformer.py: Special case GStrv as arrays of utf8.
    
    * giscanner/annotationparser.py: Make full transfer the default for
    arrays of char* returned by functions.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=620170

 gir/GIMarshallingTests-1.0-expected.gir |   56 ++++++++++++++++++++++++++++
 gir/gimarshallingtests.c                |   61 +++++++++++++++++++++++++++++++
 gir/gimarshallingtests.h                |    8 ++++
 girepository/giroffsets.c               |   10 +++---
 girepository/girparser.c                |    3 ++
 giscanner/annotationparser.py           |    6 +++-
 giscanner/glibtransformer.py            |    5 ++-
 7 files changed, 142 insertions(+), 7 deletions(-)
---
diff --git a/gir/GIMarshallingTests-1.0-expected.gir b/gir/GIMarshallingTests-1.0-expected.gir
index 743b94d..0ed461b 100644
--- a/gir/GIMarshallingTests-1.0-expected.gir
+++ b/gir/GIMarshallingTests-1.0-expected.gir
@@ -20,6 +20,11 @@ and/or use gtk-doc annotations.  -->
       <field name="long_" writable="1">
         <type name="long" c:type="glong"/>
       </field>
+      <field name="g_strv" writable="1">
+        <array c:type="GStrv">
+          <type name="utf8"/>
+        </array>
+      </field>
       <constructor name="new"
                    c:identifier="g_i_marshalling_tests_boxed_struct_new">
         <return-value transfer-ownership="full">
@@ -1830,6 +1835,57 @@ and/or use gtk-doc annotations.  -->
         </type>
       </return-value>
     </function>
+    <function name="gstrv_in" c:identifier="g_i_marshalling_tests_gstrv_in">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="g_strv" transfer-ownership="none">
+          <array c:type="GStrv">
+            <type name="utf8"/>
+          </array>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="gstrv_inout"
+              c:identifier="g_i_marshalling_tests_gstrv_inout">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="g_strv"
+                   direction="inout"
+                   caller-allocates="0"
+                   transfer-ownership="none">
+          <array c:type="GStrv*">
+            <type name="utf8"/>
+          </array>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="gstrv_out" c:identifier="g_i_marshalling_tests_gstrv_out">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="g_strv"
+                   direction="out"
+                   caller-allocates="1"
+                   transfer-ownership="none">
+          <array c:type="GStrv*">
+            <type name="utf8"/>
+          </array>
+        </parameter>
+      </parameters>
+    </function>
+    <function name="gstrv_return"
+              c:identifier="g_i_marshalling_tests_gstrv_return">
+      <return-value transfer-ownership="full">
+        <array c:type="GStrv">
+          <type name="utf8"/>
+        </array>
+      </return-value>
+    </function>
     <function name="gtype_in" c:identifier="g_i_marshalling_tests_gtype_in">
       <return-value transfer-ownership="none">
         <type name="none" c:type="void"/>
diff --git a/gir/gimarshallingtests.c b/gir/gimarshallingtests.c
index 0888197..ee6d91f 100644
--- a/gir/gimarshallingtests.c
+++ b/gir/gimarshallingtests.c
@@ -1581,6 +1581,62 @@ g_i_marshalling_tests_garray_utf8_full_inout (GArray **array_)
 }
 
 /**
+ * g_i_marshalling_tests_gstrv_return:
+ * Returns:
+ */
+GStrv
+g_i_marshalling_tests_gstrv_return (void)
+{
+    GStrv values = g_new0 (gchar*, 4);
+    values[0] = g_strdup ("0");
+    values[1] = g_strdup ("1");
+    values[2] = g_strdup ("2");
+    values[3] = NULL;
+    return values;
+}
+
+/**
+ * g_i_marshalling_tests_gstrv_in:
+ * @g_strv:
+ */
+void
+g_i_marshalling_tests_gstrv_in (GStrv g_strv)
+{
+    g_assert(g_strv_length(g_strv) == 3);
+    g_assert(strcmp(g_strv[0], "0") == 0);
+    g_assert(strcmp(g_strv[1], "1") == 0);
+    g_assert(strcmp(g_strv[2], "2") == 0);
+}
+
+/**
+ * g_i_marshalling_tests_gstrv_out:
+ * @g_strv: (out) (transfer none):
+ */
+void
+g_i_marshalling_tests_gstrv_out (GStrv *g_strv)
+{
+    static gchar *values[] = {"0", "1", "2", NULL};
+    *g_strv = values;
+}
+
+/**
+ * g_i_marshalling_tests_gstrv_inout:
+ * @g_strv: (inout) (transfer none):
+ */
+void
+g_i_marshalling_tests_gstrv_inout (GStrv *g_strv)
+{
+    static gchar *values[] = {"-1", "0", "1", "2", NULL};
+
+    g_assert(g_strv_length(*g_strv) == 3);
+    g_assert(strcmp((*g_strv)[0], "0") == 0);
+    g_assert(strcmp((*g_strv)[1], "1") == 0);
+    g_assert(strcmp((*g_strv)[2], "2") == 0);
+
+    *g_strv = values;
+}
+
+/**
  * g_i_marshalling_tests_glist_int_none_return:
  * Returns: (element-type gint) (transfer none):
  */
@@ -2735,6 +2791,11 @@ g_i_marshalling_tests__boxed_struct_return (void)
         struct_ = g_new(GIMarshallingTestsBoxedStruct, 1);
 
         struct_->long_ = 42;
+        struct_->g_strv = g_new0(gchar*, 4);
+        struct_->g_strv[0] = g_strdup("0");
+        struct_->g_strv[1] = g_strdup("1");
+        struct_->g_strv[2] = g_strdup("2");
+        struct_->g_strv[3] = NULL;
     }
 
     return struct_;
diff --git a/gir/gimarshallingtests.h b/gir/gimarshallingtests.h
index deb33e5..1ad5dd7 100644
--- a/gir/gimarshallingtests.h
+++ b/gir/gimarshallingtests.h
@@ -316,6 +316,13 @@ void g_i_marshalling_tests_garray_utf8_none_inout (GArray **array_);
 void g_i_marshalling_tests_garray_utf8_container_inout (GArray **array_);
 void g_i_marshalling_tests_garray_utf8_full_inout (GArray **array_);
 
+/* GStrv */
+
+GStrv g_i_marshalling_tests_gstrv_return (void);
+void g_i_marshalling_tests_gstrv_in (GStrv g_strv);
+void g_i_marshalling_tests_gstrv_out (GStrv *g_strv);
+void g_i_marshalling_tests_gstrv_inout (GStrv *g_strv);
+
 /* GList */
 
 GList *g_i_marshalling_tests_glist_int_none_return (void);
@@ -505,6 +512,7 @@ void g_i_marshalling_tests__pointer_struct_inout (GIMarshallingTestsPointerStruc
 
 typedef struct {
     glong long_;
+    GStrv g_strv;
 } GIMarshallingTestsBoxedStruct;
 
 GType g_i_marshalling_tests_boxed_struct_get_type (void) G_GNUC_CONST;
diff --git a/girepository/giroffsets.c b/girepository/giroffsets.c
index 7a5e701..263665c 100644
--- a/girepository/giroffsets.c
+++ b/girepository/giroffsets.c
@@ -232,7 +232,11 @@ get_type_size_alignment (GIrNodeType *type,
 {
   ffi_type *type_ffi;
 
-  if (type->tag == GI_TYPE_TAG_ARRAY)
+  if (type->is_pointer)
+    {
+      type_ffi = &ffi_type_pointer;
+    }
+  else if (type->tag == GI_TYPE_TAG_ARRAY)
     {
       gint elt_size, elt_alignment;
 
@@ -250,10 +254,6 @@ get_type_size_alignment (GIrNodeType *type,
 
       return TRUE;
     }
-  else if (type->is_pointer)
-    {
-      type_ffi = &ffi_type_pointer;
-    }
   else
     {
       if (type->tag == GI_TYPE_TAG_INTERFACE)
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 5861c16..678482c 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1745,6 +1745,9 @@ start_type (GMarkupParseContext *context,
           else
             /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */
             typenode->zero_terminated = !(typenode->has_length || typenode->has_size);
+
+          if (typenode->has_size && ctx->current_typed->type == G_IR_NODE_FIELD)
+            typenode->is_pointer = FALSE;
         } else {
           typenode->zero_terminated = FALSE;
           typenode->has_length = FALSE;
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 85237cd..d632174 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -934,7 +934,11 @@ class AnnotationApplier(object):
             else:
                 return PARAM_TRANSFER_NONE
         elif isinstance(node, Return):
-            if (node.type.canonical in BASIC_GIR_TYPES or
+            if (isinstance(node.type, Array) and
+                    node.type.element_type is not None and
+                    node.type.element_type.name == 'utf8'):
+                return PARAM_TRANSFER_FULL
+            elif (node.type.canonical in BASIC_GIR_TYPES or
                 (node.type.canonical in [TYPE_NONE, TYPE_ANY] and
                  node.type.is_const)):
                 return PARAM_TRANSFER_NONE
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index ca43eb0..2e45b13 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -28,7 +28,7 @@ import subprocess
 from .ast import (Alias, Bitfield, Callback, Constant, Enum, Function, Member,
                   Namespace, Parameter, Property, Record, Return, Type, Union,
                   Field, VFunction, type_name_from_ctype,
-                  default_array_types, TYPE_UINT8, PARAM_TRANSFER_FULL)
+                  default_array_types, TYPE_UINT8, PARAM_TRANSFER_FULL, Array)
 from .transformer import Names
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
                       GLibInterface, GLibObject, GLibSignal, GLibBoxedStruct,
@@ -845,6 +845,9 @@ class GLibTransformer(object):
         # Workaround glib bug #548689, to be included in 2.18.0
         if ptype.name == "GParam":
             ptype.name = "GObject.ParamSpec"
+        elif ptype.name == "GObject.Strv":
+            return Array(None, ptype.ctype, Type('utf8'))
+
         return self._transformer.resolve_param_type_full(ptype,
                                                          self._names,
                                                          **kwargs)



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