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