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