5254fa3458cdf2692329a12147aa281e01a63c65
[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   return hash;
1269 }
1270
1271 /**
1272  * regress_test_ghash_gvalue_in:
1273  * @hash: (element-type utf8 GValue): the hash table returned by
1274  * regress_test_ghash_gvalue_return().
1275  */
1276 void
1277 regress_test_ghash_gvalue_in (GHashTable *hash)
1278 {
1279   GValue *value;
1280   const gchar **strings;
1281   int i;
1282
1283   g_assert(hash != NULL);
1284
1285   value = g_hash_table_lookup(hash, "integer");
1286   g_assert(value != NULL);
1287   g_assert(G_VALUE_HOLDS_INT(value));
1288   g_assert(g_value_get_int(value) == 12);
1289
1290   value = g_hash_table_lookup(hash, "boolean");
1291   g_assert(value != NULL);
1292   g_assert(G_VALUE_HOLDS_BOOLEAN(value));
1293   g_assert(g_value_get_boolean(value) == TRUE);
1294
1295   value = g_hash_table_lookup(hash, "string");
1296   g_assert(value != NULL);
1297   g_assert(G_VALUE_HOLDS_STRING(value));
1298   g_assert(strcmp(g_value_get_string(value), "some text") == 0);
1299
1300   value = g_hash_table_lookup(hash, "strings");
1301   g_assert(value != NULL);
1302   g_assert(G_VALUE_HOLDS(value, G_TYPE_STRV));
1303   strings = g_value_get_boxed(value);
1304   g_assert(strings != NULL);
1305   for (i = 0; string_array[i] != NULL; i++)
1306     g_assert(strcmp(strings[i], string_array[i]) == 0);
1307 }
1308
1309 /**
1310  * regress_test_ghash_container_return:
1311  *
1312  * Return value: (element-type utf8 utf8) (transfer container):
1313  */
1314 GHashTable *
1315 regress_test_ghash_container_return (void)
1316 {
1317   return regress_test_table_ghash_new_container ();
1318 }
1319
1320 /**
1321  * regress_test_ghash_everything_return:
1322  *
1323  * Return value: (element-type utf8 utf8) (transfer full):
1324  */
1325 GHashTable *
1326 regress_test_ghash_everything_return (void)
1327 {
1328   return regress_test_table_ghash_new_full ();
1329 }
1330
1331 static void
1332 assert_test_table_ghash (const GHashTable *in)
1333 {
1334   GHashTable *h = regress_test_table_ghash_const();
1335   GHashTableIter iter;
1336   gpointer key, value;
1337
1338   g_assert(g_hash_table_size(h) ==
1339            g_hash_table_size((GHashTable*)in));
1340
1341   g_hash_table_iter_init(&iter, (GHashTable*)in);
1342   while (g_hash_table_iter_next (&iter, &key, &value))
1343     g_assert( strcmp(g_hash_table_lookup(h, (char*)key), (char*)value) == 0);
1344 }
1345
1346 /**
1347  * regress_test_ghash_null_in:
1348  * @in: (element-type utf8 utf8) (allow-none):
1349  */
1350 void
1351 regress_test_ghash_null_in (const GHashTable *in)
1352 {
1353   g_assert (in == NULL);
1354 }
1355
1356 /**
1357  * regress_test_ghash_null_out:
1358  * @out: (element-type utf8 utf8) (allow-none) (out):
1359  */
1360 void
1361 regress_test_ghash_null_out (const GHashTable **out)
1362 {
1363   *out = NULL;
1364 }
1365
1366 /**
1367  * regress_test_ghash_nothing_in:
1368  * @in: (element-type utf8 utf8):
1369  */
1370 void
1371 regress_test_ghash_nothing_in (const GHashTable *in)
1372 {
1373   assert_test_table_ghash (in);
1374 }
1375
1376 /**
1377  * regress_test_ghash_nothing_in2:
1378  * @in: (element-type utf8 utf8):
1379  */
1380 void
1381 regress_test_ghash_nothing_in2 (GHashTable *in)
1382 {
1383   assert_test_table_ghash (in);
1384 }
1385
1386 /* Nested collection types */
1387
1388 /**
1389  * regress_test_ghash_nested_everything_return:
1390  *
1391  * Specify nested parameterized types directly with the (type ) annotation.
1392  *
1393  * Return value: (type GLib.HashTable<utf8,GLib.HashTable<utf8,utf8>>) (transfer full):
1394  */
1395 GHashTable *
1396 regress_test_ghash_nested_everything_return (void)
1397 {
1398   GHashTable *hash;
1399   hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1400                                (void (*) (gpointer)) g_hash_table_destroy);
1401   g_hash_table_insert(hash, g_strdup("wibble"), regress_test_table_ghash_new_full());
1402   return hash;
1403 }
1404
1405 /**
1406  * regress_test_ghash_nested_everything_return2:
1407  *
1408  * Another way of specifying nested parameterized types: using the
1409  * element-type annotation.
1410  *
1411  * Return value: (element-type utf8 GLib.HashTable<utf8,utf8>) (transfer full):
1412  */
1413 GHashTable *
1414 regress_test_ghash_nested_everything_return2 (void)
1415 {
1416   return regress_test_ghash_nested_everything_return();
1417 }
1418
1419 /************************************************************************/
1420
1421 /**
1422  * regress_test_garray_container_return:
1423  *
1424  * Returns: (transfer container) (type GLib.PtrArray) (element-type utf8):
1425  */
1426 GPtrArray *
1427 regress_test_garray_container_return (void)
1428 {
1429   GPtrArray *array;
1430
1431   array = g_ptr_array_new_with_free_func (g_free);
1432   g_ptr_array_add (array, g_strdup ("regress"));
1433
1434   return array;
1435 }
1436
1437 /**
1438  * regress_test_garray_full_return:
1439  *
1440  * Returns: (transfer full) (type GLib.PtrArray) (element-type utf8):
1441  */
1442 GPtrArray *
1443 regress_test_garray_full_return (void)
1444 {
1445   GPtrArray *array;
1446
1447   array = g_ptr_array_new ();
1448   g_ptr_array_add (array, g_strdup ("regress"));
1449
1450   return array;
1451 }
1452
1453 /************************************************************************/
1454
1455 /* error? */
1456
1457 /* enums / flags */
1458
1459 /**
1460  * NUM_REGRESS_FOO: (skip)
1461  *
1462  * num of elements in RegressFoo
1463  */
1464
1465 GType
1466 regress_test_enum_get_type (void)
1467 {
1468     static GType etype = 0;
1469     if (G_UNLIKELY(etype == 0)) {
1470         static const GEnumValue values[] = {
1471             { REGRESS_TEST_VALUE1, "REGRESS_TEST_VALUE1", "value1" },
1472             { REGRESS_TEST_VALUE2, "REGRESS_TEST_VALUE2", "value2" },
1473             { REGRESS_TEST_VALUE3, "REGRESS_TEST_VALUE3", "value3" },
1474             { REGRESS_TEST_VALUE4, "REGRESS_TEST_VALUE4", "value4" },
1475             { 0, NULL, NULL }
1476         };
1477         etype = g_enum_register_static (g_intern_static_string ("RegressTestEnum"), values);
1478     }
1479
1480     return etype;
1481 }
1482
1483 GType
1484 regress_test_enum_unsigned_get_type (void)
1485 {
1486     static GType etype = 0;
1487     if (G_UNLIKELY(etype == 0)) {
1488         static const GEnumValue values[] = {
1489             { REGRESS_TEST_UNSIGNED_VALUE1, "REGRESS_TEST_UNSIGNED_VALUE1", "value1" },
1490             { REGRESS_TEST_UNSIGNED_VALUE2, "REGRESS_TEST_UNSIGNED_VALUE2", "value2" },
1491             { 0, NULL, NULL }
1492         };
1493         etype = g_enum_register_static (g_intern_static_string ("RegressTestEnumUnsigned"), values);
1494     }
1495
1496     return etype;
1497 }
1498
1499 GType
1500 regress_test_flags_get_type (void)
1501 {
1502     static GType etype = 0;
1503     if (G_UNLIKELY(etype == 0)) {
1504         static const GFlagsValue values[] = {
1505             { REGRESS_TEST_FLAG1, "TEST_FLAG1", "flag1" },
1506             { REGRESS_TEST_FLAG2, "TEST_FLAG2", "flag2" },
1507             { REGRESS_TEST_FLAG3, "TEST_FLAG3", "flag3" },
1508             { 0, NULL, NULL }
1509         };
1510         etype = g_flags_register_static (g_intern_static_string ("RegressTestFlags"), values);
1511     }
1512
1513     return etype;
1514 }
1515
1516 const gchar *
1517 regress_test_enum_param(RegressTestEnum e)
1518 {
1519   GEnumValue *ev;
1520   GEnumClass *ec;
1521
1522   ec = g_type_class_ref (regress_test_enum_get_type ());
1523   ev = g_enum_get_value (ec, e);
1524   g_type_class_unref (ec);
1525
1526   return ev->value_nick;
1527 }
1528
1529 const gchar *
1530 regress_test_unsigned_enum_param(RegressTestEnumUnsigned e)
1531 {
1532   GEnumValue *ev;
1533   GEnumClass *ec;
1534
1535   ec = g_type_class_ref (regress_test_enum_unsigned_get_type ());
1536   ev = g_enum_get_value (ec, e);
1537   g_type_class_unref (ec);
1538
1539   return ev->value_nick;
1540 }
1541
1542 /**
1543  * regress_global_get_flags_out:
1544  * @v: (out): A flags value
1545  *
1546  */
1547 void
1548 regress_global_get_flags_out (RegressTestFlags *v)
1549 {
1550   *v = REGRESS_TEST_FLAG1 | REGRESS_TEST_FLAG3;
1551 }
1552
1553 /* structures */
1554
1555 /**
1556  * regress_test_struct_a_clone:
1557  * @a: the structure
1558  * @a_out: (out caller-allocates): the cloned structure
1559  *
1560  * Make a copy of a RegressTestStructA
1561  */
1562 void
1563 regress_test_struct_a_clone (RegressTestStructA *a,
1564                      RegressTestStructA *a_out)
1565 {
1566   *a_out = *a;
1567 }
1568
1569 /**
1570  * regress_test_struct_b_clone:
1571  * @b: the structure
1572  * @b_out: (out): the cloned structure
1573  *
1574  * Make a copy of a RegressTestStructB
1575  */
1576 void
1577 regress_test_struct_b_clone (RegressTestStructB *b,
1578                      RegressTestStructB *b_out)
1579 {
1580   *b_out = *b;
1581 }
1582
1583 /* plain-old-data boxed types */
1584
1585 RegressTestSimpleBoxedA *
1586 regress_test_simple_boxed_a_copy (RegressTestSimpleBoxedA *a)
1587 {
1588   RegressTestSimpleBoxedA *new_a = g_slice_new (RegressTestSimpleBoxedA);
1589
1590   *new_a = *a;
1591
1592   return new_a;
1593 }
1594
1595 static void
1596 regress_test_simple_boxed_a_free (RegressTestSimpleBoxedA *a)
1597 {
1598   g_slice_free (RegressTestSimpleBoxedA, a);
1599 }
1600
1601 GType
1602 regress_test_simple_boxed_a_get_gtype (void)
1603 {
1604   static GType our_type = 0;
1605
1606   if (our_type == 0)
1607     our_type = g_boxed_type_register_static (g_intern_static_string ("RegressTestSimpleBoxedA"),
1608                                              (GBoxedCopyFunc)regress_test_simple_boxed_a_copy,
1609                                              (GBoxedFreeFunc)regress_test_simple_boxed_a_free);
1610   return our_type;
1611 }
1612
1613 RegressTestSimpleBoxedB *
1614 regress_test_simple_boxed_b_copy (RegressTestSimpleBoxedB *b)
1615 {
1616   RegressTestSimpleBoxedB *new_b = g_slice_new (RegressTestSimpleBoxedB);
1617
1618   *new_b = *b;
1619
1620   return new_b;
1621 }
1622
1623 gboolean
1624 regress_test_simple_boxed_a_equals (RegressTestSimpleBoxedA *a,
1625                             RegressTestSimpleBoxedA *other_a)
1626 {
1627   return (a->some_int == other_a->some_int &&
1628           a->some_int8 == other_a->some_int8 &&
1629           a->some_double == other_a->some_double);
1630 }
1631
1632 const RegressTestSimpleBoxedA*
1633 regress_test_simple_boxed_a_const_return (void)
1634 {
1635   static RegressTestSimpleBoxedA simple_a = {
1636     5, 6, 7.0
1637   };
1638
1639   return &simple_a;
1640 }
1641
1642 static void
1643 regress_test_simple_boxed_b_free (RegressTestSimpleBoxedB *a)
1644 {
1645   g_slice_free (RegressTestSimpleBoxedB, a);
1646 }
1647
1648 GType
1649 regress_test_simple_boxed_b_get_type (void)
1650 {
1651   static GType our_type = 0;
1652
1653   if (our_type == 0)
1654     our_type = g_boxed_type_register_static (g_intern_static_string ("RegressTestSimpleBoxedB"),
1655                                              (GBoxedCopyFunc)regress_test_simple_boxed_b_copy,
1656                                              (GBoxedFreeFunc)regress_test_simple_boxed_b_free);
1657   return our_type;
1658 }
1659
1660 /* opaque boxed */
1661
1662 struct _RegressTestBoxedPrivate
1663 {
1664   guint magic;
1665 };
1666
1667 /**
1668  * regress_test_boxed_new:
1669  *
1670  * Returns: (transfer full):
1671  */
1672 RegressTestBoxed *
1673 regress_test_boxed_new (void)
1674 {
1675   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1676   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1677   boxed->priv->magic = 0xdeadbeef;
1678
1679   return boxed;
1680 }
1681
1682 /**
1683  * regress_test_boxed_new_alternative_constructor1:
1684  *
1685  * Returns: (transfer full):
1686  */
1687 RegressTestBoxed *
1688 regress_test_boxed_new_alternative_constructor1 (int i)
1689 {
1690   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1691   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1692   boxed->priv->magic = 0xdeadbeef;
1693   boxed->some_int8 = i;
1694
1695   return boxed;
1696 }
1697
1698 /**
1699  * regress_test_boxed_new_alternative_constructor2:
1700  *
1701  * Returns: (transfer full):
1702  */
1703 RegressTestBoxed *
1704 regress_test_boxed_new_alternative_constructor2 (int i, int j)
1705 {
1706   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1707   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1708   boxed->priv->magic = 0xdeadbeef;
1709   boxed->some_int8 = i + j;
1710
1711   return boxed;
1712 }
1713
1714 /**
1715  * regress_test_boxed_new_alternative_constructor3:
1716  *
1717  * Returns: (transfer full):
1718  */
1719 RegressTestBoxed *
1720 regress_test_boxed_new_alternative_constructor3 (char *s)
1721 {
1722   RegressTestBoxed *boxed = g_slice_new0(RegressTestBoxed);
1723   boxed->priv = g_slice_new0(RegressTestBoxedPrivate);
1724   boxed->priv->magic = 0xdeadbeef;
1725   boxed->some_int8 = atoi(s);
1726
1727   return boxed;
1728 }
1729
1730 /**
1731  * regress_test_boxed_copy:
1732  *
1733  * Returns: (transfer full):
1734  */
1735 RegressTestBoxed *
1736 regress_test_boxed_copy (RegressTestBoxed *boxed)
1737 {
1738   RegressTestBoxed *new_boxed = regress_test_boxed_new();
1739   RegressTestBoxedPrivate *save;
1740
1741   save = new_boxed->priv;
1742   *new_boxed = *boxed;
1743   new_boxed->priv = save;
1744
1745   return new_boxed;
1746 }
1747
1748 gboolean
1749 regress_test_boxed_equals (RegressTestBoxed *boxed,
1750                    RegressTestBoxed *other)
1751 {
1752   return (other->some_int8 == boxed->some_int8 &&
1753           regress_test_simple_boxed_a_equals(&other->nested_a, &boxed->nested_a));
1754 }
1755
1756 static void
1757 regress_test_boxed_free (RegressTestBoxed *boxed)
1758 {
1759   g_assert (boxed->priv->magic == 0xdeadbeef);
1760
1761   g_slice_free (RegressTestBoxedPrivate, boxed->priv);
1762   g_slice_free (RegressTestBoxed, boxed);
1763 }
1764
1765 GType
1766 regress_test_boxed_get_type (void)
1767 {
1768   static GType our_type = 0;
1769
1770   if (our_type == 0)
1771     our_type = g_boxed_type_register_static (g_intern_static_string ("RegressTestBoxed"),
1772                                              (GBoxedCopyFunc)regress_test_boxed_copy,
1773                                              (GBoxedFreeFunc)regress_test_boxed_free);
1774   return our_type;
1775 }
1776
1777 RegressTestBoxedB *
1778 regress_test_boxed_b_new (gint8 some_int8, glong some_long)
1779 {
1780   RegressTestBoxedB *boxed;
1781
1782   boxed = g_slice_new (RegressTestBoxedB);
1783   boxed->some_int8 = some_int8;
1784   boxed->some_long = some_long;
1785
1786   return boxed;
1787 }
1788
1789 RegressTestBoxedB *
1790 regress_test_boxed_b_copy (RegressTestBoxedB *boxed)
1791 {
1792   return regress_test_boxed_b_new (boxed->some_int8, boxed->some_long);
1793 }
1794
1795 static void
1796 regress_test_boxed_b_free (RegressTestBoxedB *boxed)
1797 {
1798   g_slice_free (RegressTestBoxedB, boxed);
1799 }
1800
1801 G_DEFINE_BOXED_TYPE(RegressTestBoxedB,
1802                     regress_test_boxed_b,
1803                     regress_test_boxed_b_copy,
1804                     regress_test_boxed_b_free);
1805
1806 G_DEFINE_TYPE(RegressTestObj, regress_test_obj, G_TYPE_OBJECT);
1807
1808 enum
1809 {
1810   PROP_TEST_OBJ_BARE = 1,
1811   PROP_TEST_OBJ_BOXED,
1812   PROP_TEST_OBJ_HASH_TABLE,
1813   PROP_TEST_OBJ_LIST,
1814   PROP_TEST_OBJ_HASH_TABLE_OLD,
1815   PROP_TEST_OBJ_LIST_OLD,
1816   PROP_TEST_OBJ_INT,
1817   PROP_TEST_OBJ_FLOAT,
1818   PROP_TEST_OBJ_DOUBLE,
1819   PROP_TEST_OBJ_STRING,
1820   PROP_TEST_OBJ_GTYPE
1821 };
1822
1823 static void
1824 regress_test_obj_set_property (GObject      *object,
1825                        guint         property_id,
1826                        const GValue *value,
1827                        GParamSpec   *pspec)
1828 {
1829   RegressTestObj *self = REGRESS_TEST_OBJECT (object);
1830   GList *list;
1831
1832   switch (property_id)
1833     {
1834     case PROP_TEST_OBJ_BARE:
1835       regress_test_obj_set_bare (self, g_value_get_object (value));
1836       break;
1837
1838     case PROP_TEST_OBJ_BOXED:
1839       if (self->boxed)
1840         regress_test_boxed_free (self->boxed);
1841       self->boxed = g_value_dup_boxed (value);
1842       break;
1843
1844     case PROP_TEST_OBJ_HASH_TABLE:
1845     case PROP_TEST_OBJ_HASH_TABLE_OLD:
1846       if (self->hash_table)
1847         g_hash_table_unref (self->hash_table);
1848       self->hash_table = g_hash_table_ref (g_value_get_boxed (value));
1849       break;
1850
1851     case PROP_TEST_OBJ_LIST:
1852     case PROP_TEST_OBJ_LIST_OLD:
1853       if (self->list != NULL)
1854         {
1855           for (list = self->list; list != NULL; list = g_list_next (list))
1856             g_free (list->data);
1857           g_list_free (self->list);
1858         }
1859       self->list = NULL;
1860       for (list = g_value_get_pointer (value); list != NULL; list = g_list_next (list))
1861         self->list = g_list_append (self->list, g_strdup (list->data));
1862       break;
1863
1864     case PROP_TEST_OBJ_INT:
1865       self->some_int8 = g_value_get_int (value);
1866       break;
1867
1868     case PROP_TEST_OBJ_FLOAT:
1869       self->some_float = g_value_get_float (value);
1870       break;
1871
1872     case PROP_TEST_OBJ_DOUBLE:
1873       self->some_double = g_value_get_double (value);
1874       break;
1875
1876     case PROP_TEST_OBJ_STRING:
1877       self->string = g_value_dup_string (value);
1878       break;
1879
1880     case PROP_TEST_OBJ_GTYPE:
1881       self->gtype = g_value_get_gtype (value);
1882       break;
1883
1884     default:
1885       /* We don't have any other property... */
1886       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1887       break;
1888     }
1889 }
1890
1891 static void
1892 regress_test_obj_get_property (GObject    *object,
1893                         guint       property_id,
1894                         GValue     *value,
1895                         GParamSpec *pspec)
1896 {
1897   RegressTestObj *self = REGRESS_TEST_OBJECT (object);
1898
1899   switch (property_id)
1900     {
1901     case PROP_TEST_OBJ_BARE:
1902       g_value_set_object (value, self->bare);
1903       break;
1904
1905     case PROP_TEST_OBJ_BOXED:
1906       g_value_set_boxed (value, self->boxed);
1907       break;
1908
1909     case PROP_TEST_OBJ_HASH_TABLE:
1910     case PROP_TEST_OBJ_HASH_TABLE_OLD:
1911       if (self->hash_table != NULL)
1912         g_hash_table_ref (self->hash_table);
1913       g_value_set_boxed (value, self->hash_table);
1914       break;
1915
1916     case PROP_TEST_OBJ_LIST:
1917     case PROP_TEST_OBJ_LIST_OLD:
1918       g_value_set_pointer (value, self->list);
1919       break;
1920
1921     case PROP_TEST_OBJ_INT:
1922       g_value_set_int (value, self->some_int8);
1923       break;
1924
1925     case PROP_TEST_OBJ_FLOAT:
1926       g_value_set_float (value, self->some_float);
1927       break;
1928
1929     case PROP_TEST_OBJ_DOUBLE:
1930       g_value_set_double (value, self->some_double);
1931       break;
1932
1933     case PROP_TEST_OBJ_STRING:
1934       g_value_set_string (value, self->string);
1935       break;
1936
1937     case PROP_TEST_OBJ_GTYPE:
1938       g_value_set_gtype (value, self->gtype);
1939       break;
1940
1941     default:
1942       /* We don't have any other property... */
1943       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1944       break;
1945     }
1946 }
1947
1948 static void
1949 regress_test_obj_dispose (GObject *gobject)
1950 {
1951   RegressTestObj *self = REGRESS_TEST_OBJECT (gobject);
1952
1953   if (self->bare)
1954     {
1955       g_object_unref (self->bare);
1956
1957       self->bare = NULL;
1958     }
1959
1960   if (self->boxed)
1961     {
1962       regress_test_boxed_free (self->boxed);
1963       self->boxed = NULL;
1964     }
1965
1966   /* Chain up to the parent class */
1967   G_OBJECT_CLASS (regress_test_obj_parent_class)->dispose (gobject);
1968 }
1969
1970 static int
1971 regress_test_obj_default_matrix (RegressTestObj *obj, const char *somestr)
1972 {
1973   return 42;
1974 }
1975
1976 enum {
1977   REGRESS_TEST_OBJ_SIGNAL_SIG_NEW_WITH_ARRAY_PROP,
1978   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_HASH_PROP,
1979   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_STRV,
1980   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_OBJ,
1981   REGRESS_TEST_OBJ_SIGNAL_FIRST,
1982   REGRESS_TEST_OBJ_SIGNAL_CLEANUP,
1983   REGRESS_TEST_OBJ_SIGNAL_ALL,
1984   N_REGRESS_TEST_OBJ_SIGNALS
1985 };
1986
1987 static guint regress_test_obj_signals[N_REGRESS_TEST_OBJ_SIGNALS] = { 0 };
1988
1989 static void
1990 regress_test_obj_class_init (RegressTestObjClass *klass)
1991 {
1992   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1993   GParamSpec *pspec;
1994   GType param_types[1];
1995
1996   klass->test_signal =
1997     g_signal_newv ("test",
1998                    G_TYPE_FROM_CLASS (gobject_class),
1999                    G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
2000                    NULL /* closure */,
2001                    NULL /* accumulator */,
2002                    NULL /* accumulator data */,
2003                    g_cclosure_marshal_VOID__VOID,
2004                    G_TYPE_NONE /* return_type */,
2005                    0     /* n_params */,
2006                    NULL  /* param_types */);
2007
2008   param_types[0] = regress_test_simple_boxed_a_get_gtype() | G_SIGNAL_TYPE_STATIC_SCOPE;
2009   klass->test_signal_with_static_scope_arg =
2010     g_signal_newv ("test-with-static-scope-arg",
2011                    G_TYPE_FROM_CLASS (gobject_class),
2012                    G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
2013                    NULL /* closure */,
2014                    NULL /* accumulator */,
2015                    NULL /* accumulator data */,
2016                    g_cclosure_marshal_VOID__BOXED,
2017                    G_TYPE_NONE /* return_type */,
2018                    1     /* n_params */,
2019                    param_types);
2020
2021   /**
2022    * RegressTestObj::sig-with-array-prop:
2023    * @self: an object
2024    * @arr: (type GArray) (element-type uint): numbers
2025    *
2026    * This test signal is like TelepathyGlib's
2027    *  TpChannel:: group-members-changed-detailed:
2028    */
2029   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_NEW_WITH_ARRAY_PROP] =
2030     g_signal_new ("sig-with-array-prop",
2031                   G_TYPE_FROM_CLASS (gobject_class),
2032                   G_SIGNAL_RUN_LAST,
2033                   0,
2034                   NULL,
2035                   NULL,
2036                   g_cclosure_marshal_VOID__BOXED,
2037                   G_TYPE_NONE,
2038                   1,
2039                   G_TYPE_ARRAY);
2040
2041   /**
2042    * RegressTestObj::sig-with-hash-prop:
2043    * @self: an object
2044    * @hash: (element-type utf8 GObject.Value):
2045    *
2046    * This test signal is like TelepathyGlib's
2047    *  TpAccount::status-changed
2048    */
2049   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_HASH_PROP] =
2050     g_signal_new ("sig-with-hash-prop",
2051                   G_TYPE_FROM_CLASS (gobject_class),
2052                   G_SIGNAL_RUN_LAST,
2053                   0,
2054                   NULL,
2055                   NULL,
2056                   g_cclosure_marshal_VOID__BOXED,
2057                   G_TYPE_NONE,
2058                   1,
2059                   G_TYPE_HASH_TABLE);
2060
2061   /**
2062    * RegressTestObj::sig-with-strv:
2063    * @self: an object
2064    * @strs: strings
2065    *
2066    * Test GStrv as a param.
2067    */
2068   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_STRV] =
2069     g_signal_new ("sig-with-strv",
2070                   G_TYPE_FROM_CLASS (gobject_class),
2071                   G_SIGNAL_RUN_LAST,
2072                   0,
2073                   NULL,
2074                   NULL,
2075                   g_cclosure_marshal_VOID__BOXED,
2076                   G_TYPE_NONE,
2077                   1,
2078                   G_TYPE_STRV);
2079
2080    /**
2081    * RegressTestObj::sig-with-obj:
2082    * @self: an object
2083    * @obj: (transfer none): A newly created RegressTestObj
2084    *
2085    * Test transfer none GObject as a param (tests refcounting).
2086    * Use with regress_test_obj_emit_sig_with_obj
2087    */
2088   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_OBJ] =
2089     g_signal_new ("sig-with-obj",
2090                   G_TYPE_FROM_CLASS (gobject_class),
2091                   G_SIGNAL_RUN_LAST,
2092                   0,
2093                   NULL,
2094                   NULL,
2095                   g_cclosure_marshal_VOID__OBJECT,
2096                   G_TYPE_NONE,
2097                   1,
2098                   G_TYPE_OBJECT);
2099
2100   regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_FIRST] =
2101     g_signal_new ("first",
2102                   G_TYPE_FROM_CLASS (gobject_class),
2103                   G_SIGNAL_RUN_FIRST,
2104                   0,
2105                   NULL,
2106                   NULL,
2107                   g_cclosure_marshal_VOID__VOID,
2108                   G_TYPE_NONE,
2109                   0);
2110
2111     regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_CLEANUP] =
2112     g_signal_new ("cleanup",
2113                   G_TYPE_FROM_CLASS (gobject_class),
2114                   G_SIGNAL_RUN_CLEANUP,
2115                   0,
2116                   NULL,
2117                   NULL,
2118                   g_cclosure_marshal_VOID__VOID,
2119                   G_TYPE_NONE,
2120                   0);
2121
2122     regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_ALL] =
2123     g_signal_new ("all",
2124                   G_TYPE_FROM_CLASS (gobject_class),
2125                   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_ACTION | G_SIGNAL_NO_HOOKS,
2126                   0,
2127                   NULL,
2128                   NULL,
2129                   g_cclosure_marshal_VOID__VOID,
2130                   G_TYPE_NONE,
2131                   0);
2132
2133   gobject_class->set_property = regress_test_obj_set_property;
2134   gobject_class->get_property = regress_test_obj_get_property;
2135   gobject_class->dispose = regress_test_obj_dispose;
2136
2137   pspec = g_param_spec_object ("bare",
2138                                "Bare property",
2139                                "A contained object",
2140                                G_TYPE_OBJECT,
2141                                G_PARAM_READWRITE);
2142   g_object_class_install_property (gobject_class,
2143                                    PROP_TEST_OBJ_BARE,
2144                                    pspec);
2145
2146   pspec = g_param_spec_boxed ("boxed",
2147                               "Boxed property",
2148                               "A contained boxed struct",
2149                               REGRESS_TEST_TYPE_BOXED,
2150                               G_PARAM_READWRITE);
2151   g_object_class_install_property (gobject_class,
2152                                    PROP_TEST_OBJ_BOXED,
2153                                    pspec);
2154
2155   /**
2156    * RegressTestObj:hash-table:
2157    *
2158    * Type: GLib.HashTable(utf8,gint8)
2159    * Transfer: container
2160    */
2161   pspec = g_param_spec_boxed ("hash-table",
2162                               "GHashTable property",
2163                               "A contained GHashTable",
2164                               G_TYPE_HASH_TABLE,
2165                               G_PARAM_READWRITE);
2166   g_object_class_install_property (gobject_class,
2167                                    PROP_TEST_OBJ_HASH_TABLE,
2168                                    pspec);
2169
2170   /**
2171    * RegressTestObj:list:
2172    *
2173    * Type: GLib.List(utf8)
2174    * Transfer: none
2175    */
2176   pspec = g_param_spec_pointer ("list",
2177                                 "GList property",
2178                                 "A contained GList",
2179                                 G_PARAM_READWRITE);
2180   g_object_class_install_property (gobject_class,
2181                                    PROP_TEST_OBJ_LIST,
2182                                    pspec);
2183
2184   /**
2185    * RegressTestObj:hash-table-old:
2186    *
2187    * Type: GLib.HashTable<utf8,gint8>
2188    * Transfer: container
2189    */
2190   pspec = g_param_spec_boxed ("hash-table-old",
2191                               "GHashTable property with <>",
2192                               "A contained GHashTable with <>",
2193                               G_TYPE_HASH_TABLE,
2194                               G_PARAM_READWRITE);
2195   g_object_class_install_property (gobject_class,
2196                                    PROP_TEST_OBJ_HASH_TABLE_OLD,
2197                                    pspec);
2198
2199   /**
2200    * RegressTestObj:list-old:
2201    *
2202    * Type: GLib.List<utf8>
2203    * Transfer: none
2204    */
2205   pspec = g_param_spec_pointer ("list-old",
2206                                 "GList property with ()",
2207                                 "A contained GList with <>",
2208                                 G_PARAM_READWRITE);
2209   g_object_class_install_property (gobject_class,
2210                                    PROP_TEST_OBJ_LIST_OLD,
2211                                    pspec);
2212
2213
2214
2215   /**
2216    * TestObj:int:
2217    */
2218   pspec = g_param_spec_int ("int",
2219                             "int property",
2220                             "A contained int",
2221                             G_MININT,
2222                             G_MAXINT,
2223                             0,
2224                             G_PARAM_READWRITE);
2225   g_object_class_install_property (gobject_class,
2226                                    PROP_TEST_OBJ_INT,
2227                                    pspec);
2228
2229   /**
2230    * TestObj:float:
2231    */
2232   pspec = g_param_spec_float ("float",
2233                               "float property",
2234                               "A contained float",
2235                               G_MINFLOAT,
2236                               G_MAXFLOAT,
2237                               1.0f,
2238                               G_PARAM_READWRITE);
2239   g_object_class_install_property (gobject_class,
2240                                    PROP_TEST_OBJ_FLOAT,
2241                                    pspec);
2242
2243   /**
2244    * TestObj:double:
2245    */
2246   pspec = g_param_spec_double ("double",
2247                                "double property",
2248                                "A contained double",
2249                                G_MINDOUBLE,
2250                                G_MAXDOUBLE,
2251                                1.0f,
2252                                G_PARAM_READWRITE);
2253   g_object_class_install_property (gobject_class,
2254                                    PROP_TEST_OBJ_DOUBLE,
2255                                    pspec);
2256
2257   /**
2258    * TestObj:string:
2259    */
2260   pspec = g_param_spec_string ("string",
2261                                "string property",
2262                                "A contained string",
2263                                NULL,
2264                                G_PARAM_READWRITE);
2265   g_object_class_install_property (gobject_class,
2266                                    PROP_TEST_OBJ_STRING,
2267                                    pspec);
2268
2269
2270   /**
2271    * TestObj:gtype:
2272    */
2273   pspec = g_param_spec_gtype ("gtype",
2274                               "GType property",
2275                               "A GType property",
2276                               G_TYPE_NONE,
2277                               G_PARAM_READWRITE);
2278   g_object_class_install_property (gobject_class,
2279                                    PROP_TEST_OBJ_GTYPE,
2280                                    pspec);
2281
2282   klass->matrix = regress_test_obj_default_matrix;
2283 }
2284
2285 static void
2286 regress_test_obj_init (RegressTestObj *obj)
2287 {
2288   obj->bare = NULL;
2289   obj->boxed = NULL;
2290   obj->hash_table = NULL;
2291   obj->gtype = G_TYPE_INVALID;
2292 }
2293
2294 /**
2295  * regress_test_obj_new: (constructor)
2296  * @obj: A #RegressTestObj
2297  */
2298 RegressTestObj *
2299 regress_test_obj_new (RegressTestObj *obj)
2300 {
2301   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
2302 }
2303
2304 /**
2305  * regress_constructor: (constructor)
2306  *
2307  */
2308 RegressTestObj *
2309 regress_constructor (void)
2310 {
2311   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
2312 }
2313
2314 /**
2315  * regress_test_obj_new_from_file:
2316  */
2317 RegressTestObj *
2318 regress_test_obj_new_from_file (const char *x, GError **error)
2319 {
2320   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
2321 }
2322
2323 /**
2324  * regress_test_obj_set_bare:
2325  * @bare: (allow-none):
2326  */
2327 void
2328 regress_test_obj_set_bare (RegressTestObj *obj, GObject *bare)
2329 {
2330   if (obj->bare)
2331     g_object_unref (obj->bare);
2332   obj->bare = bare;
2333   if (obj->bare)
2334     g_object_ref (obj->bare);
2335 }
2336
2337 void
2338 regress_test_obj_emit_sig_with_obj (RegressTestObj *obj)
2339 {
2340     RegressTestObj *obj_param = regress_constructor ();
2341     g_object_set (obj_param, "int", 3, NULL);
2342     g_signal_emit_by_name (obj, "sig-with-obj", obj_param);
2343     g_object_unref (obj_param);
2344 }
2345
2346 int
2347 regress_test_obj_instance_method (RegressTestObj *obj)
2348 {
2349     return -1;
2350 }
2351
2352 double
2353 regress_test_obj_static_method (int x)
2354 {
2355   return x;
2356 }
2357
2358 /**
2359  * regress_forced_method: (method)
2360  * @obj: A #RegressTestObj
2361  *
2362  */
2363 void
2364 regress_forced_method (RegressTestObj *obj)
2365 {
2366 }
2367
2368 /**
2369  * regress_test_obj_torture_signature_0:
2370  * @obj: A #RegressTestObj
2371  * @x:
2372  * @y: (out):
2373  * @z: (out):
2374  * @foo:
2375  * @q: (out):
2376  * @m:
2377  *
2378  */
2379 void
2380 regress_test_obj_torture_signature_0 (RegressTestObj    *obj,
2381                               int         x,
2382                               double     *y,
2383                               int        *z,
2384                               const char *foo,
2385                               int        *q,
2386                               guint       m)
2387 {
2388   *y = x;
2389   *z = x * 2;
2390   *q = g_utf8_strlen (foo, -1) + m;
2391 }
2392
2393 /**
2394  * regress_test_obj_torture_signature_1:
2395  * @obj: A #RegressTestObj
2396  * @x:
2397  * @y: (out):
2398  * @z: (out):
2399  * @foo:
2400  * @q: (out):
2401  * @m:
2402  * @error: A #GError
2403  *
2404  * This function throws an error if m is odd.
2405  */
2406 gboolean
2407 regress_test_obj_torture_signature_1 (RegressTestObj   *obj,
2408                               int        x,
2409                               double     *y,
2410                               int        *z,
2411                               const char *foo,
2412                               int        *q,
2413                               guint       m,
2414                               GError    **error)
2415 {
2416   *y = x;
2417   *z = x * 2;
2418   *q = g_utf8_strlen (foo, -1) + m;
2419   if (m % 2 == 0)
2420       return TRUE;
2421   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "m is odd");
2422   return FALSE;
2423 }
2424
2425 /**
2426  * regress_test_obj_skip_return_val:
2427  * @obj: a #RegressTestObj
2428  * @a: Parameter.
2429  * @out_b: (out): A return value.
2430  * @c: Other parameter.
2431  * @inout_d: (inout): Will be incremented.
2432  * @out_sum: (out): Return value.
2433  * @num1: Number.
2434  * @num2: Number.
2435  * @error: Return location for error.
2436  *
2437  * Check that the return value is skipped
2438  *
2439  * Returns: (skip): %TRUE if the call succeeds, %FALSE if @error is set.
2440  */
2441 gboolean
2442 regress_test_obj_skip_return_val (RegressTestObj *obj,
2443                                   gint            a,
2444                                   gint           *out_b,
2445                                   gdouble         c,
2446                                   gint           *inout_d,
2447                                   gint           *out_sum,
2448                                   gint            num1,
2449                                   gint            num2,
2450                                   GError        **error)
2451 {
2452   if (out_b != NULL)
2453     *out_b = a + 1;
2454   if (inout_d != NULL)
2455     *inout_d = *inout_d + 1;
2456   if (out_sum != NULL)
2457     *out_sum = num1 + 10*num2;
2458   return TRUE;
2459 }
2460
2461 /**
2462  * regress_test_obj_skip_return_val_no_out:
2463  * @obj: a #RegressTestObj
2464  * @a: Parameter.
2465  * @error: Return location for error.
2466  *
2467  * Check that the return value is skipped. Succeed if a is nonzero, otherwise
2468  * raise an error.
2469  *
2470  * Returns: (skip): %TRUE if the call succeeds, %FALSE if @error is set.
2471  */
2472 gboolean
2473 regress_test_obj_skip_return_val_no_out (RegressTestObj *obj,
2474                                          gint            a,
2475                                          GError        **error)
2476 {
2477   if (a == 0) {
2478     g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "a is zero");
2479     return FALSE;
2480   } else {
2481     return TRUE;
2482   }
2483 }
2484
2485 /**
2486  * regress_test_obj_skip_param:
2487  * @obj: A #RegressTestObj.
2488  * @a: Parameter.
2489  * @out_b: (out): Return value.
2490  * @c: (skip): Other parameter.
2491  * @inout_d: (inout): Will be incremented.
2492  * @out_sum: (out): Return value.
2493  * @num1: Number.
2494  * @num2: Number.
2495  * @error: Return location for error.
2496  *
2497  * Check that a parameter is skipped
2498  *
2499  * Returns: %TRUE if the call succeeds, %FALSE if @error is set.
2500  */
2501 gboolean
2502 regress_test_obj_skip_param (RegressTestObj *obj,
2503                              gint            a,
2504                              gint           *out_b,
2505                              gdouble         c,
2506                              gint           *inout_d,
2507                              gint           *out_sum,
2508                              gint            num1,
2509                              gint            num2,
2510                              GError        **error)
2511 {
2512   if (out_b != NULL)
2513     *out_b = a + 1;
2514   if (inout_d != NULL)
2515     *inout_d = *inout_d + 1;
2516   if (out_sum != NULL)
2517     *out_sum = num1 + 10*num2;
2518   return TRUE;
2519 }
2520
2521 /**
2522  * regress_test_obj_skip_out_param:
2523  * @obj: A #RegressTestObj.
2524  * @a: Parameter.
2525  * @out_b: (out) (skip): Return value.
2526  * @c: Other parameter.
2527  * @inout_d: (inout): Will be incremented.
2528  * @out_sum: (out): Return value.
2529  * @num1: Number.
2530  * @num2: Number.
2531  * @error: Return location for error.
2532  *
2533  * Check that the out value is skipped
2534  *
2535  * Returns: %TRUE if the call succeeds, %FALSE if @error is set.
2536  */
2537 gboolean
2538 regress_test_obj_skip_out_param (RegressTestObj *obj,
2539                                  gint            a,
2540                                  gint           *out_b,
2541                                  gdouble         c,
2542                                  gint           *inout_d,
2543                                  gint           *out_sum,
2544                                  gint            num1,
2545                                  gint            num2,
2546                                  GError        **error)
2547 {
2548   if (out_b != NULL)
2549     *out_b = a + 1;
2550   if (inout_d != NULL)
2551     *inout_d = *inout_d + 1;
2552   if (out_sum != NULL)
2553     *out_sum = num1 + 10*num2;
2554   return TRUE;
2555 }
2556
2557 /**
2558  * regress_test_obj_skip_inout_param:
2559  * @obj: A #RegressTestObj.
2560  * @a: Parameter.
2561  * @out_b: (out): Return value.
2562  * @c: Other parameter.
2563  * @inout_d: (inout) (skip): Will be incremented.
2564  * @out_sum: (out): Return value.
2565  * @num1: Number.
2566  * @num2: Number.
2567  * @error: Return location for error.
2568  *
2569  * Check that the out value is skipped
2570  *
2571  * Returns: %TRUE if the call succeeds, %FALSE if @error is set.
2572  */
2573 gboolean
2574 regress_test_obj_skip_inout_param (RegressTestObj *obj,
2575                                    gint            a,
2576                                    gint           *out_b,
2577                                    gdouble         c,
2578                                    gint           *inout_d,
2579                                    gint           *out_sum,
2580                                    gint            num1,
2581                                    gint            num2,
2582                                    GError        **error)
2583 {
2584   if (out_b != NULL)
2585     *out_b = a + 1;
2586   if (inout_d != NULL)
2587     *inout_d = *inout_d + 1;
2588   if (out_sum != NULL)
2589     *out_sum = num1 + 10*num2;
2590   return TRUE;
2591 }
2592
2593 /**
2594  * regress_test_obj_do_matrix:
2595  * @obj: A #RegressTestObj
2596  * @somestr: Meaningless string
2597  *
2598  * This method is virtual.  Notably its name differs from the virtual
2599  * slot name, which makes it useful for testing bindings handle this
2600  * case.
2601  *
2602  * Virtual: matrix
2603  */
2604 int
2605 regress_test_obj_do_matrix (RegressTestObj *obj, const char *somestr)
2606 {
2607   return REGRESS_TEST_OBJ_GET_CLASS (obj)->matrix (obj, somestr);
2608 }
2609
2610 /**
2611  * regress_func_obj_null_in:
2612  * @obj: (allow-none): A #RegressTestObj
2613  */
2614 void
2615 regress_func_obj_null_in (RegressTestObj *obj)
2616 {
2617 }
2618
2619 /**
2620  * regress_test_obj_null_out:
2621  * @obj: (allow-none) (out): A #RegressTestObj
2622  */
2623 void
2624 regress_test_obj_null_out (RegressTestObj **obj)
2625 {
2626   if (obj)
2627     *obj = NULL;
2628 }
2629
2630 /**
2631  * regress_test_array_fixed_out_objects:
2632  * @objs: (out) (array fixed-size=2) (transfer full): An array of #RegressTestObj
2633  */
2634 void
2635 regress_test_array_fixed_out_objects (RegressTestObj ***objs)
2636 {
2637     RegressTestObj **values = (RegressTestObj**)g_new(gpointer, 2);
2638
2639     values[0] = regress_constructor();
2640     values[1] = regress_constructor();
2641
2642     *objs = values;
2643 }
2644
2645 typedef struct _CallbackInfo CallbackInfo;
2646
2647 struct _CallbackInfo
2648 {
2649   RegressTestCallbackUserData callback;
2650   GDestroyNotify notify;
2651   gpointer user_data;
2652 };
2653
2654
2655 G_DEFINE_TYPE(RegressTestSubObj, regress_test_sub_obj, REGRESS_TEST_TYPE_OBJ);
2656
2657 static void
2658 regress_test_sub_obj_class_init (RegressTestSubObjClass *klass)
2659 {
2660 }
2661
2662 static void
2663 regress_test_sub_obj_init (RegressTestSubObj *obj)
2664 {
2665 }
2666
2667 RegressTestObj*
2668 regress_test_sub_obj_new ()
2669 {
2670   return g_object_new (REGRESS_TEST_TYPE_SUB_OBJ, NULL);
2671 }
2672
2673 int
2674 regress_test_sub_obj_instance_method (RegressTestSubObj *obj)
2675 {
2676     return 0;
2677 }
2678
2679 void
2680 regress_test_sub_obj_unset_bare (RegressTestSubObj *obj)
2681 {
2682   regress_test_obj_set_bare(REGRESS_TEST_OBJECT(obj), NULL);
2683 }
2684
2685 /* RegressTestFundamental */
2686
2687 /**
2688  * regress_test_fundamental_object_ref:
2689  *
2690  * Returns: (transfer full): A new #RegressTestFundamentalObject
2691  */
2692 RegressTestFundamentalObject *
2693 regress_test_fundamental_object_ref (RegressTestFundamentalObject * fundamental_object)
2694 {
2695   g_return_val_if_fail (fundamental_object != NULL, NULL);
2696   g_atomic_int_inc (&fundamental_object->refcount);
2697
2698   return fundamental_object;
2699 }
2700
2701 static void
2702 regress_test_fundamental_object_free (RegressTestFundamentalObject * fundamental_object)
2703 {
2704   RegressTestFundamentalObjectClass *mo_class;
2705   regress_test_fundamental_object_ref (fundamental_object);
2706
2707   mo_class = REGRESS_TEST_FUNDAMENTAL_OBJECT_GET_CLASS (fundamental_object);
2708   mo_class->finalize (fundamental_object);
2709
2710   if (G_LIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
2711     g_type_free_instance ((GTypeInstance *) fundamental_object);
2712   }
2713 }
2714
2715 void
2716 regress_test_fundamental_object_unref (RegressTestFundamentalObject * fundamental_object)
2717 {
2718   g_return_if_fail (fundamental_object != NULL);
2719   g_return_if_fail (fundamental_object->refcount > 0);
2720
2721   if (G_UNLIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
2722     regress_test_fundamental_object_free (fundamental_object);
2723   }
2724 }
2725
2726 static void
2727 regress_test_fundamental_object_replace (RegressTestFundamentalObject ** olddata, RegressTestFundamentalObject * newdata)
2728 {
2729   RegressTestFundamentalObject *olddata_val;
2730
2731   g_return_if_fail (olddata != NULL);
2732
2733   olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
2734
2735   if (olddata_val == newdata)
2736     return;
2737
2738   if (newdata)
2739     regress_test_fundamental_object_ref (newdata);
2740
2741   while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata,
2742           olddata_val, newdata)) {
2743     olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
2744   }
2745
2746   if (olddata_val)
2747     regress_test_fundamental_object_unref (olddata_val);
2748 }
2749
2750 static void
2751 regress_test_value_fundamental_object_init (GValue * value)
2752 {
2753   value->data[0].v_pointer = NULL;
2754 }
2755
2756 static void
2757 regress_test_value_fundamental_object_free (GValue * value)
2758 {
2759   if (value->data[0].v_pointer) {
2760     regress_test_fundamental_object_unref (REGRESS_TEST_FUNDAMENTAL_OBJECT_CAST (value->data[0].v_pointer));
2761   }
2762 }
2763
2764 static void
2765 regress_test_value_fundamental_object_copy (const GValue * src_value, GValue * dest_value)
2766 {
2767   if (src_value->data[0].v_pointer) {
2768     dest_value->data[0].v_pointer =
2769         regress_test_fundamental_object_ref (REGRESS_TEST_FUNDAMENTAL_OBJECT_CAST (src_value->data[0].
2770             v_pointer));
2771   } else {
2772     dest_value->data[0].v_pointer = NULL;
2773   }
2774 }
2775
2776 static gpointer
2777 regress_test_value_fundamental_object_peek_pointer (const GValue * value)
2778 {
2779   return value->data[0].v_pointer;
2780 }
2781
2782 static gchar *
2783 regress_test_value_fundamental_object_collect (GValue * value,
2784                                        guint n_collect_values,
2785                                        GTypeCValue * collect_values,
2786                                        guint collect_flags)
2787 {
2788   if (collect_values[0].v_pointer) {
2789     value->data[0].v_pointer =
2790         regress_test_fundamental_object_ref (collect_values[0].v_pointer);
2791   } else {
2792     value->data[0].v_pointer = NULL;
2793   }
2794
2795   return NULL;
2796 }
2797
2798 static gchar *
2799 regress_test_value_fundamental_object_lcopy (const GValue * value,
2800                                      guint n_collect_values,
2801                                      GTypeCValue * collect_values,
2802                                      guint collect_flags)
2803 {
2804   gpointer *fundamental_object_p = collect_values[0].v_pointer;
2805
2806   if (!fundamental_object_p) {
2807     return g_strdup_printf ("value location for '%s' passed as NULL",
2808         G_VALUE_TYPE_NAME (value));
2809   }
2810
2811   if (!value->data[0].v_pointer)
2812     *fundamental_object_p = NULL;
2813   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
2814     *fundamental_object_p = value->data[0].v_pointer;
2815   else
2816     *fundamental_object_p = regress_test_fundamental_object_ref (value->data[0].v_pointer);
2817
2818   return NULL;
2819 }
2820
2821 static void
2822 regress_test_fundamental_object_finalize (RegressTestFundamentalObject * obj)
2823 {
2824
2825 }
2826
2827 static RegressTestFundamentalObject *
2828 regress_test_fundamental_object_copy_default (const RegressTestFundamentalObject * obj)
2829 {
2830   g_warning ("RegressTestFundamentalObject classes must implement RegressTestFundamentalObject::copy");
2831   return NULL;
2832 }
2833
2834 static void
2835 regress_test_fundamental_object_class_init (gpointer g_class, gpointer class_data)
2836 {
2837   RegressTestFundamentalObjectClass *mo_class = REGRESS_TEST_FUNDAMENTAL_OBJECT_CLASS (g_class);
2838
2839   mo_class->copy = regress_test_fundamental_object_copy_default;
2840   mo_class->finalize = regress_test_fundamental_object_finalize;
2841 }
2842
2843 static void
2844 regress_test_fundamental_object_init (GTypeInstance * instance, gpointer klass)
2845 {
2846   RegressTestFundamentalObject *fundamental_object = REGRESS_TEST_FUNDAMENTAL_OBJECT_CAST (instance);
2847
2848   fundamental_object->refcount = 1;
2849 }
2850
2851 /**
2852  * RegressTestFundamentalObject:
2853  *
2854  * Ref Func: regress_test_fundamental_object_ref
2855  * Unref Func: regress_test_fundamental_object_unref
2856  * Set Value Func: regress_test_value_set_fundamental_object
2857  * Get Value Func: regress_test_value_get_fundamental_object
2858  */
2859
2860 GType
2861 regress_test_fundamental_object_get_type (void)
2862 {
2863   static GType _test_fundamental_object_type = 0;
2864
2865   if (G_UNLIKELY (_test_fundamental_object_type == 0)) {
2866     static const GTypeValueTable value_table = {
2867       regress_test_value_fundamental_object_init,
2868       regress_test_value_fundamental_object_free,
2869       regress_test_value_fundamental_object_copy,
2870       regress_test_value_fundamental_object_peek_pointer,
2871       (char *) "p",
2872       regress_test_value_fundamental_object_collect,
2873       (char *) "p",
2874       regress_test_value_fundamental_object_lcopy
2875     };
2876     static const GTypeInfo fundamental_object_info = {
2877       sizeof (RegressTestFundamentalObjectClass),
2878       NULL, NULL,
2879       regress_test_fundamental_object_class_init,
2880       NULL,
2881       NULL,
2882       sizeof (RegressTestFundamentalObject),
2883       0,
2884       (GInstanceInitFunc) regress_test_fundamental_object_init,
2885       &value_table
2886     };
2887     static const GTypeFundamentalInfo fundamental_object_fundamental_info = {
2888       (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE |
2889           G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
2890     };
2891
2892     _test_fundamental_object_type = g_type_fundamental_next ();
2893     g_type_register_fundamental (_test_fundamental_object_type, "RegressTestFundamentalObject",
2894         &fundamental_object_info, &fundamental_object_fundamental_info, G_TYPE_FLAG_ABSTRACT);
2895
2896   }
2897
2898   return _test_fundamental_object_type;
2899 }
2900
2901 /**
2902  * regress_test_value_set_fundamental_object: (skip)
2903  * @value:
2904  * @fundamental_object:
2905  */
2906 void
2907 regress_test_value_set_fundamental_object (GValue * value, RegressTestFundamentalObject * fundamental_object)
2908 {
2909   gpointer *pointer_p;
2910
2911   g_return_if_fail (REGRESS_TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value));
2912   g_return_if_fail (fundamental_object == NULL || REGRESS_TEST_IS_FUNDAMENTAL_OBJECT (fundamental_object));
2913
2914   pointer_p = &value->data[0].v_pointer;
2915
2916   regress_test_fundamental_object_replace ((RegressTestFundamentalObject **) pointer_p, fundamental_object);
2917 }
2918
2919 /**
2920  * regress_test_value_get_fundamental_object: (skip)
2921  * @value:
2922  */
2923 RegressTestFundamentalObject *
2924 regress_test_value_get_fundamental_object (const GValue * value)
2925 {
2926   g_return_val_if_fail (REGRESS_TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value), NULL);
2927
2928   return value->data[0].v_pointer;
2929 }
2930
2931 static RegressTestFundamentalObjectClass *parent_class = NULL;
2932
2933 G_DEFINE_TYPE (RegressTestFundamentalSubObject, regress_test_fundamental_sub_object, REGRESS_TEST_TYPE_FUNDAMENTAL_OBJECT);
2934
2935 static RegressTestFundamentalSubObject *
2936 _regress_test_fundamental_sub_object_copy (RegressTestFundamentalSubObject * fundamental_sub_object)
2937 {
2938   RegressTestFundamentalSubObject *copy;
2939
2940   copy = regress_test_fundamental_sub_object_new(NULL);
2941   copy->data = g_strdup(fundamental_sub_object->data);
2942   return copy;
2943 }
2944
2945 static void
2946 regress_test_fundamental_sub_object_finalize (RegressTestFundamentalSubObject * fundamental_sub_object)
2947 {
2948   g_return_if_fail (fundamental_sub_object != NULL);
2949
2950   g_free(fundamental_sub_object->data);
2951   regress_test_fundamental_object_finalize (REGRESS_TEST_FUNDAMENTAL_OBJECT (fundamental_sub_object));
2952 }
2953
2954 static void
2955 regress_test_fundamental_sub_object_class_init (RegressTestFundamentalSubObjectClass * klass)
2956 {
2957   parent_class = g_type_class_peek_parent (klass);
2958
2959   klass->fundamental_object_class.copy = (RegressTestFundamentalObjectCopyFunction) _regress_test_fundamental_sub_object_copy;
2960   klass->fundamental_object_class.finalize =
2961       (RegressTestFundamentalObjectFinalizeFunction) regress_test_fundamental_sub_object_finalize;
2962 }
2963
2964 static void
2965 regress_test_fundamental_sub_object_init(RegressTestFundamentalSubObject *object)
2966 {
2967
2968 }
2969
2970 /**
2971  * regress_test_fundamental_sub_object_new:
2972  */
2973 RegressTestFundamentalSubObject *
2974 regress_test_fundamental_sub_object_new (const char * data)
2975 {
2976   RegressTestFundamentalSubObject *object;
2977
2978   object = (RegressTestFundamentalSubObject *) g_type_create_instance (regress_test_fundamental_sub_object_get_type());
2979   object->data = g_strdup(data);
2980   return object;
2981 }
2982
2983
2984 /**
2985  * regress_test_callback:
2986  * @callback: (scope call) (allow-none):
2987  *
2988  **/
2989 int
2990 regress_test_callback (RegressTestCallback callback)
2991 {
2992     if (callback != NULL)
2993         return callback();
2994     return 0;
2995 }
2996
2997 /**
2998  * regress_test_multi_callback:
2999  * @callback: (scope call) (allow-none):
3000  *
3001  **/
3002 int
3003 regress_test_multi_callback (RegressTestCallback callback)
3004 {
3005     int sum = 0;
3006     if (callback != NULL) {
3007         sum += callback();
3008         sum += callback();
3009     }
3010
3011     return sum;
3012 }
3013
3014 /**
3015  * regress_test_array_callback:
3016  * @callback: (scope call):
3017  *
3018  **/
3019 int regress_test_array_callback (RegressTestCallbackArray callback)
3020 {
3021   static const char *strings[] = { "one", "two", "three" };
3022   static int ints[] = { -1, 0, 1, 2 };
3023   int sum = 0;
3024
3025   sum += callback(ints, 4, strings, 3);
3026   sum += callback(ints, 4, strings, 3);
3027
3028   return sum;
3029 }
3030
3031 /**
3032  * regress_test_simple_callback:
3033  * @callback: (scope call) (allow-none):
3034  *
3035  **/
3036 void
3037 regress_test_simple_callback (RegressTestSimpleCallback callback)
3038 {
3039     if (callback != NULL)
3040         callback();
3041
3042     return;
3043 }
3044
3045 /**
3046  * regress_test_callback_user_data:
3047  * @callback: (scope call):
3048  *
3049  * Call - callback parameter persists for the duration of the method
3050  * call and can be released on return.
3051  **/
3052 int
3053 regress_test_callback_user_data (RegressTestCallbackUserData callback,
3054                          gpointer user_data)
3055 {
3056   return callback(user_data);
3057 }
3058
3059 static GSList *notified_callbacks = NULL;
3060
3061 /**
3062  * regress_test_callback_destroy_notify:
3063  * @callback: (scope notified):
3064  *
3065  * Notified - callback persists until a DestroyNotify delegate
3066  * is invoked.
3067  **/
3068 int
3069 regress_test_callback_destroy_notify (RegressTestCallbackUserData callback,
3070                               gpointer user_data,
3071                               GDestroyNotify notify)
3072 {
3073   int retval;
3074   CallbackInfo *info;
3075
3076   retval = callback(user_data);
3077
3078   info = g_slice_new(CallbackInfo);
3079   info->callback = callback;
3080   info->notify = notify;
3081   info->user_data = user_data;
3082
3083   notified_callbacks = g_slist_prepend(notified_callbacks, info);
3084
3085   return retval;
3086 }
3087
3088 /**
3089  * regress_test_callback_thaw_notifications:
3090  *
3091  * Invokes all callbacks installed by #test_callback_destroy_notify(),
3092  * adding up their return values, and removes them, invoking the
3093  * corresponding destroy notfications.
3094  *
3095  * Return value: Sum of the return values of the invoked callbacks.
3096  */
3097 int
3098 regress_test_callback_thaw_notifications (void)
3099 {
3100   int retval = 0;
3101   GSList *node;
3102
3103   for (node = notified_callbacks; node != NULL; node = node->next)
3104     {
3105       CallbackInfo *info = node->data;
3106       retval += info->callback (info->user_data);
3107       if (info->notify)
3108         info->notify (info->user_data);
3109       g_slice_free (CallbackInfo, info);
3110     }
3111
3112   g_slist_free (notified_callbacks);
3113   notified_callbacks = NULL;
3114
3115   return retval;
3116 }
3117
3118 static GSList *async_callbacks = NULL;
3119
3120 /**
3121  * regress_test_callback_async:
3122  * @callback: (scope async):
3123  *
3124  **/
3125 void
3126 regress_test_callback_async (RegressTestCallbackUserData callback,
3127                      gpointer user_data)
3128 {
3129   CallbackInfo *info;
3130
3131   info = g_slice_new(CallbackInfo);
3132   info->callback = callback;
3133   info->user_data = user_data;
3134
3135   async_callbacks = g_slist_prepend(async_callbacks, info);
3136 }
3137
3138 /**
3139  * regress_test_callback_thaw_async:
3140  */
3141 int
3142 regress_test_callback_thaw_async (void)
3143 {
3144   int retval = 0;
3145   GSList *node;
3146
3147   for (node = async_callbacks; node != NULL; node = node->next)
3148     {
3149       CallbackInfo *info = node->data;
3150       retval = info->callback (info->user_data);
3151       g_slice_free (CallbackInfo, info);
3152     }
3153
3154   g_slist_free (async_callbacks);
3155   async_callbacks = NULL;
3156   return retval;
3157 }
3158
3159 void
3160 regress_test_async_ready_callback (GAsyncReadyCallback callback)
3161 {
3162   GSimpleAsyncResult *result = g_simple_async_result_new (NULL, callback, NULL,
3163     regress_test_async_ready_callback);
3164   g_simple_async_result_complete_in_idle (result);
3165 }
3166
3167 /**
3168  * regress_test_obj_instance_method_callback:
3169  * @callback: (scope call) (allow-none):
3170  *
3171  **/
3172 void
3173 regress_test_obj_instance_method_callback (RegressTestObj *obj, RegressTestCallback callback)
3174 {
3175     if (callback != NULL)
3176         callback();
3177 }
3178
3179 /**
3180  * regress_test_obj_static_method_callback:
3181  * @callback: (scope call) (allow-none):
3182  *
3183  **/
3184 void
3185 regress_test_obj_static_method_callback (RegressTestCallback callback)
3186 {
3187     if (callback != NULL)
3188         callback();
3189 }
3190
3191 /**
3192  * regress_test_obj_new_callback:
3193  * @callback: (scope notified):
3194  **/
3195 RegressTestObj *
3196 regress_test_obj_new_callback (RegressTestCallbackUserData callback, gpointer user_data,
3197                        GDestroyNotify notify)
3198 {
3199   CallbackInfo *info;
3200
3201   callback(user_data);
3202
3203   info = g_slice_new(CallbackInfo);
3204   info->callback = callback;
3205   info->notify = notify;
3206   info->user_data = user_data;
3207
3208   notified_callbacks = g_slist_prepend(notified_callbacks, info);
3209
3210   return g_object_new (REGRESS_TEST_TYPE_OBJ, NULL);
3211 }
3212
3213 /**
3214  * regress_test_hash_table_callback:
3215  * @data: (element-type utf8 gint): GHashTable that gets passed to callback
3216  * @callback: (scope call):
3217  **/
3218 void
3219 regress_test_hash_table_callback (GHashTable *data, RegressTestCallbackHashtable callback)
3220 {
3221   callback (data);
3222 }
3223
3224 /**
3225  * regress_test_gerror_callback:
3226  * @callback: (scope call):
3227  **/
3228 void
3229 regress_test_gerror_callback (RegressTestCallbackGError callback)
3230 {
3231   GError *error;
3232
3233   error = g_error_new_literal (G_IO_ERROR,
3234                                G_IO_ERROR_NOT_SUPPORTED,
3235                                "regression test error");
3236   callback (error);
3237   g_error_free (error);
3238 }
3239
3240 /**
3241  * regress_test_null_gerror_callback:
3242  * @callback: (scope call):
3243  **/
3244 void
3245 regress_test_null_gerror_callback (RegressTestCallbackGError callback)
3246 {
3247   callback (NULL);
3248 }
3249
3250 /**
3251  * regress_test_owned_gerror_callback:
3252  * @callback: (scope call):
3253  **/
3254 void
3255 regress_test_owned_gerror_callback (RegressTestCallbackOwnedGError callback)
3256 {
3257   GError *error;
3258
3259   error = g_error_new_literal (G_IO_ERROR,
3260                                G_IO_ERROR_PERMISSION_DENIED,
3261                                "regression test owned error");
3262   callback (error);
3263 }
3264
3265 /* interface */
3266
3267 static void
3268 regress_test_interface_class_init(void *g_iface)
3269 {
3270 }
3271
3272 GType
3273 regress_test_interface_get_type(void)
3274 {
3275     static GType type = 0;
3276     if (type == 0) {
3277         type = g_type_register_static_simple (G_TYPE_INTERFACE,
3278                                               "RegressTestInterface",
3279                                               sizeof (RegressTestInterfaceIface),
3280                                               (GClassInitFunc) regress_test_interface_class_init,
3281                                               0, NULL, 0);
3282     }
3283
3284     return type;
3285 }
3286
3287 /* gobject with non-standard prefix */
3288 G_DEFINE_TYPE(RegressTestWi8021x, regress_test_wi_802_1x, G_TYPE_OBJECT);
3289
3290 enum
3291 {
3292   PROP_TEST_WI_802_1X_TESTBOOL = 1
3293 };
3294
3295 static void
3296 regress_test_wi_802_1x_set_property (GObject      *object,
3297                              guint         property_id,
3298                              const GValue *value,
3299                              GParamSpec   *pspec)
3300 {
3301   RegressTestWi8021x *self = REGRESS_TEST_WI_802_1X (object);
3302
3303   switch (property_id)
3304     {
3305     case PROP_TEST_WI_802_1X_TESTBOOL:
3306       regress_test_wi_802_1x_set_testbool (self, g_value_get_boolean (value));
3307       break;
3308
3309     default:
3310       /* We don't have any other property... */
3311       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
3312       break;
3313     }
3314 }
3315
3316 static void
3317 regress_test_wi_802_1x_get_property (GObject    *object,
3318                         guint       property_id,
3319                         GValue     *value,
3320                         GParamSpec *pspec)
3321 {
3322   RegressTestWi8021x *self = REGRESS_TEST_WI_802_1X (object);
3323
3324   switch (property_id)
3325     {
3326     case PROP_TEST_WI_802_1X_TESTBOOL:
3327       g_value_set_boolean (value, regress_test_wi_802_1x_get_testbool (self));
3328       break;
3329
3330     default:
3331       /* We don't have any other property... */
3332       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
3333       break;
3334     }
3335 }
3336
3337 static void
3338 regress_test_wi_802_1x_dispose (GObject *gobject)
3339 {
3340   /* Chain up to the parent class */
3341   G_OBJECT_CLASS (regress_test_wi_802_1x_parent_class)->dispose (gobject);
3342 }
3343
3344 static void
3345 regress_test_wi_802_1x_class_init (RegressTestWi8021xClass *klass)
3346 {
3347   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3348   GParamSpec *pspec;
3349
3350   gobject_class->set_property = regress_test_wi_802_1x_set_property;
3351   gobject_class->get_property = regress_test_wi_802_1x_get_property;
3352   gobject_class->dispose = regress_test_wi_802_1x_dispose;
3353
3354   pspec = g_param_spec_boolean ("testbool",
3355                                 "Nick for testbool",
3356                                 "Blurb for testbool",
3357                                 TRUE,
3358                                 G_PARAM_READWRITE);
3359   g_object_class_install_property (gobject_class,
3360                                    PROP_TEST_WI_802_1X_TESTBOOL,
3361                                    pspec);
3362 }
3363
3364 static void
3365 regress_test_wi_802_1x_init (RegressTestWi8021x *obj)
3366 {
3367   obj->testbool = TRUE;
3368 }
3369
3370 RegressTestWi8021x *
3371 regress_test_wi_802_1x_new (void)
3372 {
3373   return g_object_new (REGRESS_TEST_TYPE_WI_802_1X, NULL);
3374 }
3375
3376 void
3377 regress_test_wi_802_1x_set_testbool (RegressTestWi8021x *obj, gboolean val)
3378 {
3379   obj->testbool = val;
3380 }
3381
3382 gboolean
3383 regress_test_wi_802_1x_get_testbool (RegressTestWi8021x *obj)
3384 {
3385   return obj->testbool;
3386 }
3387
3388 int
3389 regress_test_wi_802_1x_static_method (int x)
3390 {
3391   return 2*x;
3392 }
3393
3394 /* floating gobject */
3395 G_DEFINE_TYPE(RegressTestFloating, regress_test_floating, G_TYPE_INITIALLY_UNOWNED);
3396
3397 static void
3398 regress_test_floating_finalize(GObject *object)
3399 {
3400   g_assert(!g_object_is_floating (object));
3401
3402   G_OBJECT_CLASS(regress_test_floating_parent_class)->finalize(object);
3403 }
3404
3405 static void
3406 regress_test_floating_class_init (RegressTestFloatingClass *klass)
3407 {
3408   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3409   gobject_class->finalize = regress_test_floating_finalize;
3410 }
3411
3412 static void
3413 regress_test_floating_init (RegressTestFloating *obj)
3414 {
3415 }
3416
3417 /**
3418  * regress_test_floating_new:
3419  *
3420  * Returns:: A new floating #RegressTestFloating
3421  */
3422 RegressTestFloating *
3423 regress_test_floating_new (void)
3424 {
3425   return g_object_new (REGRESS_TEST_TYPE_FLOATING, NULL);
3426 }
3427
3428
3429 /**
3430  * regress_test_torture_signature_0:
3431  * @x:
3432  * @y: (out):
3433  * @z: (out):
3434  * @foo:
3435  * @q: (out):
3436  * @m:
3437  *
3438  */
3439 void
3440 regress_test_torture_signature_0 (int         x,
3441                           double     *y,
3442                           int        *z,
3443                           const char *foo,
3444                           int        *q,
3445                           guint       m)
3446 {
3447   *y = x;
3448   *z = x * 2;
3449   *q = g_utf8_strlen (foo, -1) + m;
3450 }
3451
3452 /**
3453  * regress_test_torture_signature_1:
3454  * @x:
3455  * @y: (out):
3456  * @z: (out):
3457  * @foo:
3458  * @q: (out):
3459  * @m:
3460  * @error: A #GError
3461  *
3462  * This function throws an error if m is odd.
3463  */
3464 gboolean
3465 regress_test_torture_signature_1 (int         x,
3466                           double     *y,
3467                           int        *z,
3468                           const char *foo,
3469                           int        *q,
3470                           guint       m,
3471                           GError    **error)
3472 {
3473   *y = x;
3474   *z = x * 2;
3475   *q = g_utf8_strlen (foo, -1) + m;
3476   if (m % 2 == 0)
3477       return TRUE;
3478   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "m is odd");
3479   return FALSE;
3480 }
3481
3482 /**
3483  * regress_test_torture_signature_2:
3484  * @x:
3485  * @callback:
3486  * @user_data:
3487  * @notify:
3488  * @y: (out):
3489  * @z: (out):
3490  * @foo:
3491  * @q: (out):
3492  * @m:
3493  *
3494  */
3495 void
3496 regress_test_torture_signature_2 (int                   x,
3497                           RegressTestCallbackUserData  callback,
3498                           gpointer              user_data,
3499                           GDestroyNotify        notify,
3500                           double               *y,
3501                           int                  *z,
3502                           const char           *foo,
3503                           int                  *q,
3504                           guint                 m)
3505 {
3506   *y = x;
3507   *z = x * 2;
3508   *q = g_utf8_strlen (foo, -1) + m;
3509   notify (user_data);
3510 }
3511
3512 /**
3513  * regress_test_date_in_gvalue:
3514  *
3515  * Returns: (transfer full):
3516  */
3517 GValue *
3518 regress_test_date_in_gvalue (void)
3519 {
3520   GValue *value = g_new0 (GValue, 1);
3521   GDate *date = g_date_new_dmy (5, 12, 1984);
3522
3523   g_value_init (value, G_TYPE_DATE);
3524   g_value_take_boxed (value, date);
3525
3526   return value;
3527 }
3528
3529 /**
3530  * regress_test_strv_in_gvalue:
3531  *
3532  * Returns: (transfer full):
3533  */
3534 GValue *
3535 regress_test_strv_in_gvalue (void)
3536 {
3537   GValue *value = g_new0 (GValue, 1);
3538   const char *strv[] = { "one", "two", "three", NULL };
3539
3540   g_value_init (value, G_TYPE_STRV);
3541   g_value_set_boxed (value, strv);
3542
3543   return value;
3544 }
3545
3546 /**
3547  * regress_test_multiline_doc_comments:
3548  *
3549  * This is a function.
3550  *
3551  * It has multiple lines in the documentation.
3552  *
3553  * The sky is blue.
3554  *
3555  * You will give me your credit card number.
3556  */
3557 void
3558 regress_test_multiline_doc_comments (void)
3559 {
3560 }
3561
3562 /**
3563  * regress_test_nested_parameter:
3564  * @a: An integer
3565  *
3566  * <informaltable>
3567  *   <tgroup cols="3">
3568  *     <thead>
3569  *       <row>
3570  *         <entry>Syntax</entry>
3571  *         <entry>Explanation</entry>
3572  *         <entry>Examples</entry>
3573  *       </row>
3574  *     </thead>
3575  *     <tbody>
3576  *       <row>
3577  *         <entry>rgb(@r, @g, @b)</entry>
3578  *         <entry>An opaque color; @r, @g, @b can be either integers between
3579  *                0 and 255 or percentages</entry>
3580  *         <entry><literallayout>rgb(128, 10, 54)
3581  * rgb(20%, 30%, 0%)</literallayout></entry>
3582  *       </row>
3583  *       <row>
3584  *         <entry>rgba(@r, @g, @b, @a)</entry>
3585  *         <entry>A translucent color; @r, @g, @b are as in the previous row,
3586  *                @a is a floating point number between 0 and 1</entry>
3587  *         <entry><literallayout>rgba(255, 255, 0, 0.5)</literallayout></entry>
3588  *       </row>
3589  *    </tbody>
3590  *  </tgroup>
3591  * </informaltable>
3592  *
3593  * What we're testing here is that the scanner ignores the @a nested inside XML.
3594  */
3595 void
3596 regress_test_nested_parameter (int a)
3597 {
3598 }
3599
3600 /**
3601  * regress_introspectable_via_alias:
3602  *
3603  */
3604 void
3605 regress_introspectable_via_alias (RegressPtrArrayAlias *data)
3606 {
3607 }
3608
3609 /**
3610  * regress_not_introspectable_via_alias:
3611  *
3612  */
3613 void
3614 regress_not_introspectable_via_alias (RegressVaListAlias ok)
3615 {
3616 }
3617
3618 /**
3619  * regress_aliased_caller_alloc:
3620  * @boxed: (out):
3621  */
3622 void regress_aliased_caller_alloc (RegressAliasedTestBoxed *boxed)
3623 {
3624   boxed->priv = g_slice_new0 (RegressTestBoxedPrivate);
3625   boxed->priv->magic = 0xdeadbeef;
3626 }
3627
3628 void
3629 regress_test_struct_fixed_array_frob (RegressTestStructFixedArray *str)
3630 {
3631   guint i;
3632   str->just_int = 7;
3633
3634   for (i = 0; i < G_N_ELEMENTS(str->array); i++)
3635     str->array[i] = 42 + i;
3636 }
3637
3638 /**
3639  * regress_has_parameter_named_attrs:
3640  * @foo: some int
3641  * @attributes: (type guint32) (array fixed-size=32): list of attributes
3642  *
3643  * This test case mirrors GnomeKeyringPasswordSchema from
3644  * libgnome-keyring.
3645  */
3646 void
3647 regress_has_parameter_named_attrs (int        foo,
3648                                    gpointer   attributes)
3649 {
3650 }