[everything] Add alternative boxed constructors
[gnome.gobject-introspection] / gir / everything.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include "everything.h"
4 #include <gio/gio.h>
5
6 /* basic types */
7 gboolean test_boolean (gboolean in)
8 {
9   return in;
10 }
11
12 gint8 test_int8 (gint8 in)
13 {
14   return in;
15 }
16
17 guint8 test_uint8 (guint8 in)
18 {
19   return in;
20 }
21
22 gint16 test_int16 (gint16 in)
23 {
24   return in;
25 }
26
27 guint16 test_uint16 (guint16 in)
28 {
29   return in;
30 }
31
32 gint32 test_int32 (gint32 in)
33 {
34   return in;
35 }
36
37 guint32 test_uint32 (guint32 in)
38 {
39   return in;
40 }
41
42 gint64 test_int64 (gint64 in)
43 {
44   return in;
45 }
46
47 guint64 test_uint64 (guint64 in)
48 {
49   return in;
50 }
51
52 gshort test_short (gshort in)
53 {
54   return in;
55 }
56
57 gushort test_ushort (gushort in)
58 {
59   return in;
60 }
61
62 gint test_int (gint in)
63 {
64   return in;
65 }
66
67 guint test_uint (guint in)
68 {
69   return in;
70 }
71
72 glong test_long (glong in)
73 {
74   return in;
75 }
76
77 gulong test_ulong (gulong in)
78 {
79   return in;
80 }
81
82 gssize test_ssize (gssize in)
83 {
84   return in;
85 }
86
87 gsize test_size (gsize in)
88 {
89   return in;
90 }
91
92 gfloat test_float (gfloat in)
93 {
94   return in;
95 }
96
97 gdouble test_double (gdouble in)
98 {
99   return in;
100 }
101
102
103 time_t test_timet (time_t in)
104 {
105   return in;
106 }
107
108 GType test_gtype (GType in)
109 {
110   return in;
111 }
112
113 int test_closure (GClosure *closure)
114 {
115   GValue return_value = {0, };
116   int ret;
117
118   g_value_init (&return_value, G_TYPE_INT);
119
120   g_closure_invoke (closure,
121                     &return_value,
122                     0, NULL,
123                     NULL);
124
125   ret = g_value_get_int (&return_value);
126
127   g_value_unset(&return_value);
128
129   return ret;
130 }
131
132 int test_closure_one_arg (GClosure *closure, int arg)
133 {
134   GValue return_value = {0, };
135   GValue arguments[1];
136   int ret;
137
138   g_value_init (&return_value, G_TYPE_INT);
139
140   memset (&arguments[0], 0, sizeof (arguments));
141   g_value_init (&arguments[0], G_TYPE_INT);
142   g_value_set_int (&arguments[0], arg);
143
144   g_closure_invoke (closure,
145                     &return_value,
146                     1, arguments,
147                     NULL);
148
149   ret = g_value_get_int (&return_value);
150
151   g_value_unset(&return_value);
152   g_value_unset(&arguments[0]);
153
154   return ret;
155 }
156
157 /**
158  * test_value_arg:
159  * @v: (transfer none): a GValue expected to contain an int
160  *
161  * Return value: the int contained in the GValue.
162  */
163 int test_int_value_arg(const GValue *v) {
164   int i;
165
166   i = g_value_get_int (v);
167
168   return i;
169 }
170
171 static GValue value;
172 /**
173  * test_value_return:
174  * @i: an int
175  *
176  * Return value: (transfer none): the int wrapped in a GValue.
177  */
178 const GValue *test_value_return(int i) {
179   memset(&value, '\0', sizeof(GValue));
180
181   g_value_init (&value, G_TYPE_INT);
182   g_value_set_int (&value, i);
183
184   return &value;
185 }
186
187
188 /************************************************************************/
189 /* utf8 */
190 /* insert BLACK HEART SUIT to ensure UTF-8 doesn't get mangled */
191 static const char utf8_const[]    = "const \xe2\x99\xa5 utf8";
192 static const char utf8_nonconst[] = "nonconst \xe2\x99\xa5 utf8";
193
194 /**
195  * test_utf8_const_return:
196  * Return value: <const char*> UTF-8 string
197  */
198 G_CONST_RETURN char *test_utf8_const_return (void)
199 {
200   /* transfer mode none */
201   return utf8_const;
202 }
203
204 /**
205  * test_utf8_nonconst_return:
206  * Return value: <char*> UTF-8 string
207  */
208 char *test_utf8_nonconst_return (void)
209 {
210   /* transfer mode full */
211   return g_strdup (utf8_nonconst);
212 }
213
214 void test_utf8_nonconst_in (char *in)
215 {
216   /* transfer mode full */
217   g_assert (strcmp (in, utf8_nonconst) == 0);
218   g_free(in);
219 }
220
221 void test_utf8_const_in (const char *in)
222 {
223   /* transfer mode none */
224   g_assert (strcmp (in, utf8_const) == 0);
225 }
226
227 /**
228  * test_utf8_out:
229  * @out: (out) (transfer full):
230  */
231 void test_utf8_out (char **out)
232 {
233   /* out parameter, transfer mode full */
234   *out = g_strdup (utf8_nonconst);
235 }
236
237 /**
238  * test_utf8_inout:
239  * @inout: (inout):
240  */
241 void test_utf8_inout (char **inout)
242 {
243   /* inout parameter, transfer mode full */
244   g_assert (strcmp (*inout, utf8_const) == 0);
245   g_free(*inout);
246   *inout = g_strdup (utf8_nonconst);
247 }
248
249 /**
250  * test_filename_return:
251  *
252  * Return value: (element-type filename) (transfer full): list of strings
253  */
254 GSList *test_filename_return (void)
255 {
256   GSList *filenames = NULL;
257   filenames = g_slist_prepend (filenames, g_filename_from_utf8("/etc/fstab", -1, NULL, NULL, NULL));
258   filenames = g_slist_prepend (filenames, g_filename_from_utf8("åäö", -1, NULL, NULL, NULL));
259   return filenames;
260 }
261
262 /* in arguments after out arguments */
263
264 /**
265  * test_int_out_utf8:
266  * @out: (out):
267  * @in:
268  */
269 void
270 test_int_out_utf8 (int *length, const char *in)
271 {
272     *length = g_utf8_strlen(in, -1);
273 }
274
275
276 /* multiple output arguments */
277
278 /**
279  * test_multi_double_args:
280  * @in:
281  * @one: (out): 
282  * @two: (out): 
283  */
284 void
285 test_multi_double_args (gdouble in, gdouble *one, gdouble *two)
286 {
287   *one = in * 2;
288   *two = in * 3;
289 }
290
291 /**
292  * test_utf8_out_out:
293  * @out0: (out) (transfer full): a copy of "first"
294  * @out1: (out) (transfer full): a copy of "second"
295  */
296 void
297 test_utf8_out_out (char **out0, char **out1)
298 {
299   *out0 = g_strdup ("first");
300   *out1 = g_strdup ("second");
301 }
302
303 /**
304  * test_utf8_out_nonconst_return:
305  * @out: (out) (transfer full): a copy of "second"
306  *
307  * Returns: (transfer full): a copy of "first"
308  */
309 char *
310 test_utf8_out_nonconst_return (char **out)
311 {
312   *out = g_strdup ("second");
313   return g_strdup ("first");
314 }
315
316
317 /* non-basic-types */
318
319 static const char *test_sequence[] = {"1", "2", "3"};
320
321 /* array */
322
323 /**
324  * test_array_int_in:
325  * @n_ints:
326  * @ints: (array length=n_ints): List of ints
327  */
328 int
329 test_array_int_in (int n_ints, int *ints)
330 {
331   int i, sum = 0;
332   for (i = 0; i < n_ints; i++)
333     sum += ints[i];
334   return sum;
335 }
336
337 /**
338  * test_array_int_out:
339  * @n_ints: (out): the length of @ints
340  * @ints: (out) (array length=n_ints) (transfer full): a list of 5 integers, from 0 to 4 in consecutive order
341  */
342 void
343 test_array_int_out (int *n_ints, int **ints)
344 {
345   int i;
346   *n_ints = 5;
347   *ints = g_malloc0(sizeof(**ints) * *n_ints);
348   for (i = 1; i < *n_ints; i++)
349     (*ints)[i] = (*ints)[i-1] + 1;
350 }
351
352 /**
353  * test_array_int_inout:
354  * @n_ints: (inout): the length of @ints
355  * @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
356  */
357 void
358 test_array_int_inout (int *n_ints, int **ints)
359 {
360   int i;
361
362   for (i = 1; i < *n_ints; i++) {
363         (*ints)[i-1] = (*ints)[i] + 1;
364   }
365
366   if (0 < *n_ints) {
367     *n_ints -= 1;
368   }
369   *ints = g_realloc(*ints, sizeof(**ints) * *n_ints);
370 }
371
372 /**
373  * test_array_gint8_in:
374  * @n_ints:
375  * @ints: (array length=n_ints): List of ints
376  */
377 int
378 test_array_gint8_in (int n_ints, gint8 *ints)
379 {
380   int i, sum = 0;
381   for (i = 0; i < n_ints; i++)
382     sum += ints[i];
383   return sum;
384 }
385
386 /**
387  * test_array_gint16_in:
388  * @n_ints:
389  * @ints: (array length=n_ints): List of ints
390  */
391 int
392 test_array_gint16_in (int n_ints, gint16 *ints)
393 {
394   int i, sum = 0;
395   for (i = 0; i < n_ints; i++)
396     sum += ints[i];
397   return sum;
398 }
399
400 /**
401  * test_array_gint32_in:
402  * @n_ints:
403  * @ints: (array length=n_ints): List of ints
404  */
405 gint32
406 test_array_gint32_in (int n_ints, gint32 *ints)
407 {
408   int i;
409   gint32 sum = 0;
410   for (i = 0; i < n_ints; i++)
411     sum += ints[i];
412   return sum;
413 }
414
415 /**
416  * test_array_gint64_in:
417  * @n_ints:
418  * @ints: (array length=n_ints): List of ints
419  */
420 gint64
421 test_array_gint64_in (int n_ints, gint64 *ints)
422 {
423   int i;
424   gint64 sum = 0;
425   for (i = 0; i < n_ints; i++)
426     sum += ints[i];
427   return sum;
428 }
429
430 /**
431  * test_strv_in:
432  * @arr: (array zero-terminated=1) (transfer none):
433  */
434 gboolean
435 test_strv_in (char **arr)
436 {
437   if (g_strv_length (arr) != 3)
438     return FALSE;
439   if (strcmp (arr[0], "1") != 0)
440     return FALSE;
441   if (strcmp (arr[1], "2") != 0)
442     return FALSE;
443   if (strcmp (arr[2], "3") != 0)
444     return FALSE;
445   return TRUE;
446 }
447
448 /**
449  * test_strv_in_container:
450  * @arr: (array zero-terminated=1) (transfer container):
451  */
452 gboolean
453 test_strv_in_container (char **arr)
454 {
455   gboolean result = test_strv_in (arr);
456   g_free (arr);
457   return result;
458 }
459
460 /**
461  * test_array_gtype_in:
462  * @n_types:
463  * @types: (array length=n_types): List of types
464  * Return value: string representation of provided types
465  * */
466 char *
467 test_array_gtype_in (int n_types, GType *types)
468 {
469   GString *string;
470   int i;
471
472   string = g_string_new ("[");
473   for (i = 0; i < n_types; i++)
474     {
475       g_string_append (string, g_type_name (types[i]));
476       g_string_append_c (string, ',');
477     }
478   g_string_append_c (string, ']');
479   return g_string_free (string, FALSE);
480 }
481
482 /**
483  * test_strv_out:
484  *
485  * No annotations here.  We want the default to Do The Right Thing.
486  */
487 char **
488 test_strv_out (void)
489 {
490   int i = 0;
491   int n = 6;
492   char **ret = g_new (char *, n);
493   ret[i++] = g_strdup ("thanks");
494   ret[i++] = g_strdup ("for");
495   ret[i++] = g_strdup ("all");
496   ret[i++] = g_strdup ("the");
497   ret[i++] = g_strdup ("fish");
498   ret[i++] = NULL;
499   g_assert (i == n);
500   return ret;
501 }
502
503 /**
504  * test_strv_out_container:
505  *
506  * Return value: (array zero-terminated=1) (transfer container):
507  */
508 char **
509 test_strv_out_container (void)
510 {
511   char **ret = g_new (char *, 4);
512   ret[0] = "1";
513   ret[1] = "2";
514   ret[2] = "3";
515   ret[3] = NULL;
516   return ret;
517 }
518
519 /**
520  * test_strv_outarg:
521  * @retp: (array zero-terminated=1) (out) (transfer container):
522  */
523 void
524 test_strv_outarg (char ***retp)
525 {
526   char **ret = g_new (char *, 4);
527   ret[0] = "1";
528   ret[1] = "2";
529   ret[2] = "3";
530   ret[3] = NULL;
531   *retp = ret;
532 }
533
534 /**
535  * test_array_fixed_size_int_in:
536  * @ints: (array fixed-size=5): a list of 5 integers
537  *
538  * Returns: the sum of the items in @ints
539  */
540 int
541 test_array_fixed_size_int_in (int *ints)
542 {
543   int i, sum = 0;
544   for (i = 0; i < 5; i++)
545     sum += ints[i];
546   return sum;
547 }
548
549 /**
550  * test_array_fixed_size_int_out:
551  * @ints: (out) (array fixed-size=5) (transfer full): a list of 5 integers ranging from 0 to 4
552  */
553 void
554 test_array_fixed_size_int_out (int **ints)
555 {
556   int i;
557   *ints = g_malloc0(sizeof(**ints) * 5);
558   for (i = 1; i < 5; i++)
559     (*ints)[i] = (*ints)[i-1] + 1;
560 }
561
562 /**
563  * test_array_fixed_size_int_return:
564  * Returns: (array fixed-size=5) (transfer full): a list of 5 integers ranging from 0 to 4
565  */
566 int *
567 test_array_fixed_size_int_return (void)
568 {
569   int i, *ints;
570   ints = g_malloc0(sizeof(*ints) * 5);
571   for (i = 1; i < 5; i++)
572     ints[i] = ints[i-1] + 1;
573   return ints;
574 }
575
576 /**
577  * test_array_int_in_take:
578  * @n_ints:
579  * @ints: (array length=n_ints) (transfer full): List of ints
580  */
581 int test_array_int_in_take (int n_ints, int *ints)
582 {
583   int i, sum = 0;
584   for (i = 0; i < n_ints; i++)
585     sum += ints[i];
586   g_free (ints);
587   return sum;
588 }
589
590 /**
591  * test_strv_out_c:
592  *
593  * No annotations here.  We want the default to Do The Right Thing.
594  */
595 const char * const*
596 test_strv_out_c (void)
597 {
598   static char **ret = NULL;
599
600   if (ret == NULL)
601     ret = test_strv_out ();
602
603   return (const char * const *) ret;
604 }
605
606 /**
607  * test_array_int_full_out:
608  * @len: length of the returned array.
609  * Returns: (array length=len) (transfer full): a new array of integers.
610  */
611 int *
612 test_array_int_full_out(int *len) {
613   int *result, i;
614   *len = 5;
615   result = g_malloc0(sizeof(*result) * (*len));
616   for (i=1; i < (*len); i++)
617     result[i] = result[i-1] + 1;
618   return result;
619 }
620
621 /**
622  * test_array_int_none_out:
623  * @len: length of the returned array.
624  * Returns: (array length=len) (transfer none): a static array of integers.
625  */
626 int *
627 test_array_int_none_out(int *len) {
628   static int result[5] = { 1, 2, 3, 4, 5 };
629   *len = 5;
630   return result;
631 }
632
633 /* interface */
634
635 /************************************************************************/
636 /* GList */
637
638 static /*const*/ GList *test_sequence_list()
639 {
640     static GList *list = NULL;
641     if (!list) {
642         gsize i;
643         for (i = 0; i < G_N_ELEMENTS(test_sequence); ++i) {
644             list = g_list_prepend (list, (gpointer)test_sequence[i]);
645         }
646         list = g_list_reverse (list);
647     }
648     return list;
649 }
650
651 /**
652  * test_glist_free:
653  * @in: (element-type utf8) (transfer full):
654  */
655 void test_glist_free (GList *in)
656 {
657   g_list_foreach (in, (GFunc)g_free, NULL);
658   g_list_free (in);
659 }
660
661 /**
662  * test_glist_nothing_return:
663  *
664  * Return value: (element-type utf8) (transfer none):
665  */
666 G_CONST_RETURN GList *test_glist_nothing_return (void)
667 {
668   return test_sequence_list ();
669 }
670
671 /**
672  * test_glist_nothing_return2:
673  *
674  * Return value: (element-type utf8) (transfer none):
675  */
676 GList *test_glist_nothing_return2 (void)
677 {
678   return test_sequence_list ();
679 }
680
681 /**
682  * test_glist_container_return:
683  *
684  * Return value: (element-type utf8) (transfer container):
685  */
686 GList *test_glist_container_return (void)
687 {
688   return g_list_copy (test_sequence_list ());
689 }
690
691 /**
692  * test_glist_everything_return:
693  *
694  * Return value: (element-type utf8) (transfer full):
695  */
696 GList *test_glist_everything_return (void)
697 {
698   GList *list;
699   GList *l;
700
701   list = g_list_copy (test_sequence_list ());
702   for (l = list; l != NULL; l = l->next)
703       l->data = g_strdup (l->data);
704   return list;
705 }
706
707 static void assert_test_sequence_list (const GList *in)
708 {
709   const GList *l;
710   gsize i;
711
712   for (i = 0, l = in; l != NULL; ++i, l = l->next) {
713       g_assert (i < G_N_ELEMENTS(test_sequence));
714       g_assert (strcmp (l->data, test_sequence[i]) == 0);
715   }
716   g_assert (i == G_N_ELEMENTS(test_sequence));
717 }
718
719 /**
720  * test_glist_nothing_in:
721  * @in: (element-type utf8):
722  */
723 void test_glist_nothing_in (const GList *in)
724 {
725   assert_test_sequence_list (in);
726 }
727
728 /**
729  * test_glist_nothing_in2:
730  * @in: (element-type utf8):
731  */
732 void test_glist_nothing_in2 (GList *in)
733 {
734   assert_test_sequence_list (in);
735 }
736
737 /**
738  * test_glist_container_in:
739  * @in: (element-type utf8) (transfer container):
740  */
741 void test_glist_container_in (GList *in)
742 {
743   assert_test_sequence_list (in);
744   g_list_free (in);
745 }
746
747 /**
748  * test_glist_everything_in:
749  * @in: (element-type utf8) (transfer full):
750  */
751 void test_glist_everything_in (GList *in)
752 {
753   assert_test_sequence_list (in);
754   test_glist_free (in);
755 }
756
757 /************************************************************************/
758 /* GSList */
759
760 static /*const*/ GSList *test_sequence_slist()
761 {
762     static GSList *list = NULL;
763     if (!list) {
764         gsize i;
765         for (i = 0; i < G_N_ELEMENTS(test_sequence); ++i) {
766             list = g_slist_prepend (list, (gpointer)test_sequence[i]);
767         }
768         list = g_slist_reverse (list);
769     }
770     return list;
771 }
772
773 /**
774  * test_gslist_free:
775  * @in: (element-type utf8) (transfer full):
776  */
777 void test_gslist_free (GSList *in)
778 {
779   g_slist_foreach (in, (GFunc)g_free, NULL);
780   g_slist_free (in);
781 }
782
783 /**
784  * test_gslist_nothing_return:
785  *
786  * Return value: (element-type utf8) (transfer none):
787  */
788 G_CONST_RETURN GSList *test_gslist_nothing_return (void)
789 {
790   return test_sequence_slist ();
791 }
792
793 /**
794  * test_gslist_nothing_return2:
795  *
796  * Return value: (element-type utf8) (transfer none):
797  */
798 GSList *test_gslist_nothing_return2 (void)
799 {
800   return test_sequence_slist ();
801 }
802
803 /**
804  * test_gslist_container_return:
805  *
806  * Return value: (element-type utf8) (transfer container):
807  */
808 GSList *test_gslist_container_return (void)
809 {
810   return g_slist_copy (test_sequence_slist ());
811 }
812
813 /**
814  * test_gslist_everything_return:
815  *
816  * Return value: (element-type utf8) (transfer full):
817  */
818 GSList *test_gslist_everything_return (void)
819 {
820   GSList *list;
821   GSList *l;
822
823   list = g_slist_copy (test_sequence_slist ());
824   for (l = list; l != NULL; l = l->next)
825       l->data = g_strdup (l->data);
826   return list;
827 }
828
829 static void assert_test_sequence_slist (const GSList *in)
830 {
831   const GSList *l;
832   gsize i;
833
834   for (i = 0, l = in; l != NULL; ++i, l = l->next) {
835       g_assert (i < G_N_ELEMENTS(test_sequence));
836       g_assert (strcmp (l->data, test_sequence[i]) == 0);
837   }
838   g_assert (i == G_N_ELEMENTS(test_sequence));
839 }
840
841 /**
842  * test_gslist_nothing_in:
843  * @in: (element-type utf8):
844  */
845 void test_gslist_nothing_in (const GSList *in)
846 {
847   assert_test_sequence_slist (in);
848 }
849
850 /**
851  * test_gslist_nothing_in2:
852  * @in: (element-type utf8):
853  */
854 void test_gslist_nothing_in2 (GSList *in)
855 {
856   assert_test_sequence_slist (in);
857 }
858
859 /**
860  * test_gslist_container_in:
861  * @in: (element-type utf8) (transfer container):
862  */
863 void test_gslist_container_in (GSList *in)
864 {
865   assert_test_sequence_slist (in);
866   g_slist_free (in);
867 }
868
869 /**
870  * test_gslist_everything_in:
871  * @in: (element-type utf8) (transfer full):
872  */
873 void test_gslist_everything_in (GSList *in)
874 {
875   assert_test_sequence_slist (in);
876   test_gslist_free (in);
877 }
878
879 /************************************************************************/
880 /* GHash */
881
882 static char *table_data[3][2] = {
883   { "foo", "bar" }, { "baz", "bat" }, { "qux", "quux" }
884 };
885
886 static GHashTable *test_table_ghash_new_container()
887 {
888   GHashTable *hash;
889   int i;
890   hash = g_hash_table_new(g_str_hash, g_str_equal);
891   for (i=0; i<3; i++)
892     g_hash_table_insert(hash, table_data[i][0], table_data[i][1]);
893   return hash;
894 }
895
896 static GHashTable *test_table_ghash_new_full()
897 {
898   GHashTable *hash;
899   int i;
900   hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
901   for (i=0; i<3; i++)
902     g_hash_table_insert(hash,
903                         g_strdup(table_data[i][0]),
904                         g_strdup(table_data[i][1]));
905   return hash;
906 }
907
908 static /*const*/ GHashTable *test_table_ghash_const()
909 {
910   static GHashTable *hash = NULL;
911   if (!hash) {
912     hash = test_table_ghash_new_container();
913   }
914   return hash;
915 }
916
917 /**
918  * test_ghash_free:
919  * @in: (transfer full) (element-type utf8 utf8)
920  */
921 void test_ghash_free (GHashTable *in)
922 {
923   /* keys and values are deleted iff an appropriate element destroy function
924    * was registered */
925   g_hash_table_unref(in);
926 }
927
928 /**
929  * test_ghash_null_return:
930  *
931  * Return value: (element-type utf8 utf8) (transfer none) (allow-none):
932  */
933 G_CONST_RETURN GHashTable *test_ghash_null_return (void)
934 {
935   return NULL;
936 }
937
938 /**
939  * test_ghash_nothing_return:
940  *
941  * Return value: (element-type utf8 utf8) (transfer none):
942  */
943 G_CONST_RETURN GHashTable *test_ghash_nothing_return (void)
944 {
945   return test_table_ghash_const ();
946 }
947
948 /**
949  * test_ghash_nothing_return2:
950  *
951  * Return value: (element-type utf8 utf8) (transfer none):
952  */
953 GHashTable *test_ghash_nothing_return2 (void)
954 {
955   return test_table_ghash_const ();
956 }
957
958 /**
959  * test_ghash_container_return:
960  *
961  * Return value: (element-type utf8 utf8) (transfer container):
962  */
963 GHashTable *test_ghash_container_return (void)
964 {
965   return test_table_ghash_new_container ();
966 }
967
968 /**
969  * test_ghash_everything_return:
970  *
971  * Return value: (element-type utf8 utf8) (transfer full):
972  */
973 GHashTable *test_ghash_everything_return (void)
974 {
975   return test_table_ghash_new_full ();
976 }
977
978 static void assert_test_table_ghash (const GHashTable *in)
979 {
980   GHashTable *h = test_table_ghash_const();
981   GHashTableIter iter;
982   gpointer key, value;
983
984   g_assert(g_hash_table_size(h) ==
985            g_hash_table_size((GHashTable*)in));
986
987   g_hash_table_iter_init(&iter, (GHashTable*)in);
988   while (g_hash_table_iter_next (&iter, &key, &value))
989     g_assert( strcmp(g_hash_table_lookup(h, (char*)key), (char*)value) == 0);
990 }
991
992 /**
993  * test_ghash_null_in:
994  * @in: (element-type utf8 utf8) (allow-none):
995  */
996 void test_ghash_null_in (const GHashTable *in)
997 {
998   g_assert (in == NULL);
999 }
1000
1001 /**
1002  * test_ghash_nothing_in:
1003  * @in: (element-type utf8 utf8):
1004  */
1005 void test_ghash_nothing_in (const GHashTable *in)
1006 {
1007   assert_test_table_ghash (in);
1008 }
1009
1010 /**
1011  * test_ghash_nothing_in2:
1012  * @in: (element-type utf8 utf8):
1013  */
1014 void test_ghash_nothing_in2 (GHashTable *in)
1015 {
1016   assert_test_table_ghash (in);
1017 }
1018
1019 /**
1020  * test_ghash_container_in:
1021  * @in: (transfer container) (element-type utf8 utf8):
1022  */
1023 void test_ghash_container_in (GHashTable *in)
1024 {
1025   assert_test_table_ghash (in);
1026   /* be careful and explicitly steal all the elements from the ghash before
1027    * freeing it. */
1028   g_hash_table_steal_all (in);
1029   g_hash_table_destroy (in);
1030 }
1031
1032 static gboolean ghash_freer(gpointer key, gpointer value, gpointer user_data) {
1033   g_free(key);
1034   g_free(value);
1035   return TRUE;
1036 }
1037
1038 /**
1039  * test_ghash_everything_in:
1040  * @in: (transfer full) (element-type utf8 utf8):
1041  */
1042 void test_ghash_everything_in (GHashTable *in)
1043 {
1044   assert_test_table_ghash (in);
1045   /* free the elements, then free the container.  Don't rely on the
1046    * GHashTable's key/value destructor functions. */
1047   g_hash_table_foreach_steal (in, ghash_freer, NULL);
1048   /* okay, dealloc the hash table. */
1049   g_hash_table_destroy (in);
1050 }
1051
1052 /* Nested collection types */
1053
1054 /**
1055  * test_ghash_nested_everything_return:
1056  * Specify nested parameterized types directly with the (type ) annotation.
1057  *
1058  * Return value: (type GLib.HashTable<utf8,GLib.HashTable<utf8,utf8>>) (transfer full):
1059  */
1060 GHashTable *
1061 test_ghash_nested_everything_return (void)
1062 {
1063   GHashTable *hash;
1064   hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
1065                                (void (*) (gpointer)) g_hash_table_destroy);
1066   g_hash_table_insert(hash, g_strdup("wibble"), test_table_ghash_new_full());
1067   return hash;
1068 }
1069
1070 /**
1071  * test_ghash_nested_everything_return2:
1072  * Another way of specifying nested parameterized types: using the
1073  * element-type annotation.
1074  *
1075  * Return value: (element-type utf8 GLib.HashTable<utf8,utf8>) (transfer full):
1076  */
1077 GHashTable *
1078 test_ghash_nested_everything_return2 (void)
1079 {
1080   return test_ghash_nested_everything_return();
1081 }
1082
1083 /************************************************************************/
1084
1085 /* error? */
1086
1087 /* enums / flags */
1088
1089 GType
1090 test_enum_get_type (void)
1091 {
1092     static GType etype = 0;
1093     if (G_UNLIKELY(etype == 0)) {
1094         static const GEnumValue values[] = {
1095             { TEST_VALUE1, "TEST_VALUE1", "value1" },
1096             { TEST_VALUE2, "TEST_VALUE2", "value2" },
1097             { TEST_VALUE3, "TEST_VALUE3", "value3" },
1098             { 0, NULL, NULL }
1099         };
1100         etype = g_enum_register_static (g_intern_static_string ("TestEnum"), values);
1101     }
1102
1103     return etype;
1104 }
1105
1106 GType
1107 test_flags_get_type (void)
1108 {
1109     static GType etype = 0;
1110     if (G_UNLIKELY(etype == 0)) {
1111         static const GFlagsValue values[] = {
1112             { TEST_FLAG1, "TEST_FLAG1", "flag1" },
1113             { TEST_FLAG2, "TEST_FLAG2", "flag2" },
1114             { TEST_FLAG3, "TEST_FLAG3", "flag3" },
1115             { 0, NULL, NULL }
1116         };
1117         etype = g_flags_register_static (g_intern_static_string ("TestFlags"), values);
1118     }
1119
1120     return etype;
1121 }
1122
1123 const gchar *
1124 test_enum_param(TestEnum e)
1125 {
1126   GEnumValue *ev;
1127   GEnumClass *ec;
1128
1129   ec = g_type_class_ref (test_enum_get_type ());
1130   ev = g_enum_get_value (ec, e);
1131   g_type_class_unref (ec);
1132
1133   return ev->value_nick;
1134 }
1135
1136 /* structures */
1137
1138 /**
1139  * test_struct_a_clone:
1140  * @a: the structure
1141  * @a_out: the cloned structure
1142  *
1143  * Make a copy of a TestStructA
1144  */
1145 void
1146 test_struct_a_clone (TestStructA *a,
1147                      TestStructA *a_out)
1148 {
1149   *a_out = *a;
1150 }
1151
1152 /**
1153  * test_struct_b_clone:
1154  * @b: the structure
1155  * @b_out: the cloned structure
1156  *
1157  * Make a copy of a TestStructB
1158  */
1159 void
1160 test_struct_b_clone (TestStructB *b,
1161                      TestStructB *b_out)
1162 {
1163   *b_out = *b;
1164 }
1165
1166 /* plain-old-data boxed types */
1167
1168 TestSimpleBoxedA *
1169 test_simple_boxed_a_copy (TestSimpleBoxedA *a)
1170 {
1171   TestSimpleBoxedA *new_a = g_slice_new (TestSimpleBoxedA);
1172
1173   *new_a = *a;
1174
1175   return new_a;
1176 }
1177
1178 static void
1179 test_simple_boxed_a_free (TestSimpleBoxedA *a)
1180 {
1181   g_slice_free (TestSimpleBoxedA, a);
1182 }
1183
1184 GType
1185 test_simple_boxed_a_get_type (void)
1186 {
1187   static GType our_type = 0;
1188
1189   if (our_type == 0)
1190     our_type = g_boxed_type_register_static (g_intern_static_string ("TestSimpleBoxedA"),
1191                                              (GBoxedCopyFunc)test_simple_boxed_a_copy,
1192                                              (GBoxedFreeFunc)test_simple_boxed_a_free);
1193   return our_type;
1194 }
1195
1196 TestSimpleBoxedB *
1197 test_simple_boxed_b_copy (TestSimpleBoxedB *b)
1198 {
1199   TestSimpleBoxedB *new_b = g_slice_new (TestSimpleBoxedB);
1200
1201   *new_b = *b;
1202
1203   return new_b;
1204 }
1205
1206 gboolean
1207 test_simple_boxed_a_equals (TestSimpleBoxedA *a,
1208                             TestSimpleBoxedA *other_a)
1209 {
1210   return (a->some_int == other_a->some_int &&
1211           a->some_int8 == other_a->some_int8 &&
1212           a->some_double == other_a->some_double);
1213 }
1214
1215 const TestSimpleBoxedA*
1216 test_simple_boxed_a_const_return (void)
1217 {
1218   static TestSimpleBoxedA simple_a = {
1219     5, 6, 7.0
1220   };
1221
1222   return &simple_a;
1223 }
1224
1225 static void
1226 test_simple_boxed_b_free (TestSimpleBoxedB *a)
1227 {
1228   g_slice_free (TestSimpleBoxedB, a);
1229 }
1230
1231 GType
1232 test_simple_boxed_b_get_type (void)
1233 {
1234   static GType our_type = 0;
1235
1236   if (our_type == 0)
1237     our_type = g_boxed_type_register_static (g_intern_static_string ("TestSimpleBoxedB"),
1238                                              (GBoxedCopyFunc)test_simple_boxed_b_copy,
1239                                              (GBoxedFreeFunc)test_simple_boxed_b_free);
1240   return our_type;
1241 }
1242
1243 /* opaque boxed */
1244
1245 struct _TestBoxedPrivate
1246 {
1247   guint magic;
1248 };
1249
1250 TestBoxed *
1251 test_boxed_new (void)
1252 {
1253   TestBoxed *boxed = g_slice_new0(TestBoxed);
1254   boxed->priv = g_slice_new0(TestBoxedPrivate);
1255   boxed->priv->magic = 0xdeadbeef;
1256
1257   return boxed;
1258 }
1259
1260 TestBoxed *
1261 test_boxed_new_alternative_constructor1 (int i)
1262 {
1263   TestBoxed *boxed = g_slice_new0(TestBoxed);
1264   boxed->priv = g_slice_new0(TestBoxedPrivate);
1265   boxed->priv->magic = 0xdeadbeef;
1266   boxed->some_int8 = i;
1267
1268   return boxed;
1269 }
1270
1271 TestBoxed *
1272 test_boxed_new_alternative_constructor2 (int i, int j)
1273 {
1274   TestBoxed *boxed = g_slice_new0(TestBoxed);
1275   boxed->priv = g_slice_new0(TestBoxedPrivate);
1276   boxed->priv->magic = 0xdeadbeef;
1277   boxed->some_int8 = i + j;
1278
1279   return boxed;
1280 }
1281
1282 TestBoxed *
1283 test_boxed_new_alternative_constructor3 (char *s)
1284 {
1285   TestBoxed *boxed = g_slice_new0(TestBoxed);
1286   boxed->priv = g_slice_new0(TestBoxedPrivate);
1287   boxed->priv->magic = 0xdeadbeef;
1288   boxed->some_int8 = atoi(s);
1289
1290   return boxed;
1291 }
1292
1293 TestBoxed *
1294 test_boxed_copy (TestBoxed *boxed)
1295 {
1296   TestBoxed *new_boxed = test_boxed_new();
1297   TestBoxedPrivate *save;
1298
1299   save = new_boxed->priv;
1300   *new_boxed = *boxed;
1301   new_boxed->priv = save;
1302
1303   return new_boxed;
1304 }
1305
1306 gboolean
1307 test_boxed_equals (TestBoxed *boxed,
1308                    TestBoxed *other)
1309 {
1310   return (other->some_int8 == boxed->some_int8 &&
1311           test_simple_boxed_a_equals(&other->nested_a, &boxed->nested_a));
1312 }
1313
1314 static void
1315 test_boxed_free (TestBoxed *boxed)
1316 {
1317   g_assert (boxed->priv->magic == 0xdeadbeef);
1318
1319   g_slice_free (TestBoxedPrivate, boxed->priv);
1320   g_slice_free (TestBoxed, boxed);
1321 }
1322
1323 GType
1324 test_boxed_get_type (void)
1325 {
1326   static GType our_type = 0;
1327
1328   if (our_type == 0)
1329     our_type = g_boxed_type_register_static (g_intern_static_string ("TestBoxed"),
1330                                              (GBoxedCopyFunc)test_boxed_copy,
1331                                              (GBoxedFreeFunc)test_boxed_free);
1332   return our_type;
1333 }
1334
1335 G_DEFINE_TYPE(TestObj, test_obj, G_TYPE_OBJECT);
1336
1337 enum
1338 {
1339   PROP_TEST_OBJ_BARE = 1,
1340   PROP_TEST_OBJ_BOXED
1341 };
1342
1343 static void
1344 test_obj_set_property (GObject      *object,
1345                        guint         property_id,
1346                        const GValue *value,
1347                        GParamSpec   *pspec)
1348 {
1349   TestObj *self = TEST_OBJECT (object);
1350
1351   switch (property_id)
1352     {
1353     case PROP_TEST_OBJ_BARE:
1354       test_obj_set_bare (self, g_value_get_object (value));
1355       break;
1356
1357     case PROP_TEST_OBJ_BOXED:
1358       if (self->boxed)
1359         test_boxed_free (self->boxed);
1360       self->boxed = g_value_dup_boxed (value);
1361       break;
1362       
1363     default:
1364       /* We don't have any other property... */
1365       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1366       break;
1367     }
1368 }
1369
1370 static void
1371 test_obj_get_property (GObject    *object,
1372                         guint       property_id,
1373                         GValue     *value,
1374                         GParamSpec *pspec)
1375 {
1376   TestObj *self = TEST_OBJECT (object);
1377
1378   switch (property_id)
1379     {
1380     case PROP_TEST_OBJ_BARE:
1381       g_value_set_object (value, self->bare);
1382       break;
1383
1384     case PROP_TEST_OBJ_BOXED:
1385       g_value_set_boxed (value, self->boxed);
1386       break;
1387       
1388     default:
1389       /* We don't have any other property... */
1390       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1391       break;
1392     }
1393 }
1394
1395 static void
1396 test_obj_dispose (GObject *gobject)
1397 {
1398   TestObj *self = TEST_OBJECT (gobject);
1399
1400   if (self->bare)
1401     {
1402       g_object_unref (self->bare);
1403
1404       self->bare = NULL;
1405     }
1406
1407   if (self->boxed)
1408     {
1409       test_boxed_free (self->boxed);
1410       self->boxed = NULL;
1411     }
1412   
1413   /* Chain up to the parent class */
1414   G_OBJECT_CLASS (test_obj_parent_class)->dispose (gobject);
1415 }
1416
1417 static int
1418 test_obj_default_matrix (TestObj *obj, const char *somestr)
1419 {
1420   return 42;
1421 }
1422
1423 static void
1424 test_obj_class_init (TestObjClass *klass)
1425 {
1426   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1427   GParamSpec *pspec;
1428   GType param_types[1];
1429
1430   klass->test_signal =
1431     g_signal_newv ("test",
1432                    G_TYPE_FROM_CLASS (gobject_class),
1433                    G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
1434                    NULL /* closure */,
1435                    NULL /* accumulator */,
1436                    NULL /* accumulator data */,
1437                    g_cclosure_marshal_VOID__VOID,
1438                    G_TYPE_NONE /* return_type */,
1439                    0     /* n_params */,
1440                    NULL  /* param_types */);
1441
1442   param_types[0] = test_simple_boxed_a_get_type() | G_SIGNAL_TYPE_STATIC_SCOPE;
1443   klass->test_signal_with_static_scope_arg =
1444     g_signal_newv ("test-with-static-scope-arg",
1445                    G_TYPE_FROM_CLASS (gobject_class),
1446                    G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
1447                    NULL /* closure */,
1448                    NULL /* accumulator */,
1449                    NULL /* accumulator data */,
1450                    g_cclosure_marshal_VOID__BOXED,
1451                    G_TYPE_NONE /* return_type */,
1452                    1     /* n_params */,
1453                    param_types);
1454
1455   gobject_class->set_property = test_obj_set_property;
1456   gobject_class->get_property = test_obj_get_property;
1457   gobject_class->dispose = test_obj_dispose;
1458
1459   pspec = g_param_spec_object ("bare",
1460                                "Bare property",
1461                                "A contained object",
1462                                G_TYPE_OBJECT,
1463                                G_PARAM_READWRITE);
1464   g_object_class_install_property (gobject_class,
1465                                    PROP_TEST_OBJ_BARE,
1466                                    pspec);
1467
1468   pspec = g_param_spec_boxed ("boxed",
1469                               "Boxed property",
1470                               "A contained boxed struct",
1471                               TEST_TYPE_BOXED,
1472                               G_PARAM_READWRITE);
1473   g_object_class_install_property (gobject_class,
1474                                    PROP_TEST_OBJ_BOXED,
1475                                    pspec);
1476   
1477   klass->matrix = test_obj_default_matrix;
1478 }
1479
1480 static void
1481 test_obj_init (TestObj *obj)
1482 {
1483   obj->bare = NULL;
1484   obj->boxed = NULL;
1485 }
1486
1487 TestObj *
1488 test_obj_new_from_file (const char *x, GError **error)
1489 {
1490   return g_object_new (TEST_TYPE_OBJ, NULL);
1491 }
1492
1493 /**
1494  * test_obj_set_bare:
1495  * @bare: (allow-none):
1496  */
1497 void
1498 test_obj_set_bare (TestObj *obj, GObject *bare)
1499 {
1500   if (obj->bare)
1501     g_object_unref (obj->bare);
1502   obj->bare = bare;
1503   if (obj->bare)
1504     g_object_ref (obj->bare);
1505 }
1506
1507 int
1508 test_obj_instance_method (TestObj *obj)
1509 {
1510     return -1;
1511 }
1512
1513 double
1514 test_obj_static_method (int x)
1515 {
1516   return x;
1517 }
1518
1519 /**
1520  * test_obj_torture_signature_0:
1521  * @obj: A #TestObj
1522  * @x:
1523  * @y: (out):
1524  * @z: (out):
1525  * @foo:
1526  * @q: (out):
1527  * @m:
1528  *
1529  */
1530 void
1531 test_obj_torture_signature_0 (TestObj    *obj,
1532                               int         x,
1533                               double     *y,
1534                               int        *z,
1535                               const char *foo,
1536                               int        *q,
1537                               guint       m)
1538 {
1539   *y = x;
1540   *z = x * 2;
1541   *q = g_utf8_strlen (foo, -1) + m;
1542 }
1543
1544 /**
1545  * test_obj_torture_signature_1:
1546  * @obj: A #TestObj
1547  * @x:
1548  * @y: (out):
1549  * @z: (out):
1550  * @foo:
1551  * @q: (out):
1552  * @m:
1553  * @error: A #GError
1554  *
1555  * This function throws an error if m is odd.
1556  */
1557 gboolean
1558 test_obj_torture_signature_1 (TestObj   *obj,
1559                               int        x,
1560                               double     *y,
1561                               int        *z,
1562                               const char *foo,
1563                               int        *q,
1564                               guint       m,
1565                               GError    **error)
1566 {
1567   *y = x;
1568   *z = x * 2;
1569   *q = g_utf8_strlen (foo, -1) + m;
1570   if (m % 2 == 0)
1571       return TRUE;
1572   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "m is odd");
1573   return FALSE;
1574 }
1575
1576 /**
1577  * test_obj_do_matrix:
1578  * @obj: A #TestObj
1579  * @somestr: Meaningless string
1580  *
1581  * This method is virtual.  Notably its name differs from the virtual
1582  * slot name, which makes it useful for testing bindings handle this
1583  * case.
1584  *
1585  * Virtual: matrix
1586  */
1587 int
1588 test_obj_do_matrix (TestObj *obj, const char *somestr)
1589 {
1590   return TEST_OBJ_GET_CLASS (obj)->matrix (obj, somestr);
1591 }
1592
1593 typedef struct _CallbackInfo CallbackInfo;
1594
1595 struct _CallbackInfo
1596 {
1597   TestCallbackUserData callback;
1598   GDestroyNotify notify;
1599   gpointer user_data;
1600 };
1601
1602
1603 G_DEFINE_TYPE(TestSubObj, test_sub_obj, TEST_TYPE_OBJ);
1604
1605 static void
1606 test_sub_obj_class_init (TestSubObjClass *klass)
1607 {
1608 }
1609
1610 static void
1611 test_sub_obj_init (TestSubObj *obj)
1612 {
1613 }
1614
1615 TestSubObj*
1616 test_sub_obj_new ()
1617 {
1618   return g_object_new (TEST_TYPE_SUB_OBJ, NULL);
1619 }
1620
1621 int
1622 test_sub_obj_instance_method (TestSubObj *obj)
1623 {
1624     return 0;
1625 }
1626
1627 void
1628 test_sub_obj_unset_bare (TestSubObj *obj)
1629 {
1630   test_obj_set_bare(TEST_OBJECT(obj), NULL);
1631 }
1632
1633
1634 /**
1635  * test_callback:
1636  * @callback: (scope call) (allow-none):
1637  *
1638  **/
1639 int
1640 test_callback (TestCallback callback)
1641 {
1642     if (callback != NULL)
1643         return callback();
1644     return 0;
1645 }
1646
1647 /**
1648  * test_callback_user_data:
1649  * @callback: (scope call):
1650  *
1651  * Call - callback parameter persists for the duration of the method
1652  * call and can be released on return.
1653  **/
1654 int
1655 test_callback_user_data (TestCallbackUserData callback,
1656                          gpointer user_data)
1657 {
1658   return callback(user_data);
1659 }
1660
1661 static GSList *notified_callbacks = NULL;
1662
1663 /**
1664  * test_callback_destroy_notify:
1665  * @callback: (scope notified):
1666  *
1667  * Notified - callback persists until a DestroyNotify delegate
1668  * is invoked.
1669  **/
1670 int
1671 test_callback_destroy_notify (TestCallbackUserData callback,
1672                               gpointer user_data,
1673                               GDestroyNotify notify)
1674 {
1675   int retval;
1676   CallbackInfo *info;
1677
1678   retval = callback(user_data);
1679
1680   info = g_slice_new(CallbackInfo);
1681   info->callback = callback;
1682   info->notify = notify;
1683   info->user_data = user_data;
1684
1685   notified_callbacks = g_slist_prepend(notified_callbacks, info);
1686
1687   return retval;
1688 }
1689
1690 /**
1691  * test_callback_thaw_notifications:
1692  *
1693  * Invokes all callbacks installed by #test_callback_destroy_notify(),
1694  * adding up their return values, and removes them, invoking the
1695  * corresponding destroy notfications.
1696  *
1697  * Return value: Sum of the return values of the invoked callbacks.
1698  */
1699 int
1700 test_callback_thaw_notifications (void)
1701 {
1702   int retval = 0;
1703   GSList *node;
1704
1705   for (node = notified_callbacks; node != NULL; node = node->next)
1706     {
1707       CallbackInfo *info = node->data;
1708       retval += info->callback (info->user_data);
1709       if (info->notify)
1710         info->notify (info->user_data);
1711       g_slice_free (CallbackInfo, info);
1712     }
1713
1714   g_slist_free (notified_callbacks);
1715   notified_callbacks = NULL;
1716
1717   return retval;
1718 }
1719
1720 static GSList *async_callbacks = NULL;
1721
1722 /**
1723  * test_callback_async:
1724  * @callback: (scope async):
1725  *
1726  **/
1727 void
1728 test_callback_async (TestCallbackUserData callback,
1729                      gpointer user_data)
1730 {
1731   CallbackInfo *info;
1732
1733   info = g_slice_new(CallbackInfo);
1734   info->callback = callback;
1735   info->user_data = user_data;
1736
1737   async_callbacks = g_slist_prepend(async_callbacks, info);
1738 }
1739
1740 /**
1741  * test_callback_thaw_async:
1742  */
1743 int
1744 test_callback_thaw_async (void)
1745 {
1746   int retval = 0;
1747   GSList *node;
1748
1749   for (node = async_callbacks; node != NULL; node = node->next)
1750     {
1751       CallbackInfo *info = node->data;
1752       retval = info->callback (info->user_data);
1753       g_slice_free (CallbackInfo, info);
1754     }
1755
1756   g_slist_free (async_callbacks);
1757   async_callbacks = NULL;
1758   return retval;
1759 }
1760
1761 /**
1762  * test_callback_infinite:
1763  * @callback: (scope infinite):
1764  *
1765  * Infinite - callback persists forever.
1766  **/
1767
1768 static GSList *infinite_callbacks = NULL;
1769
1770 int
1771 test_callback_infinite (TestCallbackUserData callback,
1772                        gpointer user_data)
1773 {
1774   infinite_callbacks = g_slist_prepend(infinite_callbacks, callback);
1775
1776   return callback(user_data);
1777 }
1778
1779 /* interface */
1780
1781 static void
1782 test_interface_class_init(void *g_iface)
1783 {
1784 }
1785
1786 GType
1787 test_interface_get_type(void)
1788 {
1789     static GType type = 0;
1790     if (type == 0) {
1791         type = g_type_register_static_simple (G_TYPE_INTERFACE,
1792                                               "EverythingTestInterface",
1793                                               sizeof (TestInterfaceIface),
1794                                               (GClassInitFunc) test_interface_class_init,
1795                                               0, NULL, 0);
1796     }
1797
1798     return type;
1799 }
1800
1801 /* gobject with non-standard prefix */
1802 G_DEFINE_TYPE(TestWi8021x, test_wi_802_1x, G_TYPE_OBJECT);
1803
1804 enum
1805 {
1806   PROP_TEST_WI_802_1X_TESTBOOL = 1
1807 };
1808
1809 static void
1810 test_wi_802_1x_set_property (GObject      *object,
1811                              guint         property_id,
1812                              const GValue *value,
1813                              GParamSpec   *pspec)
1814 {
1815   TestWi8021x *self = TEST_WI_802_1X (object);
1816
1817   switch (property_id)
1818     {
1819     case PROP_TEST_WI_802_1X_TESTBOOL:
1820       test_wi_802_1x_set_testbool (self, g_value_get_boolean (value));
1821       break;
1822
1823     default:
1824       /* We don't have any other property... */
1825       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1826       break;
1827     }
1828 }
1829
1830 static void
1831 test_wi_802_1x_get_property (GObject    *object,
1832                         guint       property_id,
1833                         GValue     *value,
1834                         GParamSpec *pspec)
1835 {
1836   TestWi8021x *self = TEST_WI_802_1X (object);
1837
1838   switch (property_id)
1839     {
1840     case PROP_TEST_WI_802_1X_TESTBOOL:
1841       g_value_set_boolean (value, test_wi_802_1x_get_testbool (self));
1842       break;
1843
1844     default:
1845       /* We don't have any other property... */
1846       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1847       break;
1848     }
1849 }
1850
1851 static void
1852 test_wi_802_1x_dispose (GObject *gobject)
1853 {
1854   /* Chain up to the parent class */
1855   G_OBJECT_CLASS (test_wi_802_1x_parent_class)->dispose (gobject);
1856 }
1857
1858 static void
1859 test_wi_802_1x_class_init (TestWi8021xClass *klass)
1860 {
1861   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1862   GParamSpec *pspec;
1863
1864   gobject_class->set_property = test_wi_802_1x_set_property;
1865   gobject_class->get_property = test_wi_802_1x_get_property;
1866   gobject_class->dispose = test_wi_802_1x_dispose;
1867
1868   pspec = g_param_spec_boolean ("testbool",
1869                                 "Nick for testbool",
1870                                 "Blurb for testbool",
1871                                 TRUE,
1872                                 G_PARAM_READWRITE);
1873   g_object_class_install_property (gobject_class,
1874                                    PROP_TEST_WI_802_1X_TESTBOOL,
1875                                    pspec);
1876 }
1877
1878 static void
1879 test_wi_802_1x_init (TestWi8021x *obj)
1880 {
1881   obj->testbool = TRUE;
1882 }
1883
1884 TestWi8021x *
1885 test_wi_802_1x_new (void)
1886 {
1887   return g_object_new (TEST_TYPE_WI_802_1X, NULL);
1888 }
1889
1890 void
1891 test_wi_802_1x_set_testbool (TestWi8021x *obj, gboolean val)
1892 {
1893   obj->testbool = val;
1894 }
1895
1896 gboolean
1897 test_wi_802_1x_get_testbool (TestWi8021x *obj)
1898 {
1899   return obj->testbool;
1900 }
1901
1902 int
1903 test_wi_802_1x_static_method (int x)
1904 {
1905   return 2*x;
1906 }
1907
1908 /**
1909  * test_torture_signature_0:
1910  * @x:
1911  * @y: (out):
1912  * @z: (out):
1913  * @foo:
1914  * @q: (out):
1915  * @m:
1916  *
1917  */
1918 void
1919 test_torture_signature_0 (int         x,
1920                           double     *y,
1921                           int        *z,
1922                           const char *foo,
1923                           int        *q,
1924                           guint       m)
1925 {
1926   *y = x;
1927   *z = x * 2;
1928   *q = g_utf8_strlen (foo, -1) + m;
1929 }
1930
1931 /**
1932  * test_torture_signature_1:
1933  * @x:
1934  * @y: (out):
1935  * @z: (out):
1936  * @foo:
1937  * @q: (out):
1938  * @m:
1939  * @error: A #GError
1940  *
1941  * This function throws an error if m is odd.
1942  */
1943 gboolean
1944 test_torture_signature_1 (int         x,
1945                           double     *y,
1946                           int        *z,
1947                           const char *foo,
1948                           int        *q,
1949                           guint       m,
1950                           GError    **error)
1951 {
1952   *y = x;
1953   *z = x * 2;
1954   *q = g_utf8_strlen (foo, -1) + m;
1955   if (m % 2 == 0)
1956       return TRUE;
1957   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "m is odd");
1958   return FALSE;
1959 }
1960
1961 /**
1962  * test_torture_signature_2:
1963  * @x:
1964  * @callback:
1965  * @user_data:
1966  * @notify:
1967  * @y: (out):
1968  * @z: (out):
1969  * @foo:
1970  * @q: (out):
1971  * @m:
1972  *
1973  */
1974 void
1975 test_torture_signature_2 (int                   x,
1976                           TestCallbackUserData  callback,
1977                           gpointer              user_data,
1978                           GDestroyNotify        notify,
1979                           double               *y,
1980                           int                  *z,
1981                           const char           *foo,
1982                           int                  *q,
1983                           guint                 m)
1984 {
1985   *y = x;
1986   *z = x * 2;
1987   *q = g_utf8_strlen (foo, -1) + m;  
1988   notify (user_data);
1989 }
1990