Add fundamental type and pspec for GVariant

Make G_TYPE_VARIANT a fundamental type instead of boxed, and add
g_variant_{set,get,dup}_variant.

Add GParamSpecVariant.

Bug #610863.
This commit is contained in:
Christian Persch 2010-06-17 18:03:51 +02:00
parent f2ae621777
commit 4708b8ecc3
14 changed files with 461 additions and 35 deletions

4
NEWS
View File

@ -28,6 +28,10 @@ and GApplication. Users of these APIs will need to be adapted.
* GObject
- Introduce g_object_notify_by_pspec
- Add GBinding
- The GVariant gtype G_TYPE_VARIANT was changed from boxed
to fundamental. We believe there were no existing users
of the boxed type, so this should not cause any applications
to break.
* Test framework
- Add package and version to the test report XML

View File

@ -147,6 +147,7 @@ G_TYPE_BOXED
G_TYPE_PARAM
G_TYPE_OBJECT
G_TYPE_GTYPE
G_TYPE_VARIANT
<SUBSECTION>
G_TYPE_RESERVED_GLIB_FIRST
@ -351,7 +352,6 @@ G_TYPE_REGEX
G_TYPE_ARRAY
G_TYPE_BYTE_ARRAY
G_TYPE_PTR_ARRAY
G_TYPE_VARIANT
G_TYPE_VARIANT_TYPE
G_TYPE_ERROR
GStrv
@ -698,6 +698,17 @@ g_param_spec_gtype
g_value_get_gtype
g_value_set_gtype
<SUBSECTION GVariant>
G_IS_PARAM_SPEC_VARIANT
G_PARAM_SPEC_VARIANT
G_VALUE_HOLDS_VARIANT
G_TYPE_PARAM_VARIANT
GParamSpecVariant
g_param_spec_variant
g_value_get_variant
g_value_dup_variant
g_value_set_variant
<SUBSECTION Private>
g_value_set_instance
g_param_spec_types

View File

@ -286,17 +286,16 @@ g_variant_type_get_gtype (void)
return type_id;
}
/**
* g_variant_get_gtype:
*
* Since: 2.24
* Deprecated: 2.26
*/
GType
g_variant_get_gtype (void)
{
static GType type_id = 0;
if (!type_id)
type_id = g_boxed_type_register_static (g_intern_static_string ("GVariant"),
(GBoxedCopyFunc) g_variant_ref,
(GBoxedFreeFunc) g_variant_unref);
return type_id;
return G_TYPE_VARIANT;
}
GType

View File

@ -194,14 +194,6 @@ GType g_boxed_type_register_static (const gchar *name,
* Since: 2.24
*/
#define G_TYPE_VARIANT_TYPE (g_variant_type_get_gtype ())
/**
* G_TYPE_VARIANT:
*
* The #GType for a boxed type holding a #GVariant reference.
*
* Since: 2.24
*/
#define G_TYPE_VARIANT (g_variant_get_gtype ())
/**
* G_TYPE_ERROR:
*
@ -229,10 +221,13 @@ GType g_array_get_type (void) G_GNUC_CONST;
GType g_byte_array_get_type (void) G_GNUC_CONST;
GType g_ptr_array_get_type (void) G_GNUC_CONST;
GType g_variant_type_get_gtype(void) G_GNUC_CONST;
GType g_variant_get_gtype (void) G_GNUC_CONST;
GType g_regex_get_type (void) G_GNUC_CONST;
GType g_error_get_type (void) G_GNUC_CONST;
#ifndef G_DISABLE_DEPRECATED
GType g_variant_get_gtype (void) G_GNUC_CONST;
#endif
/**
* GStrv:
*

View File

@ -151,6 +151,7 @@ put_marshal_value_getters (void)
fputs ("#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)\n", fout);
fputs ("#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)\n", fout);
fputs ("#define g_marshal_value_peek_object(v) g_value_get_object (v)\n", fout);
fputs ("#define g_marshal_value_peek_variant(v) g_value_get_variant (v)\n", fout);
fputs ("#else /* !G_ENABLE_DEBUG */\n", fout);
fputs ("/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.\n", fout);
fputs (" * Do not access GValues directly in your code. Instead, use the\n", fout);
@ -174,6 +175,7 @@ put_marshal_value_getters (void)
fputs ("#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer\n", fout);
fputs ("#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer\n", fout);
fputs ("#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer\n", fout);
fputs ("#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer\n", fout);
fputs ("#endif /* !G_ENABLE_DEBUG */\n", fout);
fputs ("\n", fout);
}
@ -202,6 +204,7 @@ complete_in_arg (InArgument *iarg)
{ "BOXED", "BOXED", "gpointer", "g_marshal_value_peek_boxed", },
{ "POINTER", "POINTER", "gpointer", "g_marshal_value_peek_pointer", },
{ "OBJECT", "OBJECT", "gpointer", "g_marshal_value_peek_object", },
{ "VARIANT", "VARIANT", "gpointer", "g_marshal_value_peek_variant", },
/* deprecated: */
{ "NONE", "VOID", "void", NULL, },
{ "BOOL", "BOOLEAN", "gboolean", "g_marshal_value_peek_boolean", },
@ -246,6 +249,7 @@ complete_out_arg (OutArgument *oarg)
{ "BOXED", "BOXED", "gpointer", "g_value_take_boxed", },
{ "POINTER", "POINTER", "gpointer", "g_value_set_pointer", },
{ "OBJECT", "OBJECT", "GObject*", "g_value_take_object", },
{ "VARIANT", "VARIANT", "GVariant*", "g_value_take_variant", },
/* deprecated: */
{ "NONE", "VOID", "void", NULL, },
{ "BOOL", "BOOLEAN", "gboolean", "g_value_set_boolean", },

View File

@ -19,6 +19,7 @@
# BOXED for boxed (anonymous but reference counted) types (GBoxed*)
# POINTER for anonymous pointer types (gpointer)
# OBJECT for GObject or derived types (GObject*)
# VARIANT for variants (GVariant*)
# NONE deprecated alias for VOID
# BOOL deprecated alias for BOOLEAN
@ -40,6 +41,7 @@ VOID:PARAM
VOID:BOXED
VOID:POINTER
VOID:OBJECT
VOID:VARIANT
# GRuntime specific marshallers
VOID:UINT,POINTER

View File

@ -41,7 +41,6 @@ g_error_get_type G_GNUC_CONST
g_ptr_array_get_type G_GNUC_CONST
g_regex_get_type G_GNUC_CONST
g_variant_type_get_gtype G_GNUC_CONST
g_variant_get_gtype G_GNUC_CONST
g_closure_get_type G_GNUC_CONST
g_value_get_type G_GNUC_CONST
g_value_array_get_type G_GNUC_CONST
@ -52,6 +51,7 @@ g_value_get_boxed
g_value_set_static_boxed
#ifndef G_DISABLE_DEPRECATED
g_value_set_boxed_take_ownership
g_variant_get_gtype G_GNUC_CONST
#endif
#endif
#endif
@ -215,6 +215,7 @@ g_param_spec_uint64
g_param_spec_ulong
g_param_spec_unichar
g_param_spec_value_array
g_param_spec_variant
#endif
#endif
@ -294,6 +295,9 @@ g_value_take_string
g_gtype_get_type
g_value_set_gtype
g_value_get_gtype
g_value_get_variant
g_value_dup_variant
g_value_set_variant
#endif
#endif

View File

@ -1,5 +1,6 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
* Copyright (C) 2010 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -1098,13 +1099,71 @@ param_gtype_values_cmp (GParamSpec *pspec,
return p1 < p2 ? -1 : p1 > p2;
}
static void
param_variant_init (GParamSpec *pspec)
{
GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
vspec->type = NULL;
vspec->default_value = NULL;
}
static void
param_variant_finalize (GParamSpec *pspec)
{
GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT));
if (vspec->default_value)
g_variant_unref (vspec->default_value);
g_variant_type_free (vspec->type);
parent_class->finalize (pspec);
}
static void
param_variant_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value;
value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS;
}
static gboolean
param_variant_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
GVariant *variant = value->data[0].v_pointer;
if ((variant == NULL && vspec->default_value != NULL) ||
(variant != NULL && !g_variant_is_of_type (variant, vspec->type)))
{
g_param_value_set_default (pspec, value);
return TRUE;
}
return FALSE;
}
static gint
param_variant_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GVariant *v1 = value1->data[0].v_pointer;
GVariant *v2 = value2->data[0].v_pointer;
return v1 < v2 ? -1 : v2 > v1;
}
/* --- type initialization --- */
GType *g_param_spec_types = NULL;
void
g_param_spec_types_init (void)
{
const guint n_types = 22;
const guint n_types = 23;
GType type, *spec_types, *spec_types_bound;
g_param_spec_types = g_new0 (GType, n_types);
@ -1509,6 +1568,24 @@ g_param_spec_types_init (void)
g_assert (type == G_TYPE_PARAM_GTYPE);
}
/* G_TYPE_PARAM_VARIANT
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecVariant), /* instance_size */
0, /* n_preallocs */
param_variant_init, /* instance_init */
G_TYPE_VARIANT, /* value_type */
param_variant_finalize, /* finalize */
param_variant_set_default, /* value_set_default */
param_variant_validate, /* value_validate */
param_variant_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_VARIANT);
}
g_assert (spec_types == spec_types_bound);
}
@ -2393,5 +2470,53 @@ g_param_spec_override (const gchar *name,
return pspec;
}
/**
* g_param_spec_variant:
* @name: canonical name of the property specified
* @nick: nick name for the property specified
* @blurb: description of the property specified
* @type: a #GVariantType
* @default_value: (allow-none): a #GVariant of type @type to use as the
* default value, or %NULL
* @flags: flags for the property specified
*
* Creates a new #GParamSpecVariant instance specifying a #GVariant
* property.
*
* If @default_value is floating, it is consumed.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: the newly created #GParamSpec
*
* Since: 2.26
*/
GParamSpec*
g_param_spec_variant (const gchar *name,
const gchar *nick,
const gchar *blurb,
const GVariantType *type,
GVariant *default_value,
GParamFlags flags)
{
GParamSpecVariant *vspec;
g_return_val_if_fail (type != NULL, NULL);
g_return_val_if_fail (default_value == NULL ||
g_variant_is_of_type (default_value, type), NULL);
vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT,
name,
nick,
blurb,
flags);
vspec->type = g_variant_type_copy (type);
if (default_value)
vspec->default_value = g_variant_ref_sink (default_value);
return G_PARAM_SPEC (vspec);
}
#define __G_PARAMSPECS_C__
#include "gobjectaliasdef.c"

View File

@ -549,6 +549,34 @@ G_BEGIN_DECLS
*/
#define G_PARAM_SPEC_GTYPE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_GTYPE, GParamSpecGType))
/**
* G_TYPE_PARAM_VARIANT:
*
* The #GType of #GParamSpecVariant.
*
* Since: 2.26
*/
#define G_TYPE_PARAM_VARIANT (g_param_spec_types[22])
/**
* G_IS_PARAM_SPEC_VARIANT:
* @pspec: a #GParamSpec
*
* Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_VARIANT.
*
* Returns: %TRUE on success
*
* Since: 2.26
*/
#define G_IS_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_VARIANT))
/**
* G_PARAM_SPEC_VARIANT:
* @pspec: a #GParamSpec
*
* Casts a #GParamSpec into a #GParamSpecVariant.
*
* Since: 2.26
*/
#define G_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_VARIANT, GParamSpecVariant))
/* --- typedefs & structures --- */
typedef struct _GParamSpecChar GParamSpecChar;
@ -573,6 +601,7 @@ typedef struct _GParamSpecValueArray GParamSpecValueArray;
typedef struct _GParamSpecObject GParamSpecObject;
typedef struct _GParamSpecOverride GParamSpecOverride;
typedef struct _GParamSpecGType GParamSpecGType;
typedef struct _GParamSpecVariant GParamSpecVariant;
/**
* GParamSpecChar:
@ -921,6 +950,23 @@ struct _GParamSpecGType
GParamSpec parent_instance;
GType is_a_type;
};
/**
* GParamSpecVariant:
* @parent_instance: private #GParamSpec portion
* @type: a #GVariantType, or %NULL
* @default_value: a #GVariant, or %NULL
*
* A #GParamSpec derived structure that contains the meta data for #GVariant properties.
*
* Since: 2.26
*/
struct _GParamSpecVariant
{
GParamSpec parent_instance;
GVariantType *type;
GVariant *default_value;
gpointer padding[4];
};
/* --- GParamSpec prototypes --- */
GParamSpec* g_param_spec_char (const gchar *name,
@ -1051,6 +1097,12 @@ GParamSpec* g_param_spec_gtype (const gchar *name,
const gchar *blurb,
GType is_a_type,
GParamFlags flags);
GParamSpec* g_param_spec_variant (const gchar *name,
const gchar *nick,
const gchar *blurb,
const GVariantType *type,
GVariant *default_value,
GParamFlags flags);
/* --- internal --- */
/* We prefix variable declarations so they can

View File

@ -179,6 +179,17 @@ G_BEGIN_DECLS
* The fundamental type for #GObject.
*/
#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
/**
* G_TYPE_VARIANT:
*
* The fundamental type corresponding to #GVariant.
*
* Note: GLib 2.24 did include a boxed type with this name. It was replaced
* with this fundamental type in 2.26.
*
* Since: 2.26
*/
#define G_TYPE_VARIANT G_TYPE_MAKE_FUNDAMENTAL (21)
/* Reserved fundamental type numbers to create new fundamental
@ -208,7 +219,7 @@ G_BEGIN_DECLS
* First fundamental type number to create a new fundamental type id with
* G_TYPE_MAKE_FUNDAMENTAL() reserved for GLib.
*/
#define G_TYPE_RESERVED_GLIB_FIRST (21)
#define G_TYPE_RESERVED_GLIB_FIRST (22)
/**
* G_TYPE_RESERVED_GLIB_LAST:
*

View File

@ -1,5 +1,6 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
* Copyright © 2010 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -361,6 +362,63 @@ value_lcopy_pointer (const GValue *value,
return NULL;
}
static void
value_free_variant (GValue *value)
{
if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) &&
value->data[0].v_pointer)
g_variant_unref (value->data[0].v_pointer);
}
static void
value_copy_variant (const GValue *src_value,
GValue *dest_value)
{
if (src_value->data[0].v_pointer)
dest_value->data[0].v_pointer = g_variant_ref_sink (src_value->data[0].v_pointer);
else
dest_value->data[0].v_pointer = NULL;
}
static gchar*
value_collect_variant (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
if (!collect_values[0].v_pointer)
value->data[0].v_pointer = NULL;
else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
{
value->data[0].v_pointer = collect_values[0].v_pointer;
value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
}
else
value->data[0].v_pointer = g_variant_ref_sink (collect_values[0].v_pointer);
return NULL;
}
static gchar*
value_lcopy_variant (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
GVariant **variant_p = collect_values[0].v_pointer;
if (!variant_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
if (!value->data[0].v_pointer)
*variant_p = NULL;
else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
*variant_p = value->data[0].v_pointer;
else
*variant_p = g_variant_ref_sink (value->data[0].v_pointer);
return NULL;
}
/* --- type initialization --- */
void
@ -550,6 +608,24 @@ g_value_types_init (void)
type = g_type_register_fundamental (G_TYPE_POINTER, g_intern_static_string ("gpointer"), &info, &finfo, 0);
g_assert (type == G_TYPE_POINTER);
}
/* G_TYPE_VARIANT
*/
{
static const GTypeValueTable value_table = {
value_init_pointer, /* value_init */
value_free_variant, /* value_free */
value_copy_variant, /* value_copy */
value_peek_pointer0, /* value_peek_pointer */
"p", /* collect_format */
value_collect_variant, /* collect_value */
"p", /* lcopy_format */
value_lcopy_variant, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_VARIANT, g_intern_static_string ("GVariant"), &info, &finfo, 0);
g_assert (type == G_TYPE_VARIANT);
}
}
@ -1101,6 +1177,78 @@ g_value_get_gtype (const GValue *value)
return value->data[0].v_long;
}
/**
* g_value_set_variant:
* @value: a valid #GValue of %G_TYPE_VARIANT
* @variant: a #GVariant, or %NULL
*
* Set the contents of a variant #GValue to @variant.
* If the variant is floating, it is consumed.
*
* Since: 2.26
*/
void
g_value_set_variant (GValue *value,
GVariant *variant)
{
GVariant *old_variant;
g_return_if_fail (G_VALUE_HOLDS_VARIANT (value));
old_variant = value->data[0].v_pointer;
if (variant)
value->data[0].v_pointer = g_variant_ref_sink (variant);
else
value->data[0].v_pointer = NULL;
if (old_variant)
g_variant_unref (old_variant);
}
/**
* g_value_get_variant:
* @value: a valid #GValue of %G_TYPE_VARIANT
*
* Get the contents of a variant #GValue.
*
* Returns: variant contents of @value
*
* Since: 2.26
*/
GVariant*
g_value_get_variant (const GValue *value)
{
g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
return value->data[0].v_pointer;
}
/**
* g_value_get_variant:
* @value: a valid #GValue of %G_TYPE_VARIANT
*
* Get the contents of a variant #GValue, increasing its refcount.
*
* Returns: variant contents of @value, should be unrefed using
* g_variant_unref() when no longer needed
*
* Since: 2.26
*/
GVariant*
g_value_dup_variant (const GValue *value)
{
GVariant *variant;
g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
variant = value->data[0].v_pointer;
if (variant)
g_variant_ref_sink (variant);
return variant;
}
/**
* g_strdup_value_contents:
* @value: #GValue which contents are to be described.

View File

@ -163,6 +163,17 @@ G_BEGIN_DECLS
* Returns: %TRUE on success.
*/
#define G_VALUE_HOLDS_GTYPE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_GTYPE))
/**
* G_VALUE_HOLDS_VARIANT:
* @value: a valid #GValue structure
*
* Checks whether the given #GValue can hold values of type %G_TYPE_VARIANT.
*
* Returns: %TRUE on success.
*
* Since: 2.26
*/
#define G_VALUE_HOLDS_VARIANT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_VARIANT))
/* --- prototypes --- */
@ -212,6 +223,10 @@ GType g_gtype_get_type (void);
void g_value_set_gtype (GValue *value,
GType v_gtype);
GType g_value_get_gtype (const GValue *value);
void g_value_set_variant (GValue *value,
GVariant *variant);
GVariant* g_value_get_variant (const GValue *value);
GVariant* g_value_dup_variant (const GValue *value);
/* Convenience for registering new pointer types */

View File

@ -219,6 +219,15 @@ test_collection (void)
error = collect (&value, G_TYPE_BOXED);
g_assert (error == NULL);
g_assert (g_value_get_gtype (&value) == G_TYPE_BOXED);
g_value_unset (&value);
g_value_init (&value, G_TYPE_VARIANT);
error = collect (&value, g_variant_new_uint32 (42));
g_assert (error == NULL);
g_assert (g_variant_is_of_type (g_value_get_variant (&value), G_VARIANT_TYPE ("u")));
g_assert_cmpuint (g_variant_get_uint32 (g_value_get_variant (&value)), ==, 42);
g_value_unset (&value);
}
static void
@ -357,18 +366,33 @@ test_copying (void)
g_assert (error == NULL);
g_assert (c == G_TYPE_BOXED);
}
{
GVariant *c = NULL;
g_value_unset (&value);
g_value_init (&value, G_TYPE_VARIANT);
g_value_set_variant (&value, g_variant_new_uint32 (42));
error = lcopy (&value, &c);
g_assert (error == NULL);
g_assert (c != NULL);
g_assert (g_variant_is_of_type (c, G_VARIANT_TYPE ("u")));
g_assert_cmpuint (g_variant_get_uint32 (c), ==, 42);
g_variant_unref (c);
}
}
int
main (int argc, char *argv[])
{
g_type_init ();
test_enum_transformation ();
test_gtype_value ();
test_collection ();
test_copying ();
g_test_init (&argc, &argv, NULL);
g_type_init ();
return 0;
g_test_add_func ("/gvalue/enum-transformation", test_enum_transformation);
g_test_add_func ("/gvalue/gtype", test_gtype_value);
g_test_add_func ("/gvalue/collection", test_collection);
g_test_add_func ("/gvalue/copying", test_copying);
return g_test_run ();
}

View File

@ -206,15 +206,47 @@ test_param_spec_gtype (void)
g_assert (!modified && g_value_get_gtype (&value) == G_TYPE_PARAM_INT);
}
static void
test_param_spec_variant (void)
{
GParamSpec *pspec;
GValue value = { 0, };
gboolean modified;
pspec = g_param_spec_variant ("variant", "nick", "blurb",
G_VARIANT_TYPE ("i"),
g_variant_new_int32 (42),
G_PARAM_READWRITE);
g_value_init (&value, G_TYPE_VARIANT);
g_value_set_variant (&value, g_variant_new_int32 (42));
g_assert (g_param_value_defaults (pspec, &value));
modified = g_param_value_validate (pspec, &value);
g_assert (!modified);
g_value_reset (&value);
g_value_set_variant (&value, g_variant_new_uint32 (41));
modified = g_param_value_validate (pspec, &value);
g_assert (modified);
g_assert_cmpint (g_variant_get_int32 (g_value_get_variant (&value)), ==, 42);
g_value_unset (&value);
g_param_spec_unref (pspec);
}
int
main (int argc, char *argv[])
{
g_type_init ();
test_param_spec_char ();
test_param_spec_string ();
test_param_spec_override ();
test_param_spec_gtype ();
g_test_init (&argc, &argv, NULL);
g_type_init ();
return 0;
g_test_add_func ("/paramspec/char", test_param_spec_char);
g_test_add_func ("/paramspec/string", test_param_spec_string);
g_test_add_func ("/paramspec/override", test_param_spec_override);
g_test_add_func ("/paramspec/gtype", test_param_spec_gtype);
g_test_add_func ("/paramspec/variant", test_param_spec_variant);
return g_test_run ();
}