2004-12-29 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / tests / libtest.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <glib.h>
5 #include <errno.h>
6 #include <time.h>
7
8 #ifdef WIN32
9 #define STDCALL __stdcall
10 #else
11 #define STDCALL
12 #endif
13
14 #ifdef WIN32
15 extern __declspec(dllimport) __stdcall void CoTaskMemFree(void *ptr);
16 #endif
17
18 typedef int (STDCALL *SimpleDelegate) (int a);
19
20 static void marshal_free (void *ptr)
21 {
22 #ifdef WIN32
23         CoTaskMemFree (ptr);
24 #else
25         g_free (ptr);
26 #endif
27 }
28
29 unsigned short*
30 test_lpwstr_marshal (unsigned short* chars, long length)
31 {
32         int i = 0;
33         unsigned short *res;
34
35         res = malloc (2 * (length + 1));
36
37         // printf("test_lpwstr_marshal()\n");
38         
39         while ( i < length ) {
40                 // printf("X|%u|\n", chars[i]);
41                 res [i] = chars[i];
42                 i++;
43         }
44
45         res [i] = 0;
46
47         return res;
48 }
49
50 typedef struct {
51         int b;
52         int a;
53         int c;
54 } union_test_1_type;
55
56 int mono_union_test_1 (union_test_1_type u1) {
57         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
58         return u1.a + u1.b + u1.c;
59 }
60
61 int mono_return_int (int a) {
62         // printf ("Got value %d\n", a);
63         return a;
64 }
65
66 struct ss
67 {
68         int i;
69 };
70
71 int mono_return_int_ss (struct ss a) {
72         // printf ("Got value %d\n", a.i);
73         return a.i;
74 }
75
76 struct ss mono_return_ss (struct ss a) {
77         // printf ("Got value %d\n", a.i);
78         a.i++;
79         return a;
80 }
81
82 struct sc1
83 {
84         char c[1];
85 };
86
87 struct sc1 mono_return_sc1 (struct sc1 a) {
88         // printf ("Got value %d\n", a.c[0]);
89         a.c[0]++;
90         return a;
91 }
92
93
94 struct sc3
95 {
96         char c[3];
97 };
98
99 struct sc3 mono_return_sc3 (struct sc3 a) {
100         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
101         a.c[0]++;
102         a.c[1] += 2;
103         a.c[2] += 3;
104         return a;
105 }
106
107 struct sc5
108 {
109         char c[5];
110 };
111
112 struct sc5 mono_return_sc5 (struct sc5 a) {
113         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
114         a.c[0]++;
115         a.c[1] += 2;
116         a.c[2] += 3;
117         a.c[3] += 4;
118         a.c[4] += 5;
119         return a;
120 }
121
122 union su
123 {
124         int i1;
125         int i2;
126 };
127
128 int mono_return_int_su (union su a) {
129         // printf ("Got value %d\n", a.i1);
130         return a.i1;
131 }
132
133 int mono_test_many_int_arguments (int a, int b, int c, int d, int e,
134                                   int f, int g, int h, int i, int j);
135 short mono_test_many_short_arguments (short a, short b, short c, short d, short e,
136                                       short f, short g, short h, short i, short j);
137 char mono_test_many_char_arguments (char a, char b, char c, char d, char e,
138                                     char f, char g, char h, char i, char j);
139
140 int
141 mono_test_many_int_arguments (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
142 {
143         return a + b + c + d + e + f + g + h + i + j;
144 }
145
146 short
147 mono_test_many_short_arguments (short a, short b, short c, short d, short e, short f, short g, short h, short i, short j)
148 {
149         return a + b + c + d + e + f + g + h + i + j;
150 }
151
152 char
153 mono_test_many_byte_arguments (char a, char b, char c, char d, char e, char f, char g, char h, char i, char j)
154 {
155         return a + b + c + d + e + f + g + h + i + j;
156 }
157
158 float
159 mono_test_many_float_arguments (float a, float b, float c, float d, float e, float f, float g, float h, float i, float j)
160 {
161         return a + b + c + d + e + f + g + h + i + j;
162 }
163
164 double
165 mono_test_many_double_arguments (double a, double b, double c, double d, double e, double f, double g, double h, double i, double j)
166 {
167         return a + b + c + d + e + f + g + h + i + j;
168 }
169
170 double
171 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
172 {
173         return a + b + c + d + e;
174 }
175
176 int
177 mono_test_puts_static (char *s)
178 {
179         // printf ("TEST %s\n", s);
180         return 1;
181 }
182
183 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
184
185 int
186 mono_invoke_delegate (SimpleDelegate3 delegate)
187 {
188         int res;
189
190         // printf ("start invoke %p\n", delegate);
191
192         res = delegate (2, 3);
193
194         // printf ("end invoke\n");
195
196         return res;
197 }
198
199 int 
200 mono_test_marshal_char (short a1)
201 {
202         if (a1 == 'a')
203                 return 0;
204         
205         return 1;
206 }
207
208 void
209 mono_test_marshal_char_array (gunichar2 *s)
210 {
211         const char m[] = "abcdef";
212         gunichar2* s2;
213         glong len;
214
215         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
216         
217         len = (len * 2) + 2;
218         memcpy (s, s2, len);
219
220         g_free (s2);
221 }
222
223 int
224 mono_test_empty_pinvoke (int i)
225 {
226         return i;
227 }
228
229 int 
230 mono_test_marshal_bool_byref (int a, int *b, int c)
231 {
232     int res = *b;
233
234         *b = 1;
235
236         return res;
237 }
238
239 int 
240 mono_test_marshal_array (int *a1)
241 {
242         int i, sum = 0;
243
244         for (i = 0; i < 50; i++)
245                 sum += a1 [i];
246         
247         return sum;
248 }
249
250 int 
251 mono_test_marshal_inout_array (int *a1)
252 {
253         int i, sum = 0;
254
255         for (i = 0; i < 50; i++) {
256                 sum += a1 [i];
257                 a1 [i] = 50 - a1 [i];
258         }
259         
260         return sum;
261 }
262
263 int 
264 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
265 {
266         int i, sum = 0;
267
268         for (i = 0; i < 10; i++) {
269                 a1 [i] = 'F';
270         }
271         
272         return sum;
273 }
274
275 typedef struct {
276         int a;
277         int b;
278         int c;
279         const char *d;
280 } simplestruct;
281
282 simplestruct
283 mono_test_return_vtype (int i)
284 {
285         simplestruct res;
286
287         res.a = 0;
288         res.b = 1;
289         res.c = 0;
290         res.d = "TEST";
291
292         return res;
293 }
294
295 void
296 mono_test_delegate_struct (void)
297 {
298         // printf ("TEST\n");
299 }
300
301 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
302
303 char *
304 mono_test_return_string (ReturnStringDelegate func)
305 {
306         char *res;
307
308         // printf ("mono_test_return_string\n");
309
310         res = func ("TEST");
311         marshal_free (res);
312
313         // printf ("got string: %s\n", res);
314         return g_strdup ("12345");
315 }
316
317 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
318
319 int
320 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
321 {
322         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
323             !strcmp (ss->d, "TEST1")) {
324                 ss->a = 1;
325                 ss->b = 0;
326                 ss->c = 1;
327                 ss->d = "TEST2";
328         
329                 return func (a, ss, b);
330         }
331
332         return 1;
333 }
334
335 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
336
337 int
338 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
339 {
340         int res;
341
342         /* Check that the input pointer is ignored */
343         ss->d = (gpointer)0x12345678;
344
345         func (a, ss, b);
346
347         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
348                 return 0;
349         else
350                 return 1;
351 }
352
353 typedef struct {
354         int a;
355         SimpleDelegate func, func2;
356 } DelegateStruct;
357
358 int 
359 mono_test_marshal_delegate_struct (DelegateStruct ds)
360 {
361         return ds.func (ds.a) + ds.func2 (ds.a);
362 }
363
364 int 
365 mono_test_marshal_struct (simplestruct ss)
366 {
367         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
368             !strcmp (ss.d, "TEST"))
369                 return 0;
370
371         return 1;
372 }
373
374 typedef struct {
375         int a;
376         int b;
377         int c;
378         char *d;
379         unsigned char e;
380         double f;
381         unsigned char g;
382         guint64 h;
383 } simplestruct2;
384
385 int
386 mono_test_marshal_struct2 (simplestruct2 ss)
387 {
388         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
389             !strcmp (ss.d, "TEST") && 
390             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
391                 return 0;
392
393         return 1;
394 }
395
396 /* on HP some of the struct should be on the stack and not in registers */
397 int
398 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
399 {
400         if (i != 10 || j != 11 || k != 12)
401                 return 1;
402         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
403             !strcmp (ss.d, "TEST") && 
404             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
405                 return 0;
406
407         return 1;
408 }
409
410 int
411 mono_test_marshal_struct_array (simplestruct2 *ss)
412 {
413         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
414                    !strcmp (ss[0].d, "TEST") && 
415                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
416                 return 1;
417
418         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
419                    !strcmp (ss[1].d, "TEST2") && 
420                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
421                 return 1;
422
423         return 0;
424 }
425
426 typedef struct long_align_struct {
427         gint32 a;
428         gint64 b;
429         gint64 c;
430 } long_align_struct;
431
432 int
433 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
434 {
435         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
436 }
437
438 simplestruct2 *
439 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
440 {
441         simplestruct2 *res;
442
443         if (!ss)
444                 return NULL;
445
446         if (i != 10 || j != 11 || k != 12 || l != 14)
447                 return NULL;
448         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
449                    !strcmp (ss->d, "TEST") && 
450                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
451                 return NULL;
452
453         res = g_new0 (simplestruct2, 1);
454         memcpy (res, ss, sizeof (simplestruct2));
455         res->d = g_strdup ("TEST");
456         return res;
457 }
458
459 int
460 mono_test_marshal_byref_class (simplestruct2 **ssp)
461 {
462         simplestruct2 *ss = *ssp;
463         simplestruct2 *res;
464         
465         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
466                    !strcmp (ss->d, "TEST") && 
467                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
468                 return 1;
469
470         res = g_new0 (simplestruct2, 1);
471         memcpy (res, ss, sizeof (simplestruct2));
472         res->d = g_strdup ("TEST-RES");
473
474         *ssp = res;
475         return 0;
476 }
477
478 static void *
479 get_sp (void)
480 {
481         int i;
482         void *p;
483
484         p = &i;
485         return p;
486 }
487
488 int
489 mono_test_marshal_delegate (SimpleDelegate delegate)
490 {
491         void *sp1, *sp2;
492
493         /* Check that the delegate wrapper is stdcall */
494         delegate (2);
495         sp1 = get_sp ();
496         delegate (2);
497         sp2 = get_sp ();
498         g_assert (sp1 == sp2);
499
500         return delegate (2);
501 }
502
503 SimpleDelegate
504 mono_test_marshal_return_delegate (SimpleDelegate delegate)
505 {
506         return delegate;
507 }
508
509 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
510
511 int
512 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
513 {
514         simplestruct ss, res;
515
516         ss.a = 0;
517         ss.b = 1;
518         ss.c = 0;
519         ss.d = "TEST";
520
521         res = delegate (ss);
522         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES")))
523                 return 1;
524
525         return 0;
526 }
527
528 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
529
530 int
531 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
532 {
533         simplestruct ss;
534         simplestruct *res;
535
536         ss.a = 0;
537         ss.b = 1;
538         ss.c = 0;
539         ss.d = "TEST";
540
541         /* Check argument */
542         res = delegate (&ss);
543         if (!res)
544                 return 1;
545
546         /* Check return value */
547         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
548                 return 2;
549
550         /* Check NULL argument and NULL result */
551         res = delegate (NULL);
552         if (res)
553                 return 3;
554
555         return 0;
556 }
557
558 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
559
560 int
561 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
562 {
563         simplestruct ss;
564         int res;
565         simplestruct *ptr;
566
567         ss.a = 0;
568         ss.b = 1;
569         ss.c = 0;
570         ss.d = "TEST";
571
572         ptr = &ss;
573
574         res = delegate (&ptr);
575         if (res != 0)
576                 return 1;
577
578         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
579                 return 2;
580
581         return 0;
582 }
583
584 int
585 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
586 {
587         int res;
588
589         res = delegate (NULL);
590
591         return 0;
592 }
593
594 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
595
596 int
597 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
598 {
599         int res;
600         simplestruct *ptr;
601
602         /* Check that the input pointer is ignored */
603         ptr = (gpointer)0x12345678;
604
605         res = delegate (&ptr);
606         if (res != 0)
607                 return 1;
608
609         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
610                 return 2;
611
612         return 0;
613 }
614
615 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
616
617 int
618 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
619 {
620         return delegate (s);
621 }
622
623 typedef int (STDCALL *return_int_fnt) (int i);
624 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt *d);
625
626 int
627 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
628 {
629         return delegate (ftn);
630 }
631
632 int
633 return_self (int i)
634 {
635         return i;
636 }
637
638 int
639 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
640 {
641         return delegate (return_self);
642 }
643
644 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
645
646 int
647 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
648 {
649         int i = 1;
650
651         int res = delegate (&i);
652         if (res != 0)
653                 return res;
654
655         if (i != 2)
656                 return 2;
657
658         return 0;
659 }
660
661 typedef int (STDCALL *return_int_delegate) (int i);
662
663 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) ();
664
665 int
666 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
667 {
668         return (d ()) (55);
669 }
670
671
672 int 
673 mono_test_marshal_stringbuilder (char *s, int n)
674 {
675         const char m[] = "This is my message.  Isn't it nice?";
676
677         if (strcmp (s, "ABCD") != 0)
678                 return 1;
679         strncpy(s, m, n);
680         return 0;
681 }
682
683 int 
684 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
685 {
686         const char m[] = "This is my message.  Isn't it nice?";
687         gunichar2* s2;
688         glong len;
689
690         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
691         
692         len = (len * 2) + 2;
693         if (len > n)
694                 len = n;
695         memcpy (s, s2, len);
696
697         g_free (s2);
698
699         return 0;
700 }
701
702 typedef struct {
703 #ifndef __GNUC__
704     char a;
705 #endif
706 } EmptyStruct;
707
708 int
709 mono_test_marshal_empty_string_array (char **array)
710 {
711         return (array == NULL) ? 0 : 1;
712 }
713
714 int
715 mono_test_marshal_string_array (char **array)
716 {
717         if (strcmp (array [0], "ABC"))
718                 return 1;
719         if (strcmp (array [1], "DEF"))
720                 return 2;
721
722         if (array [2] != NULL)
723                 return 3;
724
725         return 0;
726 }
727
728 int
729 mono_test_marshal_byref_string_array (char ***array)
730 {
731         if (*array == NULL)
732                 return 0;
733
734         if (strcmp ((*array) [0], "Alpha"))
735                 return 2;
736         if (strcmp ((*array) [1], "Beta"))
737                 return 2;
738         if (strcmp ((*array) [2], "Gamma"))
739                 return 2;
740
741         return 1;
742 }
743
744 int
745 mono_test_marshal_stringbuilder_array (char **array)
746 {
747         if (strcmp (array [0], "ABC"))
748                 return 1;
749         if (strcmp (array [1], "DEF"))
750                 return 2;
751
752         strcpy (array [0], "DEF");
753         strcpy (array [1], "ABC");
754
755         return 0;
756 }
757
758 int
759 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
760 {
761         GError *error = NULL;
762         char *s;
763         
764         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
765         if (strcmp (s, "ABC")) {
766                 g_free (s);
767                 return 1;
768         }
769         else
770                 g_free (s);
771
772         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
773         if (strcmp (s, "DEF")) {
774                 g_free (s);
775                 return 2;
776         }
777         else
778                 g_free (s);
779
780         if (strcmp (array2 [0], "ABC"))
781                 return 3;
782
783         if (strcmp (array2 [1], "DEF")) 
784                 return 4;
785
786         return 0;
787 }
788
789 /* this does not work on Redhat gcc 2.96 */
790 int 
791 mono_test_empty_struct (int a, EmptyStruct es, int b)
792 {
793         // printf ("mono_test_empty_struct %d %d\n", a, b);
794
795         if (a == 1 && b == 2)
796                 return 0;
797         return 1;
798 }
799
800 typedef struct {
801        char a[100];
802 } ByValStrStruct;
803
804 ByValStrStruct *
805 mono_test_byvalstr_gen (void)
806 {
807         ByValStrStruct *ret;
808        
809         ret = malloc(sizeof(ByValStrStruct));
810         memset(ret, 'a', sizeof(ByValStrStruct)-1);
811         ret->a[sizeof(ByValStrStruct)-1] = 0;
812
813         return ret;
814 }
815
816 int
817 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
818 {
819         int ret;
820
821         ret = strcmp(data->a, correctString);
822         // printf ("T1: %s\n", data->a);
823         // printf ("T2: %s\n", correctString);
824
825         marshal_free (data);
826         return (ret != 0);
827 }
828
829 int 
830 HexDump(char *data)
831 {
832         int i, res = 0;
833         char *p;
834
835         printf ("HEXDUMP DEFAULT VERSION\n");
836
837         p = data;
838         for (i=0; i < 8; ++i)
839         {
840                 res += *p;
841                 printf("%0x ", (int) *(p++));
842         }
843         putchar('\n');
844
845         return res;
846 }
847
848 int 
849 HexDumpA(char *data)
850 {
851         int i, res = 0;
852         char *p;
853
854         printf ("HEXDUMP ANSI VERSION\n");
855
856         p = data;
857         for (i=0; i < 8; ++i)
858         {
859                 res += *p;
860                 printf("%0x ", (int) *(p++));
861         }
862         putchar('\n');
863
864         return res + 100000;
865 }
866
867 int 
868 HexDump1W(char *data)
869 {
870         int i, res = 0;
871         char *p;
872
873         printf ("HEXDUMP UNICODE VERSION\n");
874
875         p = data;
876         for (i=0; i < 8; ++i)
877         {
878                 res += *p;
879                 printf("%0x ", (int) *(p++));
880         }
881         putchar('\n');
882
883         return res + 1000000;
884 }
885
886 typedef int (STDCALL *intcharFunc)(const char*);
887
888 void 
889 callFunction (intcharFunc f)
890 {
891         f ("ABC");
892 }
893
894 typedef struct {
895         const char* str;
896         int i;
897 } SimpleObj;
898
899 int
900 class_marshal_test0 (SimpleObj *obj1)
901 {
902         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
903
904         if (strcmp(obj1->str, "T1"))
905                 return -1;
906         if (obj1->i != 4)
907                 return -2;
908
909         return 0;
910 }
911
912 int
913 class_marshal_test4 (SimpleObj *obj1)
914 {
915         if (obj1)
916                 return -1;
917
918         return 0;
919 }
920
921 void
922 class_marshal_test1 (SimpleObj **obj1)
923 {
924         SimpleObj *res = malloc (sizeof (SimpleObj));
925
926         res->str = g_strdup ("ABC");
927         res->i = 5;
928
929         *obj1 = res;
930 }
931
932 int
933 class_marshal_test2 (SimpleObj **obj1)
934 {
935         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
936
937         if (strcmp((*obj1)->str, "ABC"))
938                 return -1;
939         if ((*obj1)->i != 5)
940                 return -2;
941
942         return 0;
943 }
944
945 int
946 string_marshal_test0 (char *str)
947 {
948         if (strcmp (str, "TEST0"))
949                 return -1;
950
951         return 0;
952 }
953
954 void
955 string_marshal_test1 (const char **str)
956 {
957         *str = "TEST1";
958 }
959
960 int
961 string_marshal_test2 (char **str)
962 {
963         // printf ("string_marshal_test2 %s\n", *str);
964
965         if (strcmp (*str, "TEST1"))
966                 return -1;
967
968         return 0;
969 }
970
971 int
972 string_marshal_test3 (char *str)
973 {
974         if (str)
975                 return -1;
976
977         return 0;
978 }
979
980 typedef struct {
981         int a;
982         int b;
983 } VectorList;
984
985
986 VectorList* TestVectorList (VectorList *vl)
987 {
988         VectorList *res;
989
990         // printf ("TestVectorList %d %d\n", vl->a, vl->b);
991
992         vl->a++;
993         vl->b++;
994
995         res = g_new0 (VectorList, 1);
996         memcpy (res, vl, sizeof (VectorList));
997
998         return res;
999 }
1000
1001
1002 typedef struct _OSVERSIONINFO
1003
1004         int a; 
1005         int b; 
1006 } OSVERSIONINFO; 
1007
1008 int 
1009 GetVersionEx (OSVERSIONINFO *osvi)
1010 {
1011
1012         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1013
1014         osvi->a += 1;
1015         osvi->b += 1;
1016
1017         return osvi->a + osvi->b;
1018 }
1019
1020 int 
1021 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO *osvi)
1022 {
1023
1024         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1025
1026         osvi->a += 1;
1027         osvi->b += 1;
1028
1029         return osvi->a + osvi->b;
1030 }
1031
1032 typedef struct {
1033         double x;
1034         double y;
1035 } point;
1036
1037 int
1038 mono_test_marshal_point (point pt)
1039 {
1040         // printf("point %g %g\n", pt.x, pt.y);
1041         if (pt.x == 1.25 && pt.y == 3.5)
1042                 return 0;
1043
1044         return 1;
1045 }
1046
1047 typedef struct {
1048         int x;
1049         double y;
1050 } mixed_point;
1051
1052 int
1053 mono_test_marshal_mixed_point (mixed_point pt)
1054 {
1055         // printf("mixed point %d %g\n", pt.x, pt.y);
1056         if (pt.x == 5 && pt.y == 6.75)
1057                 return 0;
1058
1059         return 1;
1060 }
1061
1062 int
1063 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1064 {
1065         if (pt->x != 5 || pt->y != 6.75)
1066                 return 1;
1067
1068         pt->x = 10;
1069         pt->y = 12.35;
1070
1071         return 0;
1072 }
1073
1074 int 
1075 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1076 {
1077     int res = 1;
1078     if (*b1 != 0 && *b1 != 1)
1079         return 1;
1080     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1081         return 1;
1082     if (*b3 != 0 && *b3 != 1)
1083         return 1;
1084     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1085         res = 0;
1086     *b1 = !*b1;
1087     *b2 = ~*b2;
1088     *b3 = !*b3;
1089     return res;
1090 }
1091
1092 struct BoolStruct
1093 {
1094     int i;
1095     char b1;
1096     short b2; /* variant_bool */
1097     int b3;
1098 };
1099
1100 int 
1101 marshal_test_bool_struct(struct BoolStruct *s)
1102 {
1103     int res = 1;
1104     if (s->b1 != 0 && s->b1 != 1)
1105         return 1;
1106     if (s->b2 != 0 && s->b2 != -1)
1107         return 1;
1108     if (s->b3 != 0 && s->b3 != 1)
1109         return 1;
1110     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1111         res = 0;
1112     s->b1 = !s->b1;
1113     s->b2 = ~s->b2;
1114     s->b3 = !s->b3;
1115     return res;
1116 }
1117
1118 #ifdef WIN32
1119 extern __declspec(dllimport) __stdcall void SetLastError(int x);
1120 #endif
1121
1122 void
1123 mono_test_last_error (int err)
1124 {
1125 #ifdef WIN32
1126         SetLastError (err);
1127 #else
1128         errno = err;
1129 #endif
1130 }
1131
1132 int
1133 mono_test_asany (void *ptr, int what)
1134 {
1135         switch (what) {
1136         case 1:
1137                 return (*(int*)ptr == 5) ? 0 : 1;
1138         case 2:
1139                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1140         case 3: {
1141                 simplestruct2 ss = *(simplestruct2*)ptr;
1142
1143                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1144             !strcmp (ss.d, "TEST") && 
1145             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1146                         return 0;
1147                 else
1148                         return 1;
1149         }
1150         case 4: {
1151                 GError *error = NULL;
1152                 char *s;
1153
1154                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1155                 if (!strcmp (s, "ABC")) {
1156                         g_free (s);
1157                         return 0;
1158                 }
1159                 else {
1160                         g_free (s);
1161                         return 1;
1162                 }
1163         }
1164         default:
1165                 g_assert_not_reached ();
1166         }
1167
1168         return 1;
1169 }
1170
1171 /*
1172  * AMD64 marshalling tests.
1173  */
1174
1175 typedef struct amd64_struct1 {
1176         int i;
1177         int j;
1178         int k;
1179         int l;
1180 } amd64_struct1;
1181
1182 amd64_struct1
1183 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1184 {
1185         s.i ++;
1186         s.j ++;
1187         s.k ++;
1188         s.l ++;
1189
1190         return s;
1191 }
1192
1193 typedef struct amd64_struct2 {
1194         int i;
1195         int j;
1196 } amd64_struct2;
1197
1198 amd64_struct2
1199 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1200 {
1201         s.i ++;
1202         s.j ++;
1203
1204         return s;
1205 }
1206
1207 typedef struct amd64_struct3 {
1208         int i;
1209 } amd64_struct3;
1210
1211 amd64_struct3
1212 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1213 {
1214         s.i ++;
1215
1216         return s;
1217 }
1218
1219 typedef struct amd64_struct4 {
1220         double d1, d2;
1221 } amd64_struct4;
1222
1223 amd64_struct4
1224 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1225 {
1226         s.d1 ++;
1227         s.d2 ++;
1228
1229         return s;
1230 }
1231
1232 static guint32 custom_res [2];
1233
1234 void*
1235 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1236 {
1237         /* ptr will be freed by CleanupNative, so make a copy */
1238         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1239         custom_res [1] = ptr [1];
1240
1241         return &custom_res;
1242 }
1243
1244 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1245
1246 int
1247 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1248 {
1249         guint32 buf [2];
1250         guint32 res;
1251         guint32 *ptr;
1252
1253         buf [0] = 0;
1254         buf [1] = 10;
1255
1256         ptr = del (&buf);
1257
1258         res = ptr [1];
1259
1260 #ifdef WIN32
1261         /* FIXME: Freed with FreeHGlobal */
1262 #else
1263         g_free (ptr);
1264 #endif
1265
1266         return res;
1267 }
1268
1269 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1270
1271 int
1272 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1273 {
1274         return func (1);
1275 }
1276
1277 typedef struct {
1278         int a, b, c;
1279         long d;
1280 } BlittableStruct;
1281         
1282 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1283
1284 int
1285 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1286 {
1287         BlittableStruct ss, res;
1288
1289         ss.a = 1;
1290         ss.b = 2;
1291         ss.c = 3;
1292         ss.d = 55;
1293
1294         res = delegate (ss);
1295         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1296                 return 1;
1297
1298         return 0;
1299 }
1300
1301 STDCALL int
1302 mono_test_stdcall_name_mangling (int a, int b, int c)
1303 {
1304         return a + b + c;
1305 }