tests: Add flags and enum to GValue GHash in/out
[platform/upstream/gobject-introspection.git] / tests / scanner / regress.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 #include <string.h>
3 #include <stdlib.h>
4 #include <glib-object.h>
5 #include <gobject/gvaluecollector.h>
6
7 #include "regress.h"
8
9 static gboolean abort_on_error = TRUE;
10
11 #define ASSERT_VALUE(condition)  \
12   if (abort_on_error)             \
13     g_assert (condition);         \
14   else                            \
15     g_warn_if_fail (condition);   \
16
17 void
18 regress_set_abort_on_error (gboolean in)
19 {
20   abort_on_error = in;
21 }
22
23 /* basic types */
24 gboolean
25 regress_test_boolean (gboolean in)
26 {
27   return in;
28 }
29
30 gboolean
31 regress_test_boolean_true (gboolean in)
32 {
33   ASSERT_VALUE (in == TRUE);
34   return in;
35 }
36
37 gboolean
38 regress_test_boolean_false (gboolean in)
39 {
40   ASSERT_VALUE (in == FALSE);
41   return in;
42 }
43
44 gint8
45 regress_test_int8 (gint8 in)
46 {
47   return in;
48 }
49
50 guint8
51 regress_test_uint8 (guint8 in)
52 {
53   return in;
54 }
55
56 gint16
57 regress_test_int16 (gint16 in)
58 {
59   return in;
60 }
61
62 guint16
63 regress_test_uint16 (guint16 in)
64 {
65   return in;
66 }
67
68 gint32
69 regress_test_int32 (gint32 in)
70 {
71   return in;
72 }
73
74 guint32
75 regress_test_uint32 (guint32 in)
76 {
77   return in;
78 }
79
80 gint64
81 regress_test_int64 (gint64 in)
82 {
83   return in;
84 }
85
86 guint64
87 regress_test_uint64 (guint64 in)
88 {
89   return in;
90 }
91
92 gshort
93 regress_test_short (gshort in)
94 {
95   return in;
96 }
97
98 gushort
99 regress_test_ushort (gushort in)
100 {
101   return in;
102 }
103
104 gint
105 regress_test_int (gint in)
106 {
107   return in;
108 }
109
110 guint
111 regress_test_uint (guint in)
112 {
113   return in;
114 }
115
116 glong
117 regress_test_long (glong in)
118 {
119   return in;
120 }
121
122 gulong
123 regress_test_ulong (gulong in)
124 {
125   return in;
126 }
127
128 gssize
129 regress_test_ssize (gssize in)
130 {
131   return in;
132 }
133
134 gsize
135 regress_test_size (gsize in)
136 {
137   return in;
138 }
139
140 gfloat
141 regress_test_float (gfloat in)
142 {
143   return in;
144 }
145
146 gdouble
147 regress_test_double (gdouble in)
148 {
149   return in;
150 }
151
152 gunichar
153 regress_test_unichar (gunichar in)
154 {
155   return in;
156 }
157
158 time_t
159 regress_test_timet (time_t in)
160 {
161   return in;
162 }
163
164 GType
165 regress_test_gtype (GType in)
166 {
167   return in;
168 }
169
170 int
171 regress_test_closure (GClosure *closure)
172 {
173   GValue return_value = {0, };
174   int ret;
175
176   g_value_init (&return_value, G_TYPE_INT);
177
178   g_closure_invoke (closure,
179                     &return_value,
180                     0, NULL,
181                     NULL);
182
183   ret = g_value_get_int (&return_value);
184
185   g_value_unset(&return_value);
186
187   return ret;
188 }
189
190 int
191 regress_test_closure_one_arg (GClosure *closure, int arg)
192 {
193   GValue return_value = {0, };
194   GValue arguments[1];
195   int ret;
196
197   g_value_init (&return_value, G_TYPE_INT);
198
199   memset (&arguments[0], 0, sizeof (arguments));
200   g_value_init (&arguments[0], G_TYPE_INT);
201   g_value_set_int (&arguments[0], arg);
202
203   g_closure_invoke (closure,
204                     &return_value,
205                     1, arguments,
206                     NULL);
207
208   ret = g_value_get_int (&return_value);
209
210   g_value_unset(&return_value);
211   g_value_unset(&arguments[0]);
212
213   return ret;
214 }
215
216 /**
217  * regress_test_closure_variant:
218  * @closure: GClosure which takes one GVariant and returns a GVariant
219  * @arg: (transfer none): a GVariant passed as argument to @closure
220  *
221  * Return value: (transfer full): the return value of @closure
222  */
223 GVariant*
224 regress_test_closure_variant (GClosure *closure, const GVariant* arg)
225 {
226   GValue return_value = {0, };
227   GValue arguments[1] = {{0,} };
228   GVariant *ret;
229   GVariant *local_arg = (GVariant*)g_memdup(arg, sizeof (GVariant*));
230
231   g_value_init (&return_value, G_TYPE_VARIANT);
232
233   g_value_init (&arguments[0], G_TYPE_VARIANT);
234   g_value_set_variant (&arguments[0], local_arg);
235
236   g_closure_invoke (closure,
237                     &return_value,
238                     1, arguments,
239                     NULL);
240
241   ret = g_value_get_variant (&return_value);
242
243   g_free (local_arg);
244   g_value_unset (&return_value);
245   g_value_unset (&arguments[0]);
246
247   return ret;
248 }
249
250 /**
251  * regress_test_value_arg:
252  * @v: (transfer none): a GValue expected to contain an int
253  *
254  * Return value: the int contained in the GValue.
255  */
256 int
257 regress_test_int_value_arg(const GValue *v)
258 {
259   int i;
260
261   i = g_value_get_int (v);
262
263   return i;
264 }
265
266 static GValue value;
267 /**
268  * regress_test_value_return:
269  * @i: an int
270  *
271  * Return value: (transfer none): the int wrapped in a GValue.
272  */
273 const GValue *
274 regress_test_value_return(int i)
275 {
276   memset(&value, '\0', sizeof(GValue));
277
278   g_value_init (&value, G_TYPE_INT);
279   g_value_set_int (&value, i);
280
281   return &value;
282 }
283
284 /************************************************************************/
285 /* foreign structs */
286
287 /**
288  * regress_test_cairo_context_full_return:
289  *
290  * Returns: (transfer full):
291  */
292 cairo_t *
293 regress_test_cairo_context_full_return (void)
294 {
295   cairo_surface_t *surface;
296   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
297   return cairo_create (surface);
298 }
299
300 /**
301  * regress_test_cairo_context_none_in:
302  * @context: (transfer none):
303  */
304 void
305 regress_test_cairo_context_none_in (cairo_t *context)
306 {
307   cairo_surface_t *surface = cairo_get_target (context);
308
309   g_assert (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32);
310   g_assert (cairo_image_surface_get_width (surface) == 10);
311   g_assert (cairo_image_surface_get_height (surface) == 10);
312 }
313
314
315 /**
316  * regress_test_cairo_surface_none_return:
317  *
318  * Returns: (transfer none):
319  */
320 cairo_surface_t *
321 regress_test_cairo_surface_none_return (void)
322 {
323   static cairo_surface_t *surface;
324
325   if (surface == NULL) {
326     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
327   }
328
329   return surface;
330 }
331
332 /**
333  * regress_test_cairo_surface_full_return:
334  *
335  * Returns: (transfer full):
336  */
337 cairo_surface_t *
338 regress_test_cairo_surface_full_return (void)
339 {
340   return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
341 }
342
343 /**
344  * regress_test_cairo_surface_none_in:
345  * @surface: (transfer none):
346  */
347 void
348 regress_test_cairo_surface_none_in (cairo_surface_t *surface)
349 {
350   g_assert (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32);
351   g_assert (cairo_image_surface_get_width (surface) == 10);
352   g_assert (cairo_image_surface_get_height (surface) == 10);
353 }
354
355 /**
356  * regress_test_cairo_surface_full_out:
357  * @surface: (out) (transfer full):
358  */
359 void
360 regress_test_cairo_surface_full_out (cairo_surface_t **surface)
361 {
362   *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
363 }
364
365 /**
366  * regress_test_gvariant_i:
367  *
368  * Returns: (transfer none): New variant
369  */
370 GVariant *
371 regress_test_gvariant_i (void)
372 {
373   return g_variant_new_int32 (1);
374 }
375
376 /**
377  * regress_test_gvariant_s:
378  *
379  * Returns: (transfer none): New variant
380  */
381 GVariant *
382 regress_test_gvariant_s (void)
383 {
384   return g_variant_new_string ("one");
385 }
386
387 /**
388  * regress_test_gvariant_asv:
389  *
390  * Returns: (transfer none): New variant
391  */
392 GVariant *
393 regress_test_gvariant_asv (void)
394 {
395   GVariantBuilder b;
396
397   g_variant_builder_init (&b, G_VARIANT_TYPE ("a{sv}"));
398
399   g_variant_builder_add (&b, "{sv}", "name", g_variant_new_string ("foo"));
400   g_variant_builder_add (&b, "{sv}", "timeout", g_variant_new_int32 (10));
401
402   return g_variant_builder_end (&b);
403 }
404
405 /**
406  * regress_test_gvariant_v:
407  *
408  * Returns: (transfer none): New variant
409  */
410 GVariant *
411 regress_test_gvariant_v (void)
412 {
413   return g_variant_new_variant (g_variant_new_string ("contents"));
414 }
415
416 /**
417  * regress_test_gvariant_as:
418  *
419  * Returns: (transfer none): New variant
420  */
421 GVariant *
422 regress_test_gvariant_as (void)
423 {
424   const char *as[] = { "one", "two", "three", NULL };
425
426   return g_variant_new_strv (as, -1);
427 }
428
429 /************************************************************************/
430 /* utf8 */
431 /* insert BLACK HEART SUIT to ensure UTF-8 doesn't get mangled */
432 static const char utf8_const[]    = "const \xe2\x99\xa5 utf8";
433 static const char utf8_nonconst[] = "nonconst \xe2\x99\xa5 utf8";
434
435 /**
436  * regress_test_utf8_const_return:
437  *
438  * Return value: UTF-8 string
439  */
440 const char *
441 regress_test_utf8_const_return (void)
442 {
443   /* transfer mode none */
444   return utf8_const;
445 }
446
447 /**
448  * regress_test_utf8_nonconst_return:
449  *
450  * Return value: (transfer full): UTF-8 string
451  */
452 char *
453 regress_test_utf8_nonconst_return (void)
454 {
455   return g_strdup (utf8_nonconst);
456 }
457
458 /**
459  * regress_test_utf8_const_in:
460  *
461  */
462 void
463 regress_test_utf8_const_in (const char *in)
464 {
465   /* transfer mode none */
466   g_assert (strcmp (in, utf8_const) == 0);
467 }
468
469 /**
470  * regress_test_utf8_out:
471  * @out: (out) (transfer full):
472  */
473 void
474 regress_test_utf8_out (char **out)
475 {
476   /* out parameter, transfer mode full */
477   *out = g_strdup (utf8_nonconst);
478 }
479
480 /**
481  * regress_test_utf8_inout:
482  * @inout: (inout) (transfer full):
483  */
484 void
485 regress_test_utf8_inout (char **inout)
486 {
487   /* inout parameter, transfer mode full */
488   g_assert (strcmp (*inout, utf8_const) == 0);
489   *inout = g_strdup (utf8_nonconst);
490 }
491
492 /**
493  * regress_test_filename_return:
494  *
495  * Return value: (element-type filename) (transfer full): list of strings
496  */
497 GSList *
498 regress_test_filename_return (void)
499 {
500   GSList *filenames = NULL;
501   filenames = g_slist_prepend (filenames, g_filename_from_utf8("/etc/fstab", -1, NULL, NULL, NULL));
502   filenames = g_slist_prepend (filenames, g_filename_from_utf8("åäö", -1, NULL, NULL, NULL));
503   return filenames;
504 }
505
506 /* in arguments after out arguments */
507
508 /**
509  * regress_test_int_out_utf8:
510  * @length: (out):
511  * @in:
512  */
513 void
514 regress_test_int_out_utf8 (int *length, const char *in)
515 {
516     *length = g_utf8_strlen(in, -1);
517 }
518
519
520 /* multiple output arguments */
521
522 /**
523  * regress_test_multi_double_args:
524  * @in:
525  * @one: (out):
526  * @two: (out):
527  */
528 void
529 regress_test_multi_double_args (gdouble in, gdouble *one, gdouble *two)
530 {
531   *one = in * 2;
532   *two = in * 3;
533 }
534
535 /**
536  * regress_test_utf8_out_out:
537  * @out0: (out) (transfer full): a copy of "first"
538  * @out1: (out) (transfer full): a copy of "second"
539  */
540 void
541 regress_test_utf8_out_out (char **out0, char **out1)
542 {
543   *out0 = g_strdup ("first");
544   *out1 = g_strdup ("second");
545 }
546
547 /**
548  * regress_test_utf8_out_nonconst_return:
549  * @out: (out) (transfer full): a copy of "second"
550  *
551  * Returns: (transfer full): a copy of "first"
552  */
553 char *
554 regress_test_utf8_out_nonconst_return (char **out)
555 {
556   *out = g_strdup ("second");
557   return g_strdup ("first");
558 }
559
560 /**
561  * regress_test_utf8_null_in:
562  * @in: (allow-none):
563  */
564 void
565 regress_test_utf8_null_in (char *in)
566 {
567   g_assert (in == NULL);
568 }
569
570 /**
571  * regress_test_utf8_null_out:
572  * @char_out: (allow-none) (out):
573  */
574 void regress_test_utf8_null_out (char **char_out)
575 {
576   *char_out = NULL;
577 }
578
579
580 /* non-basic-types */
581
582 static const char *test_sequence[] = {"1", "2", "3"};
583
584 /* array */
585
586 /**
587  * regress_test_array_int_in:
588  * @n_ints:
589  * @ints: (array length=n_ints): List of ints
590  */
591 int
592 regress_test_array_int_in (int n_ints, int *ints)
593 {
594   int i, sum = 0;
595   for (i = 0; i < n_ints; i++)
596     sum += ints[i];
597   return sum;
598 }
599
600 /**
601  * regress_test_array_int_out:
602  * @n_ints: (out): the length of @ints
603  * @ints: (out) (array length=n_ints) (transfer full): a list of 5 integers, from 0 to 4 in consecutive order
604  */
605 void
606 regress_test_array_int_out (int *n_ints, int **ints)
607 {
608   int i;
609   *n_ints = 5;
610   *ints = g_malloc0(sizeof(**ints) * *n_ints);
611   for (i = 1; i < *n_ints; i++)
612     (*ints)[i] = (*ints)[i-1] + 1;
613 }
614
615 /**
616  * regress_test_array_int_inout:
617  * @n_ints: (inout): the length of @ints
618  * @ints: (inout) (array length=n_ints) (transfer full): a list of integers whose items will be increased by 1, except the first that will be dropped
619  */
620 void
621 regress_test_array_int_inout (int *n_ints, int **ints)
622 {
623   int i;
624   int *new_ints;
625
626   if (0 < *n_ints)
627     {
628       *n_ints -= 1;
629       new_ints = g_malloc(sizeof(**ints) * *n_ints);
630       for (i = 0; i < *n_ints; i++)
631         new_ints[i] = (*ints)[i + 1] + 1;
632       *ints = new_ints;
633     }
634 }
635
636 /**
637  * regress_test_array_gint8_in:
638  * @n_ints:
639  * @ints: (array length=n_ints): List of ints
640  */
641 int
642 regress_test_array_gint8_in (int n_ints, gint8 *ints)
643 {
644   int i, sum = 0;
645   for (i = 0; i < n_ints; i++)
646     sum += ints[i];
647   return sum;
648 }
649
650 /**
651  * regress_test_array_gint16_in:
652  * @n_ints:
653  * @ints: (array length=n_ints): List of ints
654  */
655 int
656 regress_test_array_gint16_in (int n_ints, gint16 *ints)
657 {
658   int i, sum = 0;
659   for (i = 0; i < n_ints; i++)
660     sum += ints[i];
661   return sum;
662 }
663
664 /**
665  * regress_test_array_gint32_in:
666  * @n_ints:
667  * @ints: (array length=n_ints): List of ints
668  */
669 gint32
670 regress_test_array_gint32_in (int n_ints, gint32 *ints)
671 {
672   int i;
673   gint32 sum = 0;
674   for (i = 0; i < n_ints; i++)
675     sum += ints[i];
676   return sum;
677 }
678
679 /**
680  * regress_test_array_gint64_in:
681  * @n_ints:
682  * @ints: (array length=n_ints): List of ints
683  */
684 gint64
685 regress_test_array_gint64_in (int n_ints, gint64 *ints)
686 {
687   int i;
688   gint64 sum = 0;
689   for (i = 0; i < n_ints; i++)
690     sum += ints[i];
691   return sum;
692 }
693
694 /**
695  * regress_test_strv_in:
696  * @arr: (array zero-terminated=1) (transfer none):
697  */
698 gboolean
699 regress_test_strv_in (char **arr)
700 {
701   if (g_strv_length (arr) != 3)
702     return FALSE;
703   if (strcmp (arr[0], "1") != 0)
704     return FALSE;
705   if (strcmp (arr[1], "2") != 0)
706     return FALSE;
707   if (strcmp (arr[2], "3") != 0)
708     return FALSE;
709   return TRUE;
710 }
711
712 /**
713  * regress_test_array_gtype_in:
714  * @n_types:
715  * @types: (array length=n_types): List of types
716  *
717  * Return value: (transfer full): string representation of provided types
718  */
719 char *
720 regress_test_array_gtype_in (int n_types, GType *types)
721 {
722   GString *string;
723   int i;
724
725   string = g_string_new ("[");
726   for (i = 0; i < n_types; i++)
727     {
728       g_string_append (string, g_type_name (types[i]));
729       g_string_append_c (string, ',');
730     }
731   g_string_append_c (string, ']');
732   return g_string_free (string, FALSE);
733 }
734
735 /**
736  * regress_test_strv_out:
737  *
738  * Returns: (transfer full):
739  */
740 char **
741 regress_test_strv_out (void)
742 {
743   int i = 0;
744   int n = 6;
745   char **ret = g_new (char *, n);
746   ret[i++] = g_strdup ("thanks");
747   ret[i++] = g_strdup ("for");
748   ret[i++] = g_strdup ("all");
749   ret[i++] = g_strdup ("the");
750   ret[i++] = g_strdup ("fish");
751   ret[i++] = NULL;
752   g_assert (i == n);
753   return ret;
754 }
755
756 /**
757  * regress_test_strv_out_container:
758  *
759  * Return value: (array zero-terminated=1) (transfer container):
760  */
761 char **
762 regress_test_strv_out_container (void)
763 {
764   char **ret = g_new (char *, 4);
765   ret[0] = "1";
766   ret[1] = "2";
767   ret[2] = "3";
768   ret[3] = NULL;
769   return ret;
770 }
771
772 /**
773  * regress_test_strv_outarg:
774  * @retp: (array zero-terminated=1) (out) (transfer container):
775  */
776 void
777 regress_test_strv_outarg (char ***retp)
778 {
779   char **ret = g_new (char *, 4);
780   ret[0] = "1";
781   ret[1] = "2";
782   ret[2] = "3";
783   ret[3] = NULL;
784   *retp = ret;
785 }
786
787 /**
788  * regress_test_array_fixed_size_int_in:
789  * @ints: (array fixed-size=5): a list of 5 integers
790  *
791  * Returns: the sum of the items in @ints
792  */
793 int
794 regress_test_array_fixed_size_int_in (int *ints)
795 {
796   int i, sum = 0;
797   for (i = 0; i < 5; i++)
798     sum += ints[i];
799   return sum;
800 }
801
802 /**
803  * regress_test_array_fixed_size_int_out:
804  * @ints: (out) (array fixed-size=5) (transfer full): a list of 5 integers ranging from 0 to 4
805  */
806 void
807 regress_test_array_fixed_size_int_out (int **ints)
808 {
809   int i;
810   *ints = g_malloc0(sizeof(**ints) * 5);
811   for (i = 1; i < 5; i++)
812     (*ints)[i] = (*ints)[i-1] + 1;
813 }
814
815 /**
816  * regress_test_array_fixed_size_int_return:
817  *
818  * Returns: (array fixed-size=5) (transfer full): a list of 5 integers ranging from 0 to 4
819  */
820 int *
821 regress_test_array_fixed_size_int_return (void)
822 {
823   int i, *ints;
824   ints = g_malloc0(sizeof(*ints) * 5);
825   for (i = 1; i < 5; i++)
826     ints[i] = ints[i-1] + 1;
827   return ints;
828 }
829
830 /**
831  * regress_test_strv_out_c:
832  *
833  * Returns: (transfer none):
834  */
835 const char * const*
836 regress_test_strv_out_c (void)
837 {
838   static char **ret = NULL;
839
840   if (ret == NULL)
841     ret = regress_test_strv_out ();
842
843   return (const char * const *) ret;
844 }
845
846 /**
847  * regress_test_array_int_full_out:
848  * @len: length of the returned array.
849  *
850  * Returns: (array length=len) (transfer full): a new array of integers.
851  */
852 int *
853 regress_test_array_int_full_out(int *len)
854 {
855   int *result, i;
856   *len = 5;
857   result = g_malloc0(sizeof(*result) * (*len));
858   for (i=1; i < (*len); i++)
859     result[i] = result[i-1] + 1;
860   return result;
861 }
862
863 /**
864  * regress_test_array_int_none_out:
865  * @len: length of the returned array.
866  *
867  * Returns: (array length=len) (transfer none): a static array of integers.
868  */
869 int *
870 regress_test_array_int_none_out(int *len)
871 {
872   static int result[5] = { 1, 2, 3, 4, 5 };
873   *len = 5;
874   return result;
875 }
876
877 /**
878  * regress_test_array_int_null_in:
879  * @arr: (array length=len) (allow-none):
880  * @len: length
881  */
882 void
883 regress_test_array_int_null_in (int *arr, int len)
884 {
885   g_assert (arr == NULL);
886 }
887
888 /**
889  * regress_test_array_int_null_out:
890  * @arr: (out) (array length=len) (allow-none):
891  * @len: (out) : length
892  */
893 void
894 regress_test_array_int_null_out (int **arr, int *len)
895 {
896   *arr = NULL;
897   *len = 0;
898 }
899
900 /* interface */
901
902 /************************************************************************/
903 /* GList */
904
905 static /*const*/ GList *
906 regress_test_sequence_list()
907 {
908     static GList *list = NULL;
909     if (!list) {
910         gsize i;
911         for (i = 0; i < G_N_ELEMENTS(test_sequence); ++i) {
912             list = g_list_prepend (list, (gpointer)test_sequence[i]);
913         }
914         list = g_list_reverse (list);
915     }
916     return list;
917 }
918
919 /**
920  * regress_test_glist_nothing_return:
921  *
922  * Return value: (element-type utf8) (transfer none):
923  */
924 const GList *
925 regress_test_glist_nothing_return (void)
926 {
927   return regress_test_sequence_list ();
928 }
929
930 /**
931  * regress_test_glist_nothing_return2:
932  *
933  * Return value: (element-type utf8) (transfer none):
934  */
935 GList *
936 regress_test_glist_nothing_return2 (void)
937 {
938   return regress_test_sequence_list ();
939 }
940
941 /**
942  * regress_test_glist_container_return:
943  *
944  * Return value: (element-type utf8) (transfer container):
945  */
946 GList *
947 regress_test_glist_container_return (void)
948 {
949   return g_list_copy (regress_test_sequence_list ());
950 }
951
952 /**
953  * regress_test_glist_everything_return:
954  *
955  * Return value: (element-type utf8) (transfer full):
956  */
957 GList *
958 regress_test_glist_everything_return (void)
959 {
960   GList *list;
961   GList *l;
962
963   list = g_list_copy (regress_test_sequence_list ());
964   for (l = list; l != NULL; l = l->next)
965       l->data = g_strdup (l->data);
966   return list;
967 }
968
969 static void
970 regress_assert_test_sequence_list (const GList *in)
971 {
972   const GList *l;
973   gsize i;
974
975   for (i = 0, l = in; l != NULL; ++i, l = l->next) {
976       g_assert (i < G_N_ELEMENTS(test_sequence));
977       g_assert (strcmp (l->data, test_sequence[i]) == 0);
978   }
979   g_assert (i == G_N_ELEMENTS(test_sequence));
980 }
981
982 /**
983  * regress_test_glist_nothing_in:
984  * @in: (element-type utf8):
985  */
986 void
987 regress_test_glist_nothing_in (const GList *in)
988 {
989   regress_assert_test_sequence_list (in);
990 }
991
992 /**
993  * regress_test_glist_nothing_in2:
994  * @in: (element-type utf8):
995  */
996 void
997 regress_test_glist_nothing_in2 (GList *in)
998 {
999   regress_assert_test_sequence_list (in);
1000 }
1001
1002 /**
1003  * regress_test_glist_null_in:
1004  * @in: (element-type utf8) (allow-none):
1005  */
1006 void
1007 regress_test_glist_null_in (GSList *in)
1008 {
1009   g_assert (in == NULL);
1010 }
1011
1012 /**
1013  * regress_test_glist_null_out:
1014  * @out_list: (out) (element-type utf8) (allow-none):
1015  */
1016 void
1017 regress_test_glist_null_out (GSList **out_list)
1018 {
1019   *out_list = NULL;
1020 }
1021
1022
1023 /************************************************************************/
1024 /* GSList */
1025
1026 static /*const*/ GSList *
1027 regress_test_sequence_slist()
1028 {
1029     static GSList *list = NULL;
1030     if (!list) {
1031         gsize i;
1032         for (i = 0; i < G_N_ELEMENTS(test_sequence); ++i) {
1033             list = g_slist_prepend (list, (gpointer)test_sequence[i]);
1034         }
1035         list = g_slist_reverse (list);
1036     }
1037     return list;
1038 }
1039
1040 /**
1041  * regress_test_gslist_nothing_return:
1042  *
1043  * Return value: (element-type utf8) (transfer none):
1044  */
1045 const GSList *
1046 regress_test_gslist_nothing_return (void)
1047 {
1048   return regress_test_sequence_slist ();
1049 }
1050
1051 /**
1052  * regress_test_gslist_nothing_return2:
1053  *
1054  * Return value: (element-type utf8) (transfer none):
1055  */
1056 GSList *
1057 regress_test_gslist_nothing_return2 (void)
1058 {
1059   return regress_test_sequence_slist ();
1060 }
1061
1062 /**
1063  * regress_test_gslist_container_return:
1064  *
1065  * Return value: (element-type utf8) (transfer container):
1066  */
1067 GSList *
1068 regress_test_gslist_container_return (void)
1069 {
1070   return g_slist_copy (regress_test_sequence_slist ());
1071 }
1072
1073 /**
1074  * regress_test_gslist_everything_return:
1075  *
1076  * Return value: (element-type utf8) (transfer full):
1077  */
1078 GSList *
1079 regress_test_gslist_everything_return (void)
1080 {
1081   GSList *list;
1082   GSList *l;
1083
1084   list = g_slist_copy (regress_test_sequence_slist ());
1085   for (l = list; l != NULL; l = l->next)
1086       l->data = g_strdup (l->data);
1087   return list;
1088 }
1089
1090 static void
1091 regress_assert_test_sequence_slist (const GSList *in)
1092 {
1093   const GSList *l;
1094   gsize i;
1095
1096   for (i = 0, l = in; l != NULL; ++i, l = l->next) {
1097       g_assert (i < G_N_ELEMENTS(test_sequence));
1098       g_assert (strcmp (l->data, test_sequence[i]) == 0);
1099   }
1100   g_assert (i == G_N_ELEMENTS(test_sequence));
1101 }
1102
1103 /**
1104  * regress_test_gslist_nothing_in:
1105  * @in: (element-type utf8):
1106  */
1107 void
1108 regress_test_gslist_nothing_in (const GSList *in)
1109 {
1110   regress_assert_test_sequence_slist (in);
1111 }
1112
1113 /**
1114  * regress_test_gslist_nothing_in2:
1115  * @in: (element-type utf8):
1116  */
1117 void
1118 regress_test_gslist_nothing_in2 (GSList *in)
1119 {
1120   regress_assert_test_sequence_slist (in);
1121 }
1122
1123 /**
1124  * regress_test_gslist_null_in:
1125  * @in: (element-type utf8) (allow-none):
1126  */
1127 void
1128 regress_test_gslist_null_in (GSList *in)
1129 {
1130   g_assert (in == NULL);
1131 }
1132
1133 /**
1134  * regress_test_gslist_null_out:
1135  * @out_list: (out) (element-type utf8) (allow-none):
1136  */
1137 void
1138 regress_test_gslist_null_out (GSList **out_list)
1139 {
1140   *out_list = NULL;
1141 }
1142
1143 /************************************************************************/
1144 /* GHash */
1145
1146 static char *table_data[3][2] = {
1147   { "foo", "bar" }, { "baz", "bat" }, { "qux", "quux" }
1148 };
1149
1150 static GHashTable *
1151 regress_test_table_ghash_new_container()
1152 {
1153   GHashTable *hash;
1154   int i;
1155   hash = g_hash_table_new(g_str_hash, g_str_equal);
1156   for (i=0; i<3; i++)
1157     g_hash_table_insert(hash, table_data[i][0], table_data[i][1]);
1158   return hash;
1159 }
1160
1161 static GHashTable *
1162 regress_test_table_ghash_new_full()
1163 {
1164   GHashTable *hash;
1165   int i;
1166   hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1167   for (i=0; i<3; i++)
1168     g_hash_table_insert(hash,
1169                         g_strdup(table_data[i][0]),
1170                         g_strdup(table_data[i][1]));
1171   return hash;
1172 }
1173
1174 static /*const*/ GHashTable *
1175 regress_test_table_ghash_const()
1176 {
1177   static GHashTable *hash = NULL;
1178   if (!hash) {
1179     hash = regress_test_table_ghash_new_container();
1180   }
1181   return hash;
1182 }
1183
1184 /**
1185  * regress_test_ghash_null_return:
1186  *
1187  * Return value: (element-type utf8 utf8) (transfer none) (allow-none):
1188  */
1189 const GHashTable *
1190 regress_test_ghash_null_return (void)
1191 {
1192   return NULL;
1193 }
1194
1195 /**
1196  * regress_test_ghash_nothing_return:
1197  *
1198  * Return value: (element-type utf8 utf8) (transfer none):
1199  */
1200 const GHashTable *
1201 regress_test_ghash_nothing_return (void)
1202 {
1203   return regress_test_table_ghash_const ();
1204 }
1205
1206 /**
1207  * regress_test_ghash_nothing_return2:
1208  *
1209  * Return value: (element-type utf8 utf8) (transfer none):
1210  */
1211 GHashTable *
1212 regress_test_ghash_nothing_return2 (void)
1213 {
1214   return regress_test_table_ghash_const ();
1215 }
1216
1217 static GValue *
1218 g_value_new (GType type)
1219 {
1220   GValue *value = g_slice_new0(GValue);
1221   g_value_init(value, type);
1222   return value;
1223 }
1224
1225 static void
1226 g_value_free (GValue *value)
1227 {
1228   g_value_unset(value);
1229   g_slice_free(GValue, value);
1230 }
1231
1232 static const gchar *string_array[] = {
1233   "first",
1234   "second",
1235   "third",
1236   NULL
1237 };
1238
1239 /**
1240  * regress_test_ghash_gvalue_return:
1241  *
1242  * Return value: (element-type utf8 GValue) (transfer none):
1243  */
1244 GHashTable *
1245 regress_test_ghash_gvalue_return (void)
1246 {
1247   GHashTable *hash;
1248   GValue *value;
1249   hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1250                                g_free, (GDestroyNotify)g_value_free);
1251
1252   value = g_value_new(G_TYPE_INT);
1253   g_value_set_int(value, 12);
1254   g_hash_table_insert(hash, g_strdup("integer"), value);
1255
1256   value = g_value_new(G_TYPE_BOOLEAN);
1257   g_value_set_boolean(value, TRUE);
1258   g_hash_table_insert(hash, g_strdup("boolean"), value);
1259
1260   value = g_value_new(G_TYPE_STRING);
1261   g_value_set_string(value, "some text");
1262   g_hash_table_insert(hash, g_strdup("string"), value);
1263
1264   value = g_value_new(G_TYPE_STRV);
1265   g_value_set_boxed(value, string_array);
1266   g_hash_table_insert(hash, g_strdup("strings"), value);
1267
1268   value = g_value_new(REGRESS_TEST_TYPE_FLAGS);
1269   g_value_set_flags(value, REGRESS_TEST_FLAG1 | REGRESS_TEST_FLAG3);
1270   g_hash_table_insert(hash, g_strdup("flags"), value);
1271
1272   value = g_value_new(regress_test_enum_get_type());
1273   g_value_set_enum(value, REGRESS_TEST_VALUE2);
1274   g_hash_table_insert(hash, g_strdup("enum"), value);
1275
1276   return hash;
1277 }
1278
1279 /**
1280  * regress_test_ghash_gvalue_in:
1281  * @hash: (element-type utf8 GValue): the hash table returned by
1282  * regress_test_ghash_gvalue_return().
1283  */
1284 void
1285 regress_test_ghash_gvalue_in (GHashTable *hash)
1286 {
1287   GValue *value;
1288   const gchar **strings;
1289   int i;
1290
1291   g_assert(hash != NULL);
1292
1293   value = g_hash_table_lookup(hash, "integer");
1294   g_assert(value != NULL);
1295   g_assert(G_VALUE_HOLDS_INT(value));
1296   g_assert(g_value_get_int(value) == 12);
1297
1298   value = g_hash_table_lookup(hash, "boolean");
1299   g_assert(value != NULL);
1300   g_assert(G_VALUE_HOLDS_BOOLEAN(value));
1301   g_assert(g_value_get_boolean(value) == TRUE);
1302
1303   value = g_hash_table_lookup(hash, "string");
1304   g_assert(value != NULL);
1305   g_assert(G_VALUE_HOLDS_STRING(value));
1306   g_assert(strcmp(g_value_get_string(value), "some text") == 0);
1307
1308   value = g_hash_table_lookup(hash, "strings");
1309   g_assert(value != NULL);
1310   g_assert(G_VALUE_HOLDS(value, G_TYPE_STRV));
1311   strings = g_value_get_boxed(value);
1312   g_assert(strings != NULL);
1313   for (i = 0; string_array[i] != NULL; i++)
1314     g_assert(strcmp(strings[i], string_array[i]) == 0);
1315
1316   value = g_hash_table_lookup(hash, "flags");
1317   g_assert(value != NULL);
1318   g_assert(G_VALUE_HOLDS_FLAGS(value));
1319   g_assert(g_value_get_flags(value) == REGRESS_TEST_FLAG1 | REGRESS_TEST_FLAG3);
1320
1321   value = g_hash_table_lookup(hash, "enum");
1322   g_assert(value != NULL);
1323   g_assert(G_VALUE_HOLDS_ENUM(value));
1324   g_assert(g_value_get_enum(value) == REGRESS_TEST_VALUE2);
1325 }
1326
1327 /**
1328  * regress_test_ghash_container_return:
1329  *
1330  * Return value: (element-type utf8 utf8) (transfer container):
1331  */
1332 GHashTable *
1333 regress_test_ghash_container_return (void)
1334 {
1335   return regress_test_table_ghash_new_container ();
1336 }
1337
1338 /**
1339  * regress_test_ghash_everything_return:
1340  *
1341  * Return value: (element-type utf8 utf8) (transfer full):
1342  */
1343 GHashTable *
1344 regress_test_ghash_everything_return (void)
1345 {
1346   return regress_test_table_ghash_new_full ();
1347 }
1348
1349 static void
1350 assert_test_table_ghash (const GHashTable *in)
1351 {
1352   GHashTable *h = regress_test_table_ghash_const();
1353   GHashTableIter iter;
1354   gpointer key, value;
1355
1356   g_assert(g_hash_table_size(h) ==
1357            g_hash_table_size((GHashTable*)in));
1358
1359   g_hash_table_iter_init(&iter, (GHashTable*)in);
1360   while (g_hash_table_iter_next (&iter, &key, &value))
1361     g_assert( strcmp(g_hash_table_lookup(h, (char*)key), (char*)value) == 0);
1362 }
1363
1364 /**
1365  * regress_test_ghash_null_in:
1366  * @in: (element-type utf8 utf8) (allow-none):
1367  */
1368 void
1369 regress_test_ghash_null_in (const GHashTable *in)
1370 {
1371   g_assert (in == NULL);
1372 }
1373
1374 /**
1375  * regress_test_ghash_null_out:
1376  * @out: (element-type utf8 utf8) (allow-none) (out):
1377  */
1378 void
1379 regress_test_ghash_null_out (const GHashTable **out)
1380 {
1381   *out = NULL;
1382 }
1383
1384 /**
1385  * regress_test_ghash_nothing_in:
1386  * @in: (element-type utf8 utf8):
1387  */
1388 void
1389 regress_test_ghash_nothing_in (const GHashTable *in)
1390 {
1391   assert_test_table_ghash (in);
1392 }
1393
1394 /**
1395  * regress_test_ghash_nothing_in2:
1396  * @in: (element-type utf8 utf8):
1397  */
1398 void
1399 regress_test_ghash_nothing_in2 (GHashTable *in)
1400 {
1401   assert_test_table_ghash (in);
1402 }
1403
1404 /* Nested collection types */
1405
1406 /**
1407  * regress_test_ghash_nested_everything_return:
1408  *
1409  * Specify nested parameterized types directly with the (type ) annotation.
1410  *
1411  * Return value: (type GLib.HashTable<utf8,GLib.HashTable<utf8,utf8>>) (transfer full):
1412  */
1413 GHashTable *
1414 regress_test_ghash_nested_everything_return (void)
1415 {
1416   GHashTable *hash;
1417   hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1418                                (void (*) (gpointer)) g_hash_table_destroy);
1419   g_hash_table_insert(hash, g_strdup("wibble"), regress_test_table_ghash_new_full());
1420   return hash;
1421 }
1422
1423 /**
1424  * regress_test_ghash_nested_everything_return2:
1425  *
1426  * Another way of specifying nested parameterized types: using the
1427  * element-type annotation.
1428  *
1429  * Return value: (element-type utf8 GLib.HashTable<utf8,utf8>) (transfer full):
1430  */
1431 GHashTable *
1432 regress_test_ghash_nested_everything_return2 (void)
1433 {
1434   return regress_test_ghash_nested_everything_return();
1435 }
1436
1437 /************************************************************************/
1438
1439 /**
1440  * regress_test_garray_container_return:
1441  *
1442  * Returns: (transfer container) (type GLib.PtrArray) (element-type utf8):
1443  */
1444 GPtrArray *
1445 regress_test_garray_container_return (void)
1446 {
1447   GPtrArray *array;
1448
1449   array = g_ptr_array_new_with_free_func (g_free);
1450   g_ptr_array_add (array, g_strdup ("regress"));
1451
1452   return array;
1453 }
1454
1455 /**
1456  * regress_test_garray_full_return:
1457  *
1458  * Returns: (transfer full) (type GLib.PtrArray) (element-type utf8):
1459  */
1460 GPtrArray *
1461 regress_test_garray_full_return (void)
1462 {
1463   GPtrArray *array;
1464
1465   array = g_ptr_array_new ();
1466   g_ptr_array_add (array, g_strdup ("regress"));
1467
1468   return array;
1469 }
1470
1471 /************************************************************************/
1472
1473 /* error? */
1474
1475 /* enums / flags */
1476
1477 /**
1478  * NUM_REGRESS_FOO: (skip)
1479  *
1480  * num of elements in RegressFoo
1481  */
1482
1483 GType
1484 regress_test_enum_get_type (void)
1485 {
1486     static GType etype = 0;
1487     if (G_UNLIKELY(etype == 0)) {
1488         static const GEnumValue values[] = {
1489             { REGRESS_TEST_VALUE1, "REGRESS_TEST_VALUE1", "value1" },
1490             { REGRESS_TEST_VALUE2, "REGRESS_TEST_VALUE2", "value2" },
1491             { REGRESS_TEST_VALUE3, "REGRESS_TEST_VALUE3", "value3" },
1492             { REGRESS_TEST_VALUE4, "REGRESS_TEST_VALUE4", "value4" },
1493             { 0, NULL, NULL }
1494         };
1495         etype = g_enum_register_static (g_intern_static_string ("RegressTestEnum"), values);
1496     }
1497
1498     return etype;
1499 }
1500
1501 GType
1502 regress_test_enum_unsigned_get_type (void)
1503 {
1504     static GType etype = 0;
1505     if (G_UNLIKELY(etype == 0)) {
1506         static const GEnumValue values[] = {
1507             { REGRESS_TEST_UNSIGNED_VALUE1, "REGRESS_TEST_UNSIGNED_VALUE1", "value1" },
1508             { REGRESS_TEST_UNSIGNED_VALUE2, "REGRESS_TEST_UNSIGNED_VALUE2", "value2" },
1509             { 0, NULL, NULL }
1510         };
1511         etype = g_enum_register_static (g_intern_static_string ("RegressTestEnumUnsigned"), values);
1512     }
1513
1514     return etype;
1515 }
1516
1517 GType
1518 regress_test_flags_get_type (void)
1519 {
1520     static GType etype = 0;
1521     if (G_UNLIKELY(etype == 0)) {
1522         static const GFlagsValue values[] = {
1523             { REGRESS_TEST_FLAG1, "TEST_FLAG1", "flag1" },
1524             { REGRESS_TEST_FLAG2, "TEST_FLAG2", "flag2" },
1525             { REGRESS_TEST_FLAG3, "TEST_FLAG3", "flag3" },
1526             { 0, NULL, NULL }
1527         };
1528         etype = g_flags_register_static (g_intern_static_string ("RegressTestFlags"), values);
1529     }
1530
1531     return etype;
1532 }
1533
1534 const gchar *
1535 regress_test_enum_param(RegressTestEnum e)
1536 {
1537   GEnumValue *ev;
1538   GEnumClass *ec;
1539
1540   ec = g_type_class_ref (regress_test_enum_get_type ());
1541   ev = g_enum_get_value (ec, e);
1542   g_type_class_unref (ec);
1543
1544   return ev->value_nick;
1545 }
1546
1547 const gchar *
1548 regress_test_unsigned_enum_param(RegressTestEnumUnsigned e)
1549 {
1550   GEnumValue *ev;
1551   GEnumClass *ec;
1552
1553   ec = g_type_class_ref (regress_test_enum_unsigned_get_type ());
1554   ev = g_enum_get_value (ec, e);
1555   g_type_class_unref (ec);
1556
1557   return ev->value_nick;
1558 }
1559
1560 /**
1561  * regress_global_get_flags_out:
1562  * @v: (out): A flags value
1563  *
1564  */
1565 void
1566 regress_global_get_flags_out (RegressTestFlags *v)
1567 {
1568   *v = REGRESS_TEST_FLAG1 | REGRESS_TEST_FLAG3;
1569 }
1570
1571 /* structures */
1572
1573 /**
1574  * regress_test_struct_a_clone:
1575  * @a: the structure
1576  * @a_out: (out caller-allocates): the cloned structure
1577  *
1578  * Make a copy of a RegressTestStructA
1579  */
1580 void
1581 regress_test_struct_a_clone (RegressTestStructA *a,
1582                      RegressTestStructA *a_out)
1583 {
1584   *a_out = *a;
1585 }
1586
1587 /**
1588  * regress_test_struct_b_clone:
1589  * @b: the structure
1590  * @b_out: (out): the cloned structure
1591  *
1592  * Make a copy of a RegressTestStructB
1593  */
1594 void
1595 regress_test_struct_b_clone (RegressTestStructB *b,
1596                      RegressTestStructB *b_out)
1597 {
1598   *b_out = *b;
1599 }
1600
1601 /* plain-old-data boxed types */
1602
1603 RegressTestSimpleBoxedA *
1604 regress_test_simple_boxed_a_copy (RegressTestSimpleBoxedA *a)
1605 {
1606   RegressTestSimpleBoxedA *new_a = g_slice_new (RegressTestSimpleBoxedA);
1607
1608   *new_a = *a;
1609
1610   return new_a;
1611 }
1612
1613 static void
1614 regress_test_simple_boxed_a_free (RegressTestSimpleBoxedA *a)
1615 {
1616   g_slice_free (RegressTestSimpleBoxedA, a);
1617 }
1618
1619 GType
1620 regress_test_simple_boxed_a_get_gtype (void)
1621 {
1622   static GType our_type = 0;
1623
1624   if (our_type == 0)
1625     our_type = g_boxed_type_register_static (g_intern_static_string ("RegressTestSimpleBoxedA"),
1626                                              (GBoxedCopyFunc)regress_test_simple_boxed_a_copy,
1627                                              (GBoxedFreeFunc)regress_test_simple_boxed_a_free);
1628   return our_type;
1629 }
1630
1631 RegressTestSimpleBoxedB *
1632 regress_test_simple_boxed_b_copy (RegressTestSimpleBoxedB *b)
1633 {
1634   RegressTestSimpleBoxedB *new_b = g_slice_new (RegressTestSimpleBoxedB);
1635
1636   *new_b = *b;
1637
1638   return new_b;
1639 }
1640
1641 gboolean
1642 regress_test_simple_boxed_a_equals (RegressTestSimpleBoxedA *a,
1643                             RegressTestSimpleBoxedA *other_a)
1644 {
1645   return (a->some_int == other_a->some_int &&
1646           a->some_int8 == other_a->some_int8 &&
1647           a->some_double == other_a->some_double);
1648 }
1649
1650 const RegressTestSimpleBoxedA*
1651 regress_test_simple_boxed_a_const_return (void)
1652 {
1653   static RegressTestSimpleBoxedA simple_a = {
1654     5, 6, 7.0
1655   };
1656
1657   return &simple_a;
1658 }
1659
1660 static void
1661 regress_test_simple_boxed_b_free (RegressTestSimpleBoxedB *a)
1662 {
1663   g_slice_free (RegressTestSimpleBoxedB, a);
1664 }
1665
1666 GType
1667 regress_test_simple_boxed_b_get_type (void)
1668 {
1669   static GType our_type = 0;
1670
1671   if (our_type == 0)
1672     our_type = g_boxed_type_register_static (g_intern_static_string ("RegressTestSimpleBoxedB"),
1673                                              (GBoxedCopyFunc)regress_test_simple_boxed_b_copy,
1674                                              (GBoxedFreeFunc)regress_test_simple_boxed_b_free);
1675   return our_type;
1676 }
1677
1678 /* opaque boxed */
1679
1680 struct _RegressTestBoxedPrivate
1681 {
1682   guint magic;
1683 };
1684
1685 /**
1686  * regress_test_boxed_new:
1687  *
1688  * Returns: (transfer full):
1689  */
1690 RegressTestBoxed *
1691 regress_test_boxed_new (void)
1692 {
1693   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1694   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1695   boxed->priv->magic = 0xdeadbeef;
1696
1697   return boxed;
1698 }
1699
1700 /**
1701  * regress_test_boxed_new_alternative_constructor1:
1702  *
1703  * Returns: (transfer full):
1704  */
1705 RegressTestBoxed *
1706 regress_test_boxed_new_alternative_constructor1 (int i)
1707 {
1708   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1709   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1710   boxed->priv->magic = 0xdeadbeef;
1711   boxed->some_int8 = i;
1712
1713   return boxed;
1714 }
1715
1716 /**
1717  * regress_test_boxed_new_alternative_constructor2:
1718  *
1719  * Returns: (transfer full):
1720  */
1721 RegressTestBoxed *
1722 regress_test_boxed_new_alternative_constructor2 (int i, int j)
1723 {
1724   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1725   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1726   boxed->priv->magic = 0xdeadbeef;
1727   boxed->some_int8 = i + j;
1728
1729   return boxed;
1730 }
1731
1732 /**
1733  * regress_test_boxed_new_alternative_constructor3:
1734  *
1735  * Returns: (transfer full):
1736  */
1737 RegressTestBoxed *
1738 regress_test_boxed_new_alternative_constructor3 (char *s)
1739 {
1740   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1741   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1742   boxed->priv->magic = 0xdeadbeef;
1743   boxed->some_int8 = atoi(s);
1744
1745   return boxed;
1746 }
1747
1748 /**
1749  * regress_test_boxed_copy:
1750  *
1751  * Returns: (transfer full):
1752  */
1753 RegressTestBoxed *
1754 regress_test_boxed_copy (RegressTestBoxed *boxed)
1755 {
1756   RegressTestBoxed *new_boxed = regress_test_boxed_new();
1757   RegressTestBoxedPrivate *save;
1758
1759   save = new_boxed->priv;
1760   *new_boxed = *boxed;
1761   new_boxed->priv = save;
1762
1763   return new_boxed;
1764 }
1765
1766 gboolean
1767 regress_test_boxed_equals (RegressTestBoxed *boxed,
1768                    RegressTestBoxed *other)
1769 {
1770   return (other->some_int8 == boxed->some_int8 &&
1771           regress_test_simple_boxed_a_equals(&other->nested_a, &boxed->nested_a));
1772 }
1773
1774 static void
1775 regress_test_boxed_free (RegressTestBoxed *boxed)
1776 {
1777   g_assert (boxed->priv->magic == 0xdeadbeef);
1778
1779   g_slice_free (RegressTestBoxedPrivate, boxed->priv);
1780   g_slice_free (RegressTestBoxed, boxed);
1781 }
1782
1783 GType
1784 regress_test_boxed_get_type (void)
1785 {
1786   static GType our_type = 0;
1787
1788   if (our_type == 0)
1789     our_type = g_boxed_type_register_static (g_intern_static_string ("RegressTestBoxed"),
1790                                              (GBoxedCopyFunc)regress_test_boxed_copy,
1791                                              (GBoxedFreeFunc)regress_test_boxed_free);
1792   return our_type;
1793 }
1794
1795 RegressTestBoxedB *
1796 regress_test_boxed_b_new (gint8 some_int8, glong some_long)
1797 {
1798   RegressTestBoxedB *boxed;
1799
1800   boxed = g_slice_new (RegressTestBoxedB);
1801   boxed->some_int8 = some_int8;
1802   boxed->some_long = some_long;
1803
1804   return boxed;
1805 }
1806
1807 RegressTestBoxedB *
1808 regress_test_boxed_b_copy (RegressTestBoxedB *boxed)
1809 {
1810   return regress_test_boxed_b_new (boxed->some_int8, boxed->some_long);
1811 }
1812
1813 static void
1814 regress_test_boxed_b_free (RegressTestBoxedB *boxed)
1815 {
1816   g_slice_free (RegressTestBoxedB, boxed);
1817 }
1818
1819 G_DEFINE_BOXED_TYPE(RegressTestBoxedB,
1820                     regress_test_boxed_b,
1821                     regress_test_boxed_b_copy,
1822                     regress_test_boxed_b_free);
1823
1824 G_DEFINE_TYPE(RegressTestObj, regress_test_obj, G_TYPE_OBJECT);
1825
1826 enum
1827 {
1828   PROP_TEST_OBJ_BARE = 1,
1829   PROP_TEST_OBJ_BOXED,
1830   PROP_TEST_OBJ_HASH_TABLE,
1831   PROP_TEST_OBJ_LIST,
1832   PROP_TEST_OBJ_HASH_TABLE_OLD,
1833   PROP_TEST_OBJ_LIST_OLD,
1834   PROP_TEST_OBJ_INT,
1835   PROP_TEST_OBJ_FLOAT,
1836   PROP_TEST_OBJ_DOUBLE,
1837   PROP_TEST_OBJ_STRING,
1838   PROP_TEST_OBJ_GTYPE
1839 };
1840
1841 static void
1842 regress_test_obj_set_property (GObject      *object,
1843                        guint         property_id,
1844                        const GValue *value,
1845                        GParamSpec   *pspec)
1846 {
1847   RegressTestObj *self = REGRESS_TEST_OBJECT (object);
1848   GList *list;
1849
1850   switch (property_id)
1851     {
1852     case PROP_TEST_OBJ_BARE:
1853       regress_test_obj_set_bare (self, g_value_get_object (value));
1854       break;
1855
1856     case PROP_TEST_OBJ_BOXED:
1857       if (self->boxed)
1858         regress_test_boxed_free (self->boxed);
1859       self->boxed = g_value_dup_boxed (value);
1860       break;
1861
1862     case PROP_TEST_OBJ_HASH_TABLE:
1863     case PROP_TEST_OBJ_HASH_TABLE_OLD:
1864       if (self->hash_table)
1865         g_hash_table_unref (self->hash_table);
1866       self->hash_table = g_hash_table_ref (g_value_get_boxed (value));
1867       break;
1868
1869     case PROP_TEST_OBJ_LIST:
1870     case PROP_TEST_OBJ_LIST_OLD:
1871       if (self->list != NULL)
1872         {
1873           for (list = self->list; list != NULL; list = g_list_next (list))
1874             g_free (list->data);
1875           g_list_free (self->list);
1876         }
1877       self->list = NULL;
1878       for (list = g_value_get_pointer (value); list != NULL; list = g_list_next (list))
1879         self->list = g_list_append (self->list, g_strdup (list->data));
1880       break;
1881
1882     case PROP_TEST_OBJ_INT:
1883       self->some_int8 = g_value_get_int (value);
1884       break;
1885
1886     case PROP_TEST_OBJ_FLOAT:
1887       self->some_float = g_value_get_float (value);
1888       break;
1889
1890     case PROP_TEST_OBJ_DOUBLE:
1891       self->some_double = g_value_get_double (value);
1892       break;
1893
1894     case PROP_TEST_OBJ_STRING:
1895       self->string = g_value_dup_string (value);
1896       break;
1897
1898     case PROP_TEST_OBJ_GTYPE:
1899       self->gtype = g_value_get_gtype (value);
1900       break;
1901
1902     default:
1903       /* We don't have any other property... */
1904       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1905       break;
1906     }
1907 }
1908
1909 static void
1910 regress_test_obj_get_property (GObject    *object,
1911                         guint       property_id,
1912                         GValue     *value,
1913                         GParamSpec *pspec)
1914 {
1915   RegressTestObj *self = REGRESS_TEST_OBJECT (object);
1916
1917   switch (property_id)
1918     {
1919     case PROP_TEST_OBJ_BARE:
1920       g_value_set_object (value, self->bare);
1921       break;
1922
1923     case PROP_TEST_OBJ_BOXED:
1924       g_value_set_boxed (value, self->boxed);
1925       break;
1926
1927     case PROP_TEST_OBJ_HASH_TABLE:
1928     case PROP_TEST_OBJ_HASH_TABLE_OLD:
1929       if (self->hash_table != NULL)
1930         g_hash_table_ref (self->hash_table);
1931       g_value_set_boxed (value, self->hash_table);
1932       break;
1933
1934     case PROP_TEST_OBJ_LIST:
1935     case PROP_TEST_OBJ_LIST_OLD:
1936       g_value_set_pointer (value, self->list);
1937       break;
1938
1939     case PROP_TEST_OBJ_INT:
1940       g_value_set_int (value, self->some_int8);
1941       break;
1942
1943     case PROP_TEST_OBJ_FLOAT:
1944       g_value_set_float (value, self->some_float);
1945       break;
1946
1947     case PROP_TEST_OBJ_DOUBLE:
1948       g_value_set_double (value, self->some_double);
1949       break;
1950
1951     case PROP_TEST_OBJ_STRING:
1952       g_value_set_string (value, self->string);
1953       break;
1954
1955     case PROP_TEST_OBJ_GTYPE:
1956       g_value_set_gtype (value, self->gtype);
1957       break;
1958
1959     default:
1960       /* We don't have any other property... */
1961       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1962       break;
1963     }
1964 }
1965
1966 static void
1967 regress_test_obj_dispose (GObject *gobject)
1968 {
1969   RegressTestObj *self = REGRESS_TEST_OBJECT (gobject);
1970
1971   if (self->bare)
1972     {
1973       g_object_unref (self->bare);
1974
1975       self->bare = NULL;
1976     }
1977
1978   if (self->boxed)
1979     {
1980       regress_test_boxed_free (self->boxed);
1981       self->boxed = NULL;
1982     }
1983
1984   /* Chain up to the parent class */
1985   G_OBJECT_CLASS (regress_test_obj_parent_class)->dispose (gobject);
1986 }
1987
1988 static int
1989 regress_test_obj_default_matrix (RegressTestObj *obj, const char *somestr)
1990 {
1991   return 42;
1992 }
1993
1994 enum {
1995   REGRESS_TEST_OBJ_SIGNAL_SIG_NEW_WITH_ARRAY_PROP,
1996   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_HASH_PROP,
1997   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_STRV,
1998   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_OBJ,
1999   REGRESS_TEST_OBJ_SIGNAL_FIRST,
2000   REGRESS_TEST_OBJ_SIGNAL_CLEANUP,
2001   REGRESS_TEST_OBJ_SIGNAL_ALL,
2002   N_REGRESS_TEST_OBJ_SIGNALS
2003 };
2004
2005 static guint regress_test_obj_signals[N_REGRESS_TEST_OBJ_SIGNALS] = { 0 };
2006
2007 static void
2008 regress_test_obj_class_init (RegressTestObjClass *klass)
2009 {
2010   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
2011   GParamSpec *pspec;
2012   GType param_types[1];
2013
2014   klass->test_signal =
2015     g_signal_newv ("test",
2016                    G_TYPE_FROM_CLASS (gobject_class),
2017                    G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
2018                    NULL /* closure */,
2019                    NULL /* accumulator */,
2020                    NULL /* accumulator data */,
2021                    g_cclosure_marshal_VOID__VOID,
2022                    G_TYPE_NONE /* return_type */,
2023                    0     /* n_params */,
2024                    NULL  /* param_types */);
2025
2026   param_types[0] = regress_test_simple_boxed_a_get_gtype() | G_SIGNAL_TYPE_STATIC_SCOPE;
2027   klass->test_signal_with_static_scope_arg =
2028     g_signal_newv ("test-with-static-scope-arg",
2029                    G_TYPE_FROM_CLASS (gobject_class),
2030                    G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
2031                    NULL /* closure */,
2032                    NULL /* accumulator */,
2033                    NULL /* accumulator data */,
2034                    g_cclosure_marshal_VOID__BOXED,
2035                    G_TYPE_NONE /* return_type */,
2036                    1     /* n_params */,
2037                    param_types);
2038
2039   /**
2040    * RegressTestObj::sig-with-array-prop:
2041    * @self: an object
2042    * @arr: (type GArray) (element-type uint): numbers
2043    *
2044    * This test signal is like TelepathyGlib's
2045    *  TpChannel:: group-members-changed-detailed:
2046    */
2047   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_NEW_WITH_ARRAY_PROP] =
2048     g_signal_new ("sig-with-array-prop",
2049                   G_TYPE_FROM_CLASS (gobject_class),
2050                   G_SIGNAL_RUN_LAST,
2051                   0,
2052                   NULL,
2053                   NULL,
2054                   g_cclosure_marshal_VOID__BOXED,
2055                   G_TYPE_NONE,
2056                   1,
2057                   G_TYPE_ARRAY);
2058
2059   /**
2060    * RegressTestObj::sig-with-hash-prop:
2061    * @self: an object
2062    * @hash: (element-type utf8 GObject.Value):
2063    *
2064    * This test signal is like TelepathyGlib's
2065    *  TpAccount::status-changed
2066    */
2067   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_HASH_PROP] =
2068     g_signal_new ("sig-with-hash-prop",
2069                   G_TYPE_FROM_CLASS (gobject_class),
2070                   G_SIGNAL_RUN_LAST,
2071                   0,
2072                   NULL,
2073                   NULL,
2074                   g_cclosure_marshal_VOID__BOXED,
2075                   G_TYPE_NONE,
2076                   1,
2077                   G_TYPE_HASH_TABLE);
2078
2079   /**
2080    * RegressTestObj::sig-with-strv:
2081    * @self: an object
2082    * @strs: strings
2083    *
2084    * Test GStrv as a param.
2085    */
2086   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_STRV] =
2087     g_signal_new ("sig-with-strv",
2088                   G_TYPE_FROM_CLASS (gobject_class),
2089                   G_SIGNAL_RUN_LAST,
2090                   0,
2091                   NULL,
2092                   NULL,
2093                   g_cclosure_marshal_VOID__BOXED,
2094                   G_TYPE_NONE,
2095                   1,
2096                   G_TYPE_STRV);
2097
2098    /**
2099    * RegressTestObj::sig-with-obj:
2100    * @self: an object
2101    * @obj: (transfer none): A newly created RegressTestObj
2102    *
2103    * Test transfer none GObject as a param (tests refcounting).
2104    * Use with regress_test_obj_emit_sig_with_obj
2105    */
2106   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_OBJ] =
2107     g_signal_new ("sig-with-obj",
2108                   G_TYPE_FROM_CLASS (gobject_class),
2109                   G_SIGNAL_RUN_LAST,
2110                   0,
2111                   NULL,
2112                   NULL,
2113                   g_cclosure_marshal_VOID__OBJECT,
2114                   G_TYPE_NONE,
2115                   1,
2116                   G_TYPE_OBJECT);
2117
2118   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_FIRST] =
2119     g_signal_new ("first",
2120                   G_TYPE_FROM_CLASS (gobject_class),
2121                   G_SIGNAL_RUN_FIRST,
2122                   0,
2123                   NULL,
2124                   NULL,
2125                   g_cclosure_marshal_VOID__VOID,
2126                   G_TYPE_NONE,
2127                   0);
2128
2129     regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_CLEANUP] =
2130     g_signal_new ("cleanup",
2131                   G_TYPE_FROM_CLASS (gobject_class),
2132                   G_SIGNAL_RUN_CLEANUP,
2133                   0,
2134                   NULL,
2135                   NULL,
2136                   g_cclosure_marshal_VOID__VOID,
2137                   G_TYPE_NONE,
2138                   0);
2139
2140     regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_ALL] =
2141     g_signal_new ("all",
2142                   G_TYPE_FROM_CLASS (gobject_class),
2143                   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_ACTION | G_SIGNAL_NO_HOOKS,
2144                   0,
2145                   NULL,
2146                   NULL,
2147                   g_cclosure_marshal_VOID__VOID,
2148                   G_TYPE_NONE,
2149                   0);
2150
2151   gobject_class->set_property = regress_test_obj_set_property;
2152   gobject_class->get_property = regress_test_obj_get_property;
2153   gobject_class->dispose = regress_test_obj_dispose;
2154
2155   pspec = g_param_spec_object ("bare",
2156                                "Bare property",
2157                                "A contained object",
2158                                G_TYPE_OBJECT,
2159                                G_PARAM_READWRITE);
2160   g_object_class_install_property (gobject_class,
2161                                    PROP_TEST_OBJ_BARE,
2162                                    pspec);
2163
2164   pspec = g_param_spec_boxed ("boxed",
2165                               "Boxed property",
2166                               "A contained boxed struct",
2167                               REGRESS_TEST_TYPE_BOXED,
2168                               G_PARAM_READWRITE);
2169   g_object_class_install_property (gobject_class,
2170                                    PROP_TEST_OBJ_BOXED,
2171                                    pspec);
2172
2173   /**
2174    * RegressTestObj:hash-table:
2175    *
2176    * Type: GLib.HashTable(utf8,gint8)
2177    * Transfer: container
2178    */
2179   pspec = g_param_spec_boxed ("hash-table",
2180                               "GHashTable property",
2181                               "A contained GHashTable",
2182                               G_TYPE_HASH_TABLE,
2183                               G_PARAM_READWRITE);
2184   g_object_class_install_property (gobject_class,
2185                                    PROP_TEST_OBJ_HASH_TABLE,
2186                                    pspec);
2187
2188   /**
2189    * RegressTestObj:list:
2190    *
2191    * Type: GLib.List(utf8)
2192    * Transfer: none
2193    */
2194   pspec = g_param_spec_pointer ("list",
2195                                 "GList property",
2196                                 "A contained GList",
2197                                 G_PARAM_READWRITE);
2198   g_object_class_install_property (gobject_class,
2199                                    PROP_TEST_OBJ_LIST,
2200                                    pspec);
2201
2202   /**
2203    * RegressTestObj:hash-table-old:
2204    *
2205    * Type: GLib.HashTable<utf8,gint8>
2206    * Transfer: container
2207    */
2208   pspec = g_param_spec_boxed ("hash-table-old",
2209                               "GHashTable property with <>",
2210                               "A contained GHashTable with <>",
2211                               G_TYPE_HASH_TABLE,
2212                               G_PARAM_READWRITE);
2213   g_object_class_install_property (gobject_class,
2214                                    PROP_TEST_OBJ_HASH_TABLE_OLD,
2215                                    pspec);
2216
2217   /**
2218    * RegressTestObj:list-old:
2219    *
2220    * Type: GLib.List<utf8>
2221    * Transfer: none
2222    */
2223   pspec = g_param_spec_pointer ("list-old",
2224                                 "GList property with ()",
2225                                 "A contained GList with <>",
2226                                 G_PARAM_READWRITE);
2227   g_object_class_install_property (gobject_class,
2228                                    PROP_TEST_OBJ_LIST_OLD,
2229                                    pspec);
2230
2231
2232
2233   /**
2234    * TestObj:int:
2235    */
2236   pspec = g_param_spec_int ("int",
2237                             "int property",
2238                             "A contained int",
2239                             G_MININT,
2240                             G_MAXINT,
2241                             0,
2242                             G_PARAM_READWRITE);
2243   g_object_class_install_property (gobject_class,
2244                                    PROP_TEST_OBJ_INT,
2245                                    pspec);
2246
2247   /**
2248    * TestObj:float:
2249    */
2250   pspec = g_param_spec_float ("float",
2251                               "float property",
2252                               "A contained float",
2253                               G_MINFLOAT,
2254                               G_MAXFLOAT,
2255                               1.0f,
2256                               G_PARAM_READWRITE);
2257   g_object_class_install_property (gobject_class,
2258                                    PROP_TEST_OBJ_FLOAT,
2259                                    pspec);
2260
2261   /**
2262    * TestObj:double:
2263    */
2264   pspec = g_param_spec_double ("double",
2265                                "double property",
2266                                "A contained double",
2267                                G_MINDOUBLE,
2268                                G_MAXDOUBLE,
2269                                1.0f,
2270                                G_PARAM_READWRITE);
2271   g_object_class_install_property (gobject_class,
2272                                    PROP_TEST_OBJ_DOUBLE,
2273                                    pspec);
2274
2275   /**
2276    * TestObj:string:
2277    */
2278   pspec = g_param_spec_string ("string",
2279                                "string property",
2280                                "A contained string",
2281                                NULL,
2282                                G_PARAM_READWRITE);
2283   g_object_class_install_property (gobject_class,
2284                                    PROP_TEST_OBJ_STRING,
2285                                    pspec);
2286
2287
2288   /**
2289    * TestObj:gtype:
2290    */
2291   pspec = g_param_spec_gtype ("gtype",
2292                               "GType property",
2293                               "A GType property",
2294                               G_TYPE_NONE,
2295                               G_PARAM_READWRITE);
2296   g_object_class_install_property (gobject_class,
2297                                    PROP_TEST_OBJ_GTYPE,
2298                                    pspec);
2299
2300   klass->matrix = regress_test_obj_default_matrix;
2301 }
2302
2303 static void
2304 regress_test_obj_init (RegressTestObj *obj)
2305 {
2306   obj->bare = NULL;
2307   obj->boxed = NULL;
2308   obj->hash_table = NULL;
2309   obj->gtype = G_TYPE_INVALID;
2310 }
2311
2312 /**
2313  * regress_test_obj_new: (constructor)
2314  * @obj: A #RegressTestObj
2315  */
2316 RegressTestObj *
2317 regress_test_obj_new (RegressTestObj *obj)
2318 {
2319   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
2320 }
2321
2322 /**
2323  * regress_constructor: (constructor)
2324  *
2325  */
2326 RegressTestObj *
2327 regress_constructor (void)
2328 {
2329   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
2330 }
2331
2332 /**
2333  * regress_test_obj_new_from_file:
2334  */
2335 RegressTestObj *
2336 regress_test_obj_new_from_file (const char *x, GError **error)
2337 {
2338   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
2339 }
2340
2341 /**
2342  * regress_test_obj_set_bare:
2343  * @bare: (allow-none):
2344  */
2345 void
2346 regress_test_obj_set_bare (RegressTestObj *obj, GObject *bare)
2347 {
2348   if (obj->bare)
2349     g_object_unref (obj->bare);
2350   obj->bare = bare;
2351   if (obj->bare)
2352     g_object_ref (obj->bare);
2353 }
2354
2355 void
2356 regress_test_obj_emit_sig_with_obj (RegressTestObj *obj)
2357 {
2358     RegressTestObj *obj_param = regress_constructor ();
2359     g_object_set (obj_param, "int", 3, NULL);
2360     g_signal_emit_by_name (obj, "sig-with-obj", obj_param);
2361     g_object_unref (obj_param);
2362 }
2363
2364 int
2365 regress_test_obj_instance_method (RegressTestObj *obj)
2366 {
2367     return -1;
2368 }
2369
2370 double
2371 regress_test_obj_static_method (int x)
2372 {
2373   return x;
2374 }
2375
2376 /**
2377  * regress_forced_method: (method)
2378  * @obj: A #RegressTestObj
2379  *
2380  */
2381 void
2382 regress_forced_method (RegressTestObj *obj)
2383 {
2384 }
2385
2386 /**
2387  * regress_test_obj_torture_signature_0:
2388  * @obj: A #RegressTestObj
2389  * @x:
2390  * @y: (out):
2391  * @z: (out):
2392  * @foo:
2393  * @q: (out):
2394  * @m:
2395  *
2396  */
2397 void
2398 regress_test_obj_torture_signature_0 (RegressTestObj    *obj,
2399                               int         x,
2400                               double     *y,
2401                               int        *z,
2402                               const char *foo,
2403                               int        *q,
2404                               guint       m)
2405 {
2406   *y = x;
2407   *z = x * 2;
2408   *q = g_utf8_strlen (foo, -1) + m;
2409 }
2410
2411 /**
2412  * regress_test_obj_torture_signature_1:
2413  * @obj: A #RegressTestObj
2414  * @x:
2415  * @y: (out):
2416  * @z: (out):
2417  * @foo:
2418  * @q: (out):
2419  * @m:
2420  * @error: A #GError
2421  *
2422  * This function throws an error if m is odd.
2423  */
2424 gboolean
2425 regress_test_obj_torture_signature_1 (RegressTestObj   *obj,
2426                               int        x,
2427                               double     *y,
2428                               int        *z,
2429                               const char *foo,
2430                               int        *q,
2431                               guint       m,
2432                               GError    **error)
2433 {
2434   *y = x;
2435   *z = x * 2;
2436   *q = g_utf8_strlen (foo, -1) + m;
2437   if (m % 2 == 0)
2438       return TRUE;
2439   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "m is odd");
2440   return FALSE;
2441 }
2442
2443 /**
2444  * regress_test_obj_skip_return_val:
2445  * @obj: a #RegressTestObj
2446  * @a: Parameter.
2447  * @out_b: (out): A return value.
2448  * @c: Other parameter.
2449  * @inout_d: (inout): Will be incremented.
2450  * @out_sum: (out): Return value.
2451  * @num1: Number.
2452  * @num2: Number.
2453  * @error: Return location for error.
2454  *
2455  * Check that the return value is skipped
2456  *
2457  * Returns: (skip): %TRUE if the call succeeds, %FALSE if @error is set.
2458  */
2459 gboolean
2460 regress_test_obj_skip_return_val (RegressTestObj *obj,
2461                                   gint            a,
2462                                   gint           *out_b,
2463                                   gdouble         c,
2464                                   gint           *inout_d,
2465                                   gint           *out_sum,
2466                                   gint            num1,
2467                                   gint            num2,
2468                                   GError        **error)
2469 {
2470   if (out_b != NULL)
2471     *out_b = a + 1;
2472   if (inout_d != NULL)
2473     *inout_d = *inout_d + 1;
2474   if (out_sum != NULL)
2475     *out_sum = num1 + 10*num2;
2476   return TRUE;
2477 }
2478
2479 /**
2480  * regress_test_obj_skip_return_val_no_out:
2481  * @obj: a #RegressTestObj
2482  * @a: Parameter.
2483  * @error: Return location for error.
2484  *
2485  * Check that the return value is skipped. Succeed if a is nonzero, otherwise
2486  * raise an error.
2487  *
2488  * Returns: (skip): %TRUE if the call succeeds, %FALSE if @error is set.
2489  */
2490 gboolean
2491 regress_test_obj_skip_return_val_no_out (RegressTestObj *obj,
2492                                          gint            a,
2493                                          GError        **error)
2494 {
2495   if (a == 0) {
2496     g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "a is zero");
2497     return FALSE;
2498   } else {
2499     return TRUE;
2500   }
2501 }
2502
2503 /**
2504  * regress_test_obj_skip_param:
2505  * @obj: A #RegressTestObj.
2506  * @a: Parameter.
2507  * @out_b: (out): Return value.
2508  * @c: (skip): Other parameter.
2509  * @inout_d: (inout): Will be incremented.
2510  * @out_sum: (out): Return value.
2511  * @num1: Number.
2512  * @num2: Number.
2513  * @error: Return location for error.
2514  *
2515  * Check that a parameter is skipped
2516  *
2517  * Returns: %TRUE if the call succeeds, %FALSE if @error is set.
2518  */
2519 gboolean
2520 regress_test_obj_skip_param (RegressTestObj *obj,
2521                              gint            a,
2522                              gint           *out_b,
2523                              gdouble         c,
2524                              gint           *inout_d,
2525                              gint           *out_sum,
2526                              gint            num1,
2527                              gint            num2,
2528                              GError        **error)
2529 {
2530   if (out_b != NULL)
2531     *out_b = a + 1;
2532   if (inout_d != NULL)
2533     *inout_d = *inout_d + 1;
2534   if (out_sum != NULL)
2535     *out_sum = num1 + 10*num2;
2536   return TRUE;
2537 }
2538
2539 /**
2540  * regress_test_obj_skip_out_param:
2541  * @obj: A #RegressTestObj.
2542  * @a: Parameter.
2543  * @out_b: (out) (skip): Return value.
2544  * @c: Other parameter.
2545  * @inout_d: (inout): Will be incremented.
2546  * @out_sum: (out): Return value.
2547  * @num1: Number.
2548  * @num2: Number.
2549  * @error: Return location for error.
2550  *
2551  * Check that the out value is skipped
2552  *
2553  * Returns: %TRUE if the call succeeds, %FALSE if @error is set.
2554  */
2555 gboolean
2556 regress_test_obj_skip_out_param (RegressTestObj *obj,
2557                                  gint            a,
2558                                  gint           *out_b,
2559                                  gdouble         c,
2560                                  gint           *inout_d,
2561                                  gint           *out_sum,
2562                                  gint            num1,
2563                                  gint            num2,
2564                                  GError        **error)
2565 {
2566   if (out_b != NULL)
2567     *out_b = a + 1;
2568   if (inout_d != NULL)
2569     *inout_d = *inout_d + 1;
2570   if (out_sum != NULL)
2571     *out_sum = num1 + 10*num2;
2572   return TRUE;
2573 }
2574
2575 /**
2576  * regress_test_obj_skip_inout_param:
2577  * @obj: A #RegressTestObj.
2578  * @a: Parameter.
2579  * @out_b: (out): Return value.
2580  * @c: Other parameter.
2581  * @inout_d: (inout) (skip): Will be incremented.
2582  * @out_sum: (out): Return value.
2583  * @num1: Number.
2584  * @num2: Number.
2585  * @error: Return location for error.
2586  *
2587  * Check that the out value is skipped
2588  *
2589  * Returns: %TRUE if the call succeeds, %FALSE if @error is set.
2590  */
2591 gboolean
2592 regress_test_obj_skip_inout_param (RegressTestObj *obj,
2593                                    gint            a,
2594                                    gint           *out_b,
2595                                    gdouble         c,
2596                                    gint           *inout_d,
2597                                    gint           *out_sum,
2598                                    gint            num1,
2599                                    gint            num2,
2600                                    GError        **error)
2601 {
2602   if (out_b != NULL)
2603     *out_b = a + 1;
2604   if (inout_d != NULL)
2605     *inout_d = *inout_d + 1;
2606   if (out_sum != NULL)
2607     *out_sum = num1 + 10*num2;
2608   return TRUE;
2609 }
2610
2611 /**
2612  * regress_test_obj_do_matrix:
2613  * @obj: A #RegressTestObj
2614  * @somestr: Meaningless string
2615  *
2616  * This method is virtual.  Notably its name differs from the virtual
2617  * slot name, which makes it useful for testing bindings handle this
2618  * case.
2619  *
2620  * Virtual: matrix
2621  */
2622 int
2623 regress_test_obj_do_matrix (RegressTestObj *obj, const char *somestr)
2624 {
2625   return REGRESS_TEST_OBJ_GET_CLASS (obj)->matrix (obj, somestr);
2626 }
2627
2628 /**
2629  * regress_func_obj_null_in:
2630  * @obj: (allow-none): A #RegressTestObj
2631  */
2632 void
2633 regress_func_obj_null_in (RegressTestObj *obj)
2634 {
2635 }
2636
2637 /**
2638  * regress_test_obj_null_out:
2639  * @obj: (allow-none) (out): A #RegressTestObj
2640  */
2641 void
2642 regress_test_obj_null_out (RegressTestObj **obj)
2643 {
2644   if (obj)
2645     *obj = NULL;
2646 }
2647
2648 /**
2649  * regress_test_array_fixed_out_objects:
2650  * @objs: (out) (array fixed-size=2) (transfer full): An array of #RegressTestObj
2651  */
2652 void
2653 regress_test_array_fixed_out_objects (RegressTestObj ***objs)
2654 {
2655     RegressTestObj **values = (RegressTestObj**)g_new(gpointer, 2);
2656
2657     values[0] = regress_constructor();
2658     values[1] = regress_constructor();
2659
2660     *objs = values;
2661 }
2662
2663 typedef struct _CallbackInfo CallbackInfo;
2664
2665 struct _CallbackInfo
2666 {
2667   RegressTestCallbackUserData callback;
2668   GDestroyNotify notify;
2669   gpointer user_data;
2670 };
2671
2672
2673 G_DEFINE_TYPE(RegressTestSubObj, regress_test_sub_obj, REGRESS_TEST_TYPE_OBJ);
2674
2675 static void
2676 regress_test_sub_obj_class_init (RegressTestSubObjClass *klass)
2677 {
2678 }
2679
2680 static void
2681 regress_test_sub_obj_init (RegressTestSubObj *obj)
2682 {
2683 }
2684
2685 RegressTestObj*
2686 regress_test_sub_obj_new ()
2687 {
2688   return g_object_new (REGRESS_TEST_TYPE_SUB_OBJ, NULL);
2689 }
2690
2691 int
2692 regress_test_sub_obj_instance_method (RegressTestSubObj *obj)
2693 {
2694     return 0;
2695 }
2696
2697 void
2698 regress_test_sub_obj_unset_bare (RegressTestSubObj *obj)
2699 {
2700   regress_test_obj_set_bare(REGRESS_TEST_OBJECT(obj), NULL);
2701 }
2702
2703 /* RegressTestFundamental */
2704
2705 /**
2706  * regress_test_fundamental_object_ref:
2707  *
2708  * Returns: (transfer full): A new #RegressTestFundamentalObject
2709  */
2710 RegressTestFundamentalObject *
2711 regress_test_fundamental_object_ref (RegressTestFundamentalObject * fundamental_object)
2712 {
2713   g_return_val_if_fail (fundamental_object != NULL, NULL);
2714   g_atomic_int_inc (&fundamental_object->refcount);
2715
2716   return fundamental_object;
2717 }
2718
2719 static void
2720 regress_test_fundamental_object_free (RegressTestFundamentalObject * fundamental_object)
2721 {
2722   RegressTestFundamentalObjectClass *mo_class;
2723   regress_test_fundamental_object_ref (fundamental_object);
2724
2725   mo_class = REGRESS_TEST_FUNDAMENTAL_OBJECT_GET_CLASS (fundamental_object);
2726   mo_class->finalize (fundamental_object);
2727
2728   if (G_LIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
2729     g_type_free_instance ((GTypeInstance *) fundamental_object);
2730   }
2731 }
2732
2733 void
2734 regress_test_fundamental_object_unref (RegressTestFundamentalObject * fundamental_object)
2735 {
2736   g_return_if_fail (fundamental_object != NULL);
2737   g_return_if_fail (fundamental_object->refcount > 0);
2738
2739   if (G_UNLIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
2740     regress_test_fundamental_object_free (fundamental_object);
2741   }
2742 }
2743
2744 static void
2745 regress_test_fundamental_object_replace (RegressTestFundamentalObject ** olddata, RegressTestFundamentalObject * newdata)
2746 {
2747   RegressTestFundamentalObject *olddata_val;
2748
2749   g_return_if_fail (olddata != NULL);
2750
2751   olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
2752
2753   if (olddata_val == newdata)
2754     return;
2755
2756   if (newdata)
2757     regress_test_fundamental_object_ref (newdata);
2758
2759   while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata,
2760           olddata_val, newdata)) {
2761     olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
2762   }
2763
2764   if (olddata_val)
2765     regress_test_fundamental_object_unref (olddata_val);
2766 }
2767
2768 static void
2769 regress_test_value_fundamental_object_init (GValue * value)
2770 {
2771   value->data[0].v_pointer = NULL;
2772 }
2773
2774 static void
2775 regress_test_value_fundamental_object_free (GValue * value)
2776 {
2777   if (value->data[0].v_pointer) {
2778     regress_test_fundamental_object_unref (REGRESS_TEST_FUNDAMENTAL_OBJECT_CAST (value->data[0].v_pointer));
2779   }
2780 }
2781
2782 static void
2783 regress_test_value_fundamental_object_copy (const GValue * src_value, GValue * dest_value)
2784 {
2785   if (src_value->data[0].v_pointer) {
2786     dest_value->data[0].v_pointer =
2787         regress_test_fundamental_object_ref (REGRESS_TEST_FUNDAMENTAL_OBJECT_CAST (src_value->data[0].
2788             v_pointer));
2789   } else {
2790     dest_value->data[0].v_pointer = NULL;
2791   }
2792 }
2793
2794 static gpointer
2795 regress_test_value_fundamental_object_peek_pointer (const GValue * value)
2796 {
2797   return value->data[0].v_pointer;
2798 }
2799
2800 static gchar *
2801 regress_test_value_fundamental_object_collect (GValue * value,
2802                                        guint n_collect_values,
2803                                        GTypeCValue * collect_values,
2804                                        guint collect_flags)
2805 {
2806   if (collect_values[0].v_pointer) {
2807     value->data[0].v_pointer =
2808         regress_test_fundamental_object_ref (collect_values[0].v_pointer);
2809   } else {
2810     value->data[0].v_pointer = NULL;
2811   }
2812
2813   return NULL;
2814 }
2815
2816 static gchar *
2817 regress_test_value_fundamental_object_lcopy (const GValue * value,
2818                                      guint n_collect_values,
2819                                      GTypeCValue * collect_values,
2820                                      guint collect_flags)
2821 {
2822   gpointer *fundamental_object_p = collect_values[0].v_pointer;
2823
2824   if (!fundamental_object_p) {
2825     return g_strdup_printf ("value location for '%s' passed as NULL",
2826         G_VALUE_TYPE_NAME (value));
2827   }
2828
2829   if (!value->data[0].v_pointer)
2830     *fundamental_object_p = NULL;
2831   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
2832     *fundamental_object_p = value->data[0].v_pointer;
2833   else
2834     *fundamental_object_p = regress_test_fundamental_object_ref (value->data[0].v_pointer);
2835
2836   return NULL;
2837 }
2838
2839 static void
2840 regress_test_fundamental_object_finalize (RegressTestFundamentalObject * obj)
2841 {
2842
2843 }
2844
2845 static RegressTestFundamentalObject *
2846 regress_test_fundamental_object_copy_default (const RegressTestFundamentalObject * obj)
2847 {
2848   g_warning ("RegressTestFundamentalObject classes must implement RegressTestFundamentalObject::copy");
2849   return NULL;
2850 }
2851
2852 static void
2853 regress_test_fundamental_object_class_init (gpointer g_class, gpointer class_data)
2854 {
2855   RegressTestFundamentalObjectClass *mo_class = REGRESS_TEST_FUNDAMENTAL_OBJECT_CLASS (g_class);
2856
2857   mo_class->copy = regress_test_fundamental_object_copy_default;
2858   mo_class->finalize = regress_test_fundamental_object_finalize;
2859 }
2860
2861 static void
2862 regress_test_fundamental_object_init (GTypeInstance * instance, gpointer klass)
2863 {
2864   RegressTestFundamentalObject *fundamental_object = REGRESS_TEST_FUNDAMENTAL_OBJECT_CAST (instance);
2865
2866   fundamental_object->refcount = 1;
2867 }
2868
2869 /**
2870  * RegressTestFundamentalObject:
2871  *
2872  * Ref Func: regress_test_fundamental_object_ref
2873  * Unref Func: regress_test_fundamental_object_unref
2874  * Set Value Func: regress_test_value_set_fundamental_object
2875  * Get Value Func: regress_test_value_get_fundamental_object
2876  */
2877
2878 GType
2879 regress_test_fundamental_object_get_type (void)
2880 {
2881   static GType _test_fundamental_object_type = 0;
2882
2883   if (G_UNLIKELY (_test_fundamental_object_type == 0)) {
2884     static const GTypeValueTable value_table = {
2885       regress_test_value_fundamental_object_init,
2886       regress_test_value_fundamental_object_free,
2887       regress_test_value_fundamental_object_copy,
2888       regress_test_value_fundamental_object_peek_pointer,
2889       (char *) "p",
2890       regress_test_value_fundamental_object_collect,
2891       (char *) "p",
2892       regress_test_value_fundamental_object_lcopy
2893     };
2894     static const GTypeInfo fundamental_object_info = {
2895       sizeof (RegressTestFundamentalObjectClass),
2896       NULL, NULL,
2897       regress_test_fundamental_object_class_init,
2898       NULL,
2899       NULL,
2900       sizeof (RegressTestFundamentalObject),
2901       0,
2902       (GInstanceInitFunc) regress_test_fundamental_object_init,
2903       &value_table
2904     };
2905     static const GTypeFundamentalInfo fundamental_object_fundamental_info = {
2906       (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE |
2907           G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
2908     };
2909
2910     _test_fundamental_object_type = g_type_fundamental_next ();
2911     g_type_register_fundamental (_test_fundamental_object_type, "RegressTestFundamentalObject",
2912         &fundamental_object_info, &fundamental_object_fundamental_info, G_TYPE_FLAG_ABSTRACT);
2913
2914   }
2915
2916   return _test_fundamental_object_type;
2917 }
2918
2919 /**
2920  * regress_test_value_set_fundamental_object: (skip)
2921  * @value:
2922  * @fundamental_object:
2923  */
2924 void
2925 regress_test_value_set_fundamental_object (GValue * value, RegressTestFundamentalObject * fundamental_object)
2926 {
2927   gpointer *pointer_p;
2928
2929   g_return_if_fail (REGRESS_TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value));
2930   g_return_if_fail (fundamental_object == NULL || REGRESS_TEST_IS_FUNDAMENTAL_OBJECT (fundamental_object));
2931
2932   pointer_p = &value->data[0].v_pointer;
2933
2934   regress_test_fundamental_object_replace ((RegressTestFundamentalObject **) pointer_p, fundamental_object);
2935 }
2936
2937 /**
2938  * regress_test_value_get_fundamental_object: (skip)
2939  * @value:
2940  */
2941 RegressTestFundamentalObject *
2942 regress_test_value_get_fundamental_object (const GValue * value)
2943 {
2944   g_return_val_if_fail (REGRESS_TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value), NULL);
2945
2946   return value->data[0].v_pointer;
2947 }
2948
2949 static RegressTestFundamentalObjectClass *parent_class = NULL;
2950
2951 G_DEFINE_TYPE (RegressTestFundamentalSubObject, regress_test_fundamental_sub_object, REGRESS_TEST_TYPE_FUNDAMENTAL_OBJECT);
2952
2953 static RegressTestFundamentalSubObject *
2954 _regress_test_fundamental_sub_object_copy (RegressTestFundamentalSubObject * fundamental_sub_object)
2955 {
2956   RegressTestFundamentalSubObject *copy;
2957
2958   copy = regress_test_fundamental_sub_object_new(NULL);
2959   copy->data = g_strdup(fundamental_sub_object->data);
2960   return copy;
2961 }
2962
2963 static void
2964 regress_test_fundamental_sub_object_finalize (RegressTestFundamentalSubObject * fundamental_sub_object)
2965 {
2966   g_return_if_fail (fundamental_sub_object != NULL);
2967
2968   g_free(fundamental_sub_object->data);
2969   regress_test_fundamental_object_finalize (REGRESS_TEST_FUNDAMENTAL_OBJECT (fundamental_sub_object));
2970 }
2971
2972 static void
2973 regress_test_fundamental_sub_object_class_init (RegressTestFundamentalSubObjectClass * klass)
2974 {
2975   parent_class = g_type_class_peek_parent (klass);
2976
2977   klass->fundamental_object_class.copy = (RegressTestFundamentalObjectCopyFunction) _regress_test_fundamental_sub_object_copy;
2978   klass->fundamental_object_class.finalize =
2979       (RegressTestFundamentalObjectFinalizeFunction) regress_test_fundamental_sub_object_finalize;
2980 }
2981
2982 static void
2983 regress_test_fundamental_sub_object_init(RegressTestFundamentalSubObject *object)
2984 {
2985
2986 }
2987
2988 /**
2989  * regress_test_fundamental_sub_object_new:
2990  */
2991 RegressTestFundamentalSubObject *
2992 regress_test_fundamental_sub_object_new (const char * data)
2993 {
2994   RegressTestFundamentalSubObject *object;
2995
2996   object = (RegressTestFundamentalSubObject *) g_type_create_instance (regress_test_fundamental_sub_object_get_type());
2997   object->data = g_strdup(data);
2998   return object;
2999 }
3000
3001
3002 /**
3003  * regress_test_callback:
3004  * @callback: (scope call) (allow-none):
3005  *
3006  **/
3007 int
3008 regress_test_callback (RegressTestCallback callback)
3009 {
3010     if (callback != NULL)
3011         return callback();
3012     return 0;
3013 }
3014
3015 /**
3016  * regress_test_multi_callback:
3017  * @callback: (scope call) (allow-none):
3018  *
3019  **/
3020 int
3021 regress_test_multi_callback (RegressTestCallback callback)
3022 {
3023     int sum = 0;
3024     if (callback != NULL) {
3025         sum += callback();
3026         sum += callback();
3027     }
3028
3029     return sum;
3030 }
3031
3032 /**
3033  * regress_test_array_callback:
3034  * @callback: (scope call):
3035  *
3036  **/
3037 int regress_test_array_callback (RegressTestCallbackArray callback)
3038 {
3039   static const char *strings[] = { "one", "two", "three" };
3040   static int ints[] = { -1, 0, 1, 2 };
3041   int sum = 0;
3042
3043   sum += callback(ints, 4, strings, 3);
3044   sum += callback(ints, 4, strings, 3);
3045
3046   return sum;
3047 }
3048
3049 /**
3050  * regress_test_simple_callback:
3051  * @callback: (scope call) (allow-none):
3052  *
3053  **/
3054 void
3055 regress_test_simple_callback (RegressTestSimpleCallback callback)
3056 {
3057     if (callback != NULL)
3058         callback();
3059
3060     return;
3061 }
3062
3063 /**
3064  * regress_test_callback_user_data:
3065  * @callback: (scope call):
3066  *
3067  * Call - callback parameter persists for the duration of the method
3068  * call and can be released on return.
3069  **/
3070 int
3071 regress_test_callback_user_data (RegressTestCallbackUserData callback,
3072                          gpointer user_data)
3073 {
3074   return callback(user_data);
3075 }
3076
3077 static GSList *notified_callbacks = NULL;
3078
3079 /**
3080  * regress_test_callback_destroy_notify:
3081  * @callback: (scope notified):
3082  *
3083  * Notified - callback persists until a DestroyNotify delegate
3084  * is invoked.
3085  **/
3086 int
3087 regress_test_callback_destroy_notify (RegressTestCallbackUserData callback,
3088                               gpointer user_data,
3089                               GDestroyNotify notify)
3090 {
3091   int retval;
3092   CallbackInfo *info;
3093
3094   retval = callback(user_data);
3095
3096   info = g_slice_new(CallbackInfo);
3097   info->callback = callback;
3098   info->notify = notify;
3099   info->user_data = user_data;
3100
3101   notified_callbacks = g_slist_prepend(notified_callbacks, info);
3102
3103   return retval;
3104 }
3105
3106 /**
3107  * regress_test_callback_thaw_notifications:
3108  *
3109  * Invokes all callbacks installed by #test_callback_destroy_notify(),
3110  * adding up their return values, and removes them, invoking the
3111  * corresponding destroy notfications.
3112  *
3113  * Return value: Sum of the return values of the invoked callbacks.
3114  */
3115 int
3116 regress_test_callback_thaw_notifications (void)
3117 {
3118   int retval = 0;
3119   GSList *node;
3120
3121   for (node = notified_callbacks; node != NULL; node = node->next)
3122     {
3123       CallbackInfo *info = node->data;
3124       retval += info->callback (info->user_data);
3125       if (info->notify)
3126         info->notify (info->user_data);
3127       g_slice_free (CallbackInfo, info);
3128     }
3129
3130   g_slist_free (notified_callbacks);
3131   notified_callbacks = NULL;
3132
3133   return retval;
3134 }
3135
3136 static GSList *async_callbacks = NULL;
3137
3138 /**
3139  * regress_test_callback_async:
3140  * @callback: (scope async):
3141  *
3142  **/
3143 void
3144 regress_test_callback_async (RegressTestCallbackUserData callback,
3145                      gpointer user_data)
3146 {
3147   CallbackInfo *info;
3148
3149   info = g_slice_new(CallbackInfo);
3150   info->callback = callback;
3151   info->user_data = user_data;
3152
3153   async_callbacks = g_slist_prepend(async_callbacks, info);
3154 }
3155
3156 /**
3157  * regress_test_callback_thaw_async:
3158  */
3159 int
3160 regress_test_callback_thaw_async (void)
3161 {
3162   int retval = 0;
3163   GSList *node;
3164
3165   for (node = async_callbacks; node != NULL; node = node->next)
3166     {
3167       CallbackInfo *info = node->data;
3168       retval = info->callback (info->user_data);
3169       g_slice_free (CallbackInfo, info);
3170     }
3171
3172   g_slist_free (async_callbacks);
3173   async_callbacks = NULL;
3174   return retval;
3175 }
3176
3177 void
3178 regress_test_async_ready_callback (GAsyncReadyCallback callback)
3179 {
3180   GSimpleAsyncResult *result = g_simple_async_result_new (NULL, callback, NULL,
3181     regress_test_async_ready_callback);
3182   g_simple_async_result_complete_in_idle (result);
3183 }
3184
3185 /**
3186  * regress_test_obj_instance_method_callback:
3187  * @callback: (scope call) (allow-none):
3188  *
3189  **/
3190 void
3191 regress_test_obj_instance_method_callback (RegressTestObj *obj, RegressTestCallback callback)
3192 {
3193     if (callback != NULL)
3194         callback();
3195 }
3196
3197 /**
3198  * regress_test_obj_static_method_callback:
3199  * @callback: (scope call) (allow-none):
3200  *
3201  **/
3202 void
3203 regress_test_obj_static_method_callback (RegressTestCallback callback)
3204 {
3205     if (callback != NULL)
3206         callback();
3207 }
3208
3209 /**
3210  * regress_test_obj_new_callback:
3211  * @callback: (scope notified):
3212  **/
3213 RegressTestObj *
3214 regress_test_obj_new_callback (RegressTestCallbackUserData callback, gpointer user_data,
3215                        GDestroyNotify notify)
3216 {
3217   CallbackInfo *info;
3218
3219   callback(user_data);
3220
3221   info = g_slice_new(CallbackInfo);
3222   info->callback = callback;
3223   info->notify = notify;
3224   info->user_data = user_data;
3225
3226   notified_callbacks = g_slist_prepend(notified_callbacks, info);
3227
3228   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
3229 }
3230
3231 /**
3232  * regress_test_hash_table_callback:
3233  * @data: (element-type utf8 gint): GHashTable that gets passed to callback
3234  * @callback: (scope call):
3235  **/
3236 void
3237 regress_test_hash_table_callback (GHashTable *data, RegressTestCallbackHashtable callback)
3238 {
3239   callback (data);
3240 }
3241
3242 /**
3243  * regress_test_gerror_callback:
3244  * @callback: (scope call):
3245  **/
3246 void
3247 regress_test_gerror_callback (RegressTestCallbackGError callback)
3248 {
3249   GError *error;
3250
3251   error = g_error_new_literal (G_IO_ERROR,
3252                                G_IO_ERROR_NOT_SUPPORTED,
3253                                "regression test error");
3254   callback (error);
3255   g_error_free (error);
3256 }
3257
3258 /**
3259  * regress_test_null_gerror_callback:
3260  * @callback: (scope call):
3261  **/
3262 void
3263 regress_test_null_gerror_callback (RegressTestCallbackGError callback)
3264 {
3265   callback (NULL);
3266 }
3267
3268 /**
3269  * regress_test_owned_gerror_callback:
3270  * @callback: (scope call):
3271  **/
3272 void
3273 regress_test_owned_gerror_callback (RegressTestCallbackOwnedGError callback)
3274 {
3275   GError *error;
3276
3277   error = g_error_new_literal (G_IO_ERROR,
3278                                G_IO_ERROR_PERMISSION_DENIED,
3279                                "regression test owned error");
3280   callback (error);
3281 }
3282
3283 /* interface */
3284
3285 static void
3286 regress_test_interface_class_init(void *g_iface)
3287 {
3288 }
3289
3290 GType
3291 regress_test_interface_get_type(void)
3292 {
3293     static GType type = 0;
3294     if (type == 0) {
3295         type = g_type_register_static_simple (G_TYPE_INTERFACE,
3296                                               "RegressTestInterface",
3297                                               sizeof (RegressTestInterfaceIface),
3298                                               (GClassInitFunc) regress_test_interface_class_init,
3299                                               0, NULL, 0);
3300     }
3301
3302     return type;
3303 }
3304
3305 /* gobject with non-standard prefix */
3306 G_DEFINE_TYPE(RegressTestWi8021x, regress_test_wi_802_1x, G_TYPE_OBJECT);
3307
3308 enum
3309 {
3310   PROP_TEST_WI_802_1X_TESTBOOL = 1
3311 };
3312
3313 static void
3314 regress_test_wi_802_1x_set_property (GObject      *object,
3315                              guint         property_id,
3316                              const GValue *value,
3317                              GParamSpec   *pspec)
3318 {
3319   RegressTestWi8021x *self = REGRESS_TEST_WI_802_1X (object);
3320
3321   switch (property_id)
3322     {
3323     case PROP_TEST_WI_802_1X_TESTBOOL:
3324       regress_test_wi_802_1x_set_testbool (self, g_value_get_boolean (value));
3325       break;
3326
3327     default:
3328       /* We don't have any other property... */
3329       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
3330       break;
3331     }
3332 }
3333
3334 static void
3335 regress_test_wi_802_1x_get_property (GObject    *object,
3336                         guint       property_id,
3337                         GValue     *value,
3338                         GParamSpec *pspec)
3339 {
3340   RegressTestWi8021x *self = REGRESS_TEST_WI_802_1X (object);
3341
3342   switch (property_id)
3343     {
3344     case PROP_TEST_WI_802_1X_TESTBOOL:
3345       g_value_set_boolean (value, regress_test_wi_802_1x_get_testbool (self));
3346       break;
3347
3348     default:
3349       /* We don't have any other property... */
3350       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
3351       break;
3352     }
3353 }
3354
3355 static void
3356 regress_test_wi_802_1x_dispose (GObject *gobject)
3357 {
3358   /* Chain up to the parent class */
3359   G_OBJECT_CLASS (regress_test_wi_802_1x_parent_class)->dispose (gobject);
3360 }
3361
3362 static void
3363 regress_test_wi_802_1x_class_init (RegressTestWi8021xClass *klass)
3364 {
3365   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3366   GParamSpec *pspec;
3367
3368   gobject_class->set_property = regress_test_wi_802_1x_set_property;
3369   gobject_class->get_property = regress_test_wi_802_1x_get_property;
3370   gobject_class->dispose = regress_test_wi_802_1x_dispose;
3371
3372   pspec = g_param_spec_boolean ("testbool",
3373                                 "Nick for testbool",
3374                                 "Blurb for testbool",
3375                                 TRUE,
3376                                 G_PARAM_READWRITE);
3377   g_object_class_install_property (gobject_class,
3378                                    PROP_TEST_WI_802_1X_TESTBOOL,
3379                                    pspec);
3380 }
3381
3382 static void
3383 regress_test_wi_802_1x_init (RegressTestWi8021x *obj)
3384 {
3385   obj->testbool = TRUE;
3386 }
3387
3388 RegressTestWi8021x *
3389 regress_test_wi_802_1x_new (void)
3390 {
3391   return g_object_new (REGRESS_TEST_TYPE_WI_802_1X, NULL);
3392 }
3393
3394 void
3395 regress_test_wi_802_1x_set_testbool (RegressTestWi8021x *obj, gboolean val)
3396 {
3397   obj->testbool = val;
3398 }
3399
3400 gboolean
3401 regress_test_wi_802_1x_get_testbool (RegressTestWi8021x *obj)
3402 {
3403   return obj->testbool;
3404 }
3405
3406 int
3407 regress_test_wi_802_1x_static_method (int x)
3408 {
3409   return 2*x;
3410 }
3411
3412 /* floating gobject */
3413 G_DEFINE_TYPE(RegressTestFloating, regress_test_floating, G_TYPE_INITIALLY_UNOWNED);
3414
3415 static void
3416 regress_test_floating_finalize(GObject *object)
3417 {
3418   g_assert(!g_object_is_floating (object));
3419
3420   G_OBJECT_CLASS(regress_test_floating_parent_class)->finalize(object);
3421 }
3422
3423 static void
3424 regress_test_floating_class_init (RegressTestFloatingClass *klass)
3425 {
3426   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3427   gobject_class->finalize = regress_test_floating_finalize;
3428 }
3429
3430 static void
3431 regress_test_floating_init (RegressTestFloating *obj)
3432 {
3433 }
3434
3435 /**
3436  * regress_test_floating_new:
3437  *
3438  * Returns:: A new floating #RegressTestFloating
3439  */
3440 RegressTestFloating *
3441 regress_test_floating_new (void)
3442 {
3443   return g_object_new (REGRESS_TEST_TYPE_FLOATING, NULL);
3444 }
3445
3446
3447 /**
3448  * regress_test_torture_signature_0:
3449  * @x:
3450  * @y: (out):
3451  * @z: (out):
3452  * @foo:
3453  * @q: (out):
3454  * @m:
3455  *
3456  */
3457 void
3458 regress_test_torture_signature_0 (int         x,
3459                           double     *y,
3460                           int        *z,
3461                           const char *foo,
3462                           int        *q,
3463                           guint       m)
3464 {
3465   *y = x;
3466   *z = x * 2;
3467   *q = g_utf8_strlen (foo, -1) + m;
3468 }
3469
3470 /**
3471  * regress_test_torture_signature_1:
3472  * @x:
3473  * @y: (out):
3474  * @z: (out):
3475  * @foo:
3476  * @q: (out):
3477  * @m:
3478  * @error: A #GError
3479  *
3480  * This function throws an error if m is odd.
3481  */
3482 gboolean
3483 regress_test_torture_signature_1 (int         x,
3484                           double     *y,
3485                           int        *z,
3486                           const char *foo,
3487                           int        *q,
3488                           guint       m,
3489                           GError    **error)
3490 {
3491   *y = x;
3492   *z = x * 2;
3493   *q = g_utf8_strlen (foo, -1) + m;
3494   if (m % 2 == 0)
3495       return TRUE;
3496   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "m is odd");
3497   return FALSE;
3498 }
3499
3500 /**
3501  * regress_test_torture_signature_2:
3502  * @x:
3503  * @callback:
3504  * @user_data:
3505  * @notify:
3506  * @y: (out):
3507  * @z: (out):
3508  * @foo:
3509  * @q: (out):
3510  * @m:
3511  *
3512  */
3513 void
3514 regress_test_torture_signature_2 (int                   x,
3515                           RegressTestCallbackUserData  callback,
3516                           gpointer              user_data,
3517                           GDestroyNotify        notify,
3518                           double               *y,
3519                           int                  *z,
3520                           const char           *foo,
3521                           int                  *q,
3522                           guint                 m)
3523 {
3524   *y = x;
3525   *z = x * 2;
3526   *q = g_utf8_strlen (foo, -1) + m;
3527   notify (user_data);
3528 }
3529
3530 /**
3531  * regress_test_date_in_gvalue:
3532  *
3533  * Returns: (transfer full):
3534  */
3535 GValue *
3536 regress_test_date_in_gvalue (void)
3537 {
3538   GValue *value = g_new0 (GValue, 1);
3539   GDate *date = g_date_new_dmy (5, 12, 1984);
3540
3541   g_value_init (value, G_TYPE_DATE);
3542   g_value_take_boxed (value, date);
3543
3544   return value;
3545 }
3546
3547 /**
3548  * regress_test_strv_in_gvalue:
3549  *
3550  * Returns: (transfer full):
3551  */
3552 GValue *
3553 regress_test_strv_in_gvalue (void)
3554 {
3555   GValue *value = g_new0 (GValue, 1);
3556   const char *strv[] = { "one", "two", "three", NULL };
3557
3558   g_value_init (value, G_TYPE_STRV);
3559   g_value_set_boxed (value, strv);
3560
3561   return value;
3562 }
3563
3564 /**
3565  * regress_test_multiline_doc_comments:
3566  *
3567  * This is a function.
3568  *
3569  * It has multiple lines in the documentation.
3570  *
3571  * The sky is blue.
3572  *
3573  * You will give me your credit card number.
3574  */
3575 void
3576 regress_test_multiline_doc_comments (void)
3577 {
3578 }
3579
3580 /**
3581  * regress_test_nested_parameter:
3582  * @a: An integer
3583  *
3584  * <informaltable>
3585  *   <tgroup cols="3">
3586  *     <thead>
3587  *       <row>
3588  *         <entry>Syntax</entry>
3589  *         <entry>Explanation</entry>
3590  *         <entry>Examples</entry>
3591  *       </row>
3592  *     </thead>
3593  *     <tbody>
3594  *       <row>
3595  *         <entry>rgb(@r, @g, @b)</entry>
3596  *         <entry>An opaque color; @r, @g, @b can be either integers between
3597  *                0 and 255 or percentages</entry>
3598  *         <entry><literallayout>rgb(128, 10, 54)
3599  * rgb(20%, 30%, 0%)</literallayout></entry>
3600  *       </row>
3601  *       <row>
3602  *         <entry>rgba(@r, @g, @b, @a)</entry>
3603  *         <entry>A translucent color; @r, @g, @b are as in the previous row,
3604  *                @a is a floating point number between 0 and 1</entry>
3605  *         <entry><literallayout>rgba(255, 255, 0, 0.5)</literallayout></entry>
3606  *       </row>
3607  *    </tbody>
3608  *  </tgroup>
3609  * </informaltable>
3610  *
3611  * What we're testing here is that the scanner ignores the @a nested inside XML.
3612  */
3613 void
3614 regress_test_nested_parameter (int a)
3615 {
3616 }
3617
3618 /**
3619  * regress_introspectable_via_alias:
3620  *
3621  */
3622 void
3623 regress_introspectable_via_alias (RegressPtrArrayAlias *data)
3624 {
3625 }
3626
3627 /**
3628  * regress_not_introspectable_via_alias:
3629  *
3630  */
3631 void
3632 regress_not_introspectable_via_alias (RegressVaListAlias ok)
3633 {
3634 }
3635
3636 /**
3637  * regress_aliased_caller_alloc:
3638  * @boxed: (out):
3639  */
3640 void regress_aliased_caller_alloc (RegressAliasedTestBoxed *boxed)
3641 {
3642   boxed->priv = g_slice_new0 (RegressTestBoxedPrivate);
3643   boxed->priv->magic = 0xdeadbeef;
3644 }
3645
3646 void
3647 regress_test_struct_fixed_array_frob (RegressTestStructFixedArray *str)
3648 {
3649   guint i;
3650   str->just_int = 7;
3651
3652   for (i = 0; i < G_N_ELEMENTS(str->array); i++)
3653     str->array[i] = 42 + i;
3654 }
3655
3656 /**
3657  * regress_has_parameter_named_attrs:
3658  * @foo: some int
3659  * @attributes: (type guint32) (array fixed-size=32): list of attributes
3660  *
3661  * This test case mirrors GnomeKeyringPasswordSchema from
3662  * libgnome-keyring.
3663  */
3664 void
3665 regress_has_parameter_named_attrs (int        foo,
3666                                    gpointer   attributes)
3667 {
3668 }