diff options
-rw-r--r-- | codegen/valaccodememberaccessmodule.vala | 12 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/objects/property-strv-noaccessor.c-expected | 363 | ||||
-rw-r--r-- | tests/objects/property-strv-noaccessor.vala | 15 |
4 files changed, 391 insertions, 0 deletions
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index 6f01e8a0b..774377752 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -348,7 +348,19 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp)); ccall.add_argument (new CCodeConstant ("NULL")); ccode.add_expression (ccall); + set_cvalue (expr, ctemp); + + if (get_ccode_array_null_terminated (prop)) { + requires_array_length = true; + var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length")); + len_call.add_argument (ctemp); + + var glib_value = (GLibValue) expr.target_value; + glib_value.array_length_cvalues = null; + glib_value.append_array_length_cvalue (len_call); + glib_value.lvalue = false; + } } if (prop.get_accessor.value_type is GenericType) { diff --git a/tests/Makefile.am b/tests/Makefile.am index cb07869a2..0d0fca034 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -563,6 +563,7 @@ TESTS = \ objects/property-simple-type-struct-nullable.vala \ objects/property-static.vala \ objects/property-struct-no-gtype.vala \ + objects/property-strv-noaccessor.vala \ objects/property-write-only-member-read.test \ objects/regex.vala \ objects/sealed-abstract-class.test \ diff --git a/tests/objects/property-strv-noaccessor.c-expected b/tests/objects/property-strv-noaccessor.c-expected new file mode 100644 index 000000000..7443e002e --- /dev/null +++ b/tests/objects/property-strv-noaccessor.c-expected @@ -0,0 +1,363 @@ +/* objects_property_strv_noaccessor.c generated by valac, the Vala compiler + * generated from objects_property_strv_noaccessor.vala, do not modify */ + +#include <glib-object.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> + +#if !defined(VALA_EXTERN) +#if defined(_MSC_VER) +#define VALA_EXTERN __declspec(dllexport) extern +#elif __GNUC__ >= 4 +#define VALA_EXTERN __attribute__((visibility("default"))) extern +#else +#define VALA_EXTERN extern +#endif +#endif + +#define TYPE_FOO (foo_get_type ()) +#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_FOO, Foo)) +#define FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_FOO, FooClass)) +#define IS_FOO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_FOO)) +#define IS_FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_FOO)) +#define FOO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_FOO, FooClass)) + +typedef struct _Foo Foo; +typedef struct _FooClass FooClass; +typedef struct _FooPrivate FooPrivate; +enum { + FOO_0_PROPERTY, + FOO_BAR_PROPERTY, + FOO_NUM_PROPERTIES +}; +static GParamSpec* foo_properties[FOO_NUM_PROPERTIES]; +#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) +#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); +#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; } +#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; } +#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); + +struct _Foo { + GObject parent_instance; + FooPrivate * priv; +}; + +struct _FooClass { + GObjectClass parent_class; +}; + +struct _FooPrivate { + gchar** _bar; + gint _bar_length1; + gint __bar_size_; +}; + +static gint Foo_private_offset; +static gpointer foo_parent_class = NULL; + +VALA_EXTERN GType foo_get_type (void) G_GNUC_CONST ; +G_DEFINE_AUTOPTR_CLEANUP_FUNC (Foo, g_object_unref) +VALA_EXTERN Foo* foo_new (void); +VALA_EXTERN Foo* foo_construct (GType object_type); +VALA_EXTERN gchar** foo_get_bar (Foo* self); +static gchar** _vala_array_dup1 (gchar** self, + gssize length); +VALA_EXTERN void foo_set_bar (Foo* self, + gchar** value); +static gchar** _vala_array_dup2 (gchar** self, + gssize length); +static void foo_finalize (GObject * obj); +static GType foo_get_type_once (void); +static void _vala_foo_get_property (GObject * object, + guint property_id, + GValue * value, + GParamSpec * pspec); +static void _vala_foo_set_property (GObject * object, + guint property_id, + const GValue * value, + GParamSpec * pspec); +static void _vala_main (void); +static void _vala_array_destroy (gpointer array, + gssize array_length, + GDestroyNotify destroy_func); +static void _vala_array_free (gpointer array, + gssize array_length, + GDestroyNotify destroy_func); +static gssize _vala_array_length (gpointer array); + +static inline gpointer +foo_get_instance_private (Foo* self) +{ + return G_STRUCT_MEMBER_P (self, Foo_private_offset); +} + +Foo* +foo_construct (GType object_type) +{ + Foo * self = NULL; + self = (Foo*) g_object_new (object_type, NULL); + return self; +} + +Foo* +foo_new (void) +{ + return foo_construct (TYPE_FOO); +} + +static gchar** +_vala_array_dup1 (gchar** self, + gssize length) +{ + if (length >= 0) { + gchar** result; + gssize i; + result = g_new0 (gchar*, length + 1); + for (i = 0; i < length; i++) { + gchar* _tmp0_; + _tmp0_ = g_strdup (self[i]); + result[i] = _tmp0_; + } + return result; + } + return NULL; +} + +gchar** +foo_get_bar (Foo* self) +{ + gchar** result; + gchar** _tmp0_; + gint _tmp0__length1; + gchar** _tmp1_; + gint _tmp1__length1; + g_return_val_if_fail (IS_FOO (self), NULL); + _tmp0_ = self->priv->_bar; + _tmp0__length1 = self->priv->_bar_length1; + _tmp1_ = (_tmp0_ != NULL) ? _vala_array_dup1 (_tmp0_, _tmp0__length1) : _tmp0_; + _tmp1__length1 = _tmp0__length1; + result = _tmp1_; + return result; +} + +static gchar** +_vala_array_dup2 (gchar** self, + gssize length) +{ + if (length >= 0) { + gchar** result; + gssize i; + result = g_new0 (gchar*, length + 1); + for (i = 0; i < length; i++) { + gchar* _tmp0_; + _tmp0_ = g_strdup (self[i]); + result[i] = _tmp0_; + } + return result; + } + return NULL; +} + +void +foo_set_bar (Foo* self, + gchar** value) +{ + gchar** old_value; + g_return_if_fail (IS_FOO (self)); + old_value = foo_get_bar (self); + if (old_value != value) { + gchar** _tmp0_; + gint _tmp0__length1; + _tmp0_ = (value != NULL) ? _vala_array_dup2 (value, _vala_array_length (value)) : value; + _tmp0__length1 = _vala_array_length (value); + self->priv->_bar = (_vala_array_free (self->priv->_bar, self->priv->_bar_length1, (GDestroyNotify) g_free), NULL); + self->priv->_bar = _tmp0_; + self->priv->_bar_length1 = _tmp0__length1; + self->priv->__bar_size_ = self->priv->_bar_length1; + g_object_notify_by_pspec ((GObject *) self, foo_properties[FOO_BAR_PROPERTY]); + } + old_value = (g_free (old_value), NULL); +} + +static void +foo_class_init (FooClass * klass, + gpointer klass_data) +{ + foo_parent_class = g_type_class_peek_parent (klass); + g_type_class_adjust_private_offset (klass, &Foo_private_offset); + G_OBJECT_CLASS (klass)->get_property = _vala_foo_get_property; + G_OBJECT_CLASS (klass)->set_property = _vala_foo_set_property; + G_OBJECT_CLASS (klass)->finalize = foo_finalize; + g_object_class_install_property (G_OBJECT_CLASS (klass), FOO_BAR_PROPERTY, foo_properties[FOO_BAR_PROPERTY] = g_param_spec_boxed ("bar", "bar", "bar", G_TYPE_STRV, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE)); +} + +static void +foo_instance_init (Foo * self, + gpointer klass) +{ + self->priv = foo_get_instance_private (self); +} + +static void +foo_finalize (GObject * obj) +{ + Foo * self; + self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_FOO, Foo); + self->priv->_bar = (_vala_array_free (self->priv->_bar, self->priv->_bar_length1, (GDestroyNotify) g_free), NULL); + G_OBJECT_CLASS (foo_parent_class)->finalize (obj); +} + +static GType +foo_get_type_once (void) +{ + static const GTypeInfo g_define_type_info = { sizeof (FooClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) foo_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Foo), 0, (GInstanceInitFunc) foo_instance_init, NULL }; + GType foo_type_id; + foo_type_id = g_type_register_static (G_TYPE_OBJECT, "Foo", &g_define_type_info, 0); + Foo_private_offset = g_type_add_instance_private (foo_type_id, sizeof (FooPrivate)); + return foo_type_id; +} + +GType +foo_get_type (void) +{ + static volatile gsize foo_type_id__once = 0; + if (g_once_init_enter (&foo_type_id__once)) { + GType foo_type_id; + foo_type_id = foo_get_type_once (); + g_once_init_leave (&foo_type_id__once, foo_type_id); + } + return foo_type_id__once; +} + +static void +_vala_foo_get_property (GObject * object, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + Foo * self; + self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_FOO, Foo); + switch (property_id) { + case FOO_BAR_PROPERTY: + g_value_take_boxed (value, foo_get_bar (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +_vala_foo_set_property (GObject * object, + guint property_id, + const GValue * value, + GParamSpec * pspec) +{ + Foo * self; + self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_FOO, Foo); + switch (property_id) { + case FOO_BAR_PROPERTY: + { + gpointer boxed; + boxed = g_value_get_boxed (value); + foo_set_bar (self, boxed); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +_vala_main (void) +{ + gchar** bar = NULL; + gchar* _tmp0_; + gchar* _tmp1_; + gchar* _tmp2_; + gchar** _tmp3_; + gint bar_length1; + gint _bar_size_; + Foo* foo = NULL; + Foo* _tmp4_; + gchar** manam = NULL; + gchar** _tmp5_; + gchar** _tmp6_; + gint _tmp6__length1; + gint manam_length1; + gint _manam_size_; + const gchar* _tmp7_; + _tmp0_ = g_strdup ("foo"); + _tmp1_ = g_strdup ("bar"); + _tmp2_ = g_strdup ("manam"); + _tmp3_ = g_new0 (gchar*, 3 + 1); + _tmp3_[0] = _tmp0_; + _tmp3_[1] = _tmp1_; + _tmp3_[2] = _tmp2_; + bar = _tmp3_; + bar_length1 = 3; + _bar_size_ = bar_length1; + _tmp4_ = foo_new (); + foo = _tmp4_; + g_object_set (foo, "bar", bar, NULL); + g_object_get (foo, "bar", &_tmp5_, NULL); + _tmp6_ = _tmp5_; + _tmp6__length1 = _vala_array_length (_tmp5_); + manam = _tmp6_; + manam_length1 = _tmp6__length1; + _manam_size_ = manam_length1; + _vala_assert (manam_length1 == 3, "manam.length == 3"); + _tmp7_ = manam[2]; + _vala_assert (g_strcmp0 (_tmp7_, "manam") == 0, "manam[2] == \"manam\""); + manam = (_vala_array_free (manam, manam_length1, (GDestroyNotify) g_free), NULL); + _g_object_unref0 (foo); + bar = (_vala_array_free (bar, bar_length1, (GDestroyNotify) g_free), NULL); +} + +int +main (int argc, + char ** argv) +{ + _vala_main (); + return 0; +} + +static void +_vala_array_destroy (gpointer array, + gssize array_length, + GDestroyNotify destroy_func) +{ + if ((array != NULL) && (destroy_func != NULL)) { + gssize i; + for (i = 0; i < array_length; i = i + 1) { + if (((gpointer*) array)[i] != NULL) { + destroy_func (((gpointer*) array)[i]); + } + } + } +} + +static void +_vala_array_free (gpointer array, + gssize array_length, + GDestroyNotify destroy_func) +{ + _vala_array_destroy (array, array_length, destroy_func); + g_free (array); +} + +static gssize +_vala_array_length (gpointer array) +{ + gssize length; + length = 0; + if (array) { + while (((gpointer*) array)[length]) { + length++; + } + } + return length; +} + diff --git a/tests/objects/property-strv-noaccessor.vala b/tests/objects/property-strv-noaccessor.vala new file mode 100644 index 000000000..6fa394abd --- /dev/null +++ b/tests/objects/property-strv-noaccessor.vala @@ -0,0 +1,15 @@ +class Foo : Object { + [CCode (array_length = false, array_null_terminated = true)] + [NoAccessorMethod] + public string[] bar { owned get; set; } +} + +void main () { + string[] bar = { "foo", "bar", "manam" }; + var foo = new Foo (); + foo.bar = bar; + + var manam = foo.bar; + assert (manam.length == 3); + assert (manam[2] == "manam"); +} |