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