From b7804cc7114657f367f6371ddfe9805dad8c67ff Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 2 Jun 2010 19:36:59 +0200 Subject: 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 743b94df..0ed461ba 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. --> + + + + + @@ -1830,6 +1835,57 @@ and/or use gtk-doc annotations. --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gir/gimarshallingtests.c b/gir/gimarshallingtests.c index 0888197d..ee6d91f3 100644 --- a/gir/gimarshallingtests.c +++ b/gir/gimarshallingtests.c @@ -1580,6 +1580,62 @@ g_i_marshalling_tests_garray_utf8_full_inout (GArray **array_) g_array_prepend_val (*array_, val); } +/** + * 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 deb33e50..1ad5dd7e 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 7a5e7011..263665ce 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 5861c167..678482c5 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 85237cd3..d632174c 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 ca43eb09..2e45b134 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) -- cgit v1.2.1