* icall.c: Add icall to access char conversion tables.
[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 unsigned short*
9 test_lpwstr_marshal (unsigned short* chars, long length)
10 {
11         int i = 0;
12         unsigned short *res;
13
14         res = malloc (2 * (length + 1));
15
16         printf("test_lpwstr_marshal()\n");
17         
18         while ( i < length ) {
19                 printf("X|%u|\n", chars[i]);
20                 res [i] = chars[i];
21                 i++;
22         }
23
24         res [i] = 0;
25
26         return res;
27 }
28
29 typedef struct {
30         int b;
31         int a;
32         int c;
33 } union_test_1_type;
34
35 int mono_union_test_1 (union_test_1_type u1) {
36         printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
37         return u1.a + u1.b + u1.c;
38 }
39
40 int mono_return_int (int a) {
41         printf ("Got value %d\n", a);
42         return a;
43 }
44
45 struct ss
46 {
47         int i;
48 };
49
50 int mono_return_int_ss (struct ss a) {
51         printf ("Got value %d\n", a.i);
52         return a.i;
53 }
54
55 struct ss mono_return_ss (struct ss a) {
56         printf ("Got value %d\n", a.i);
57         a.i++;
58         return a;
59 }
60
61 struct sc1
62 {
63         char c[1];
64 };
65
66 struct sc1 mono_return_sc1 (struct sc1 a) {
67         printf ("Got value %d\n", a.c[0]);
68         a.c[0]++;
69         return a;
70 }
71
72
73 struct sc3
74 {
75         char c[3];
76 };
77
78 struct sc3 mono_return_sc3 (struct sc3 a) {
79         printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
80         a.c[0]++;
81         a.c[1] += 2;
82         a.c[2] += 3;
83         return a;
84 }
85
86 struct sc5
87 {
88         char c[5];
89 };
90
91 struct sc5 mono_return_sc5 (struct sc5 a) {
92         printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
93         a.c[0]++;
94         a.c[1] += 2;
95         a.c[2] += 3;
96         a.c[3] += 4;
97         a.c[4] += 5;
98         return a;
99 }
100
101 union su
102 {
103         int i1;
104         int i2;
105 };
106
107 int mono_return_int_su (union su a) {
108         printf ("Got value %d\n", a.i1);
109         return a.i1;
110 }
111
112 int mono_test_many_int_arguments (int a, int b, int c, int d, int e,
113                                   int f, int g, int h, int i, int j);
114 short mono_test_many_short_arguments (short a, short b, short c, short d, short e,
115                                       short f, short g, short h, short i, short j);
116 char mono_test_many_char_arguments (char a, char b, char c, char d, char e,
117                                     char f, char g, char h, char i, char j);
118
119 int
120 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)
121 {
122         return a + b + c + d + e + f + g + h + i + j;
123 }
124
125 short
126 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)
127 {
128         return a + b + c + d + e + f + g + h + i + j;
129 }
130
131 char
132 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)
133 {
134         return a + b + c + d + e + f + g + h + i + j;
135 }
136
137 float
138 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)
139 {
140         return a + b + c + d + e + f + g + h + i + j;
141 }
142
143 double
144 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)
145 {
146         return a + b + c + d + e + f + g + h + i + j;
147 }
148
149 double
150 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
151 {
152         return a + b + c + d + e;
153 }
154
155 int
156 mono_test_puts_static (char *s)
157 {
158         printf ("TEST %s\n", s);
159         return 1;
160 }
161
162 typedef int (*SimpleDelegate3) (int a, int b);
163
164 int
165 mono_invoke_delegate (SimpleDelegate3 delegate)
166 {
167         int res;
168
169         printf ("start invoke %p\n", delegate);
170
171         res = delegate (2, 3);
172
173         printf ("end invoke\n");
174
175         return res;
176 }
177
178 int 
179 mono_test_marshal_char (short a1)
180 {
181         if (a1 == 'a')
182                 return 0;
183         
184         return 1;
185 }
186
187 int
188 mono_test_empty_pinvoke (int i)
189 {
190         return i;
191 }
192
193 int 
194 mono_test_marshal_bool_byref (int a, int *b, int c)
195 {
196     int res = *b;
197
198         *b = 1;
199
200         return res;
201 }
202
203 int 
204 mono_test_marshal_array (int *a1)
205 {
206         int i, sum = 0;
207
208         for (i = 0; i < 50; i++)
209                 sum += a1 [i];
210         
211         return sum;
212 }
213
214 int 
215 mono_test_marshal_inout_array (int *a1)
216 {
217         int i, sum = 0;
218
219         for (i = 0; i < 50; i++) {
220                 sum += a1 [i];
221                 a1 [i] = 50 - a1 [i];
222         }
223         
224         return sum;
225 }
226
227 int 
228 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
229 {
230         int i, sum = 0;
231
232         for (i = 0; i < 10; i++) {
233                 a1 [i] = 'F';
234         }
235         
236         return sum;
237 }
238
239 typedef struct {
240         int a;
241         int b;
242         int c;
243         const char *d;
244 } simplestruct;
245
246 simplestruct
247 mono_test_return_vtype (int i)
248 {
249         simplestruct res;
250
251         res.a = 0;
252         res.b = 1;
253         res.c = 0;
254         res.d = "TEST";
255
256         return res;
257 }
258
259 void
260 mono_test_delegate_struct (void)
261 {
262         printf ("TEST\n");
263 }
264
265 typedef char* (*ReturnStringDelegate) (const char *s);
266
267 char *
268 mono_test_return_string (ReturnStringDelegate func)
269 {
270         char *res;
271
272         printf ("mono_test_return_string\n");
273
274         res = func ("TEST");
275
276         printf ("got string: %s\n", res);
277         return res;
278 }
279
280 typedef int (*RefVTypeDelegate) (int a, simplestruct *ss, int b);
281
282 int
283 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
284 {
285         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
286             !strcmp (ss->d, "TEST1")) {
287                 ss->a = 1;
288                 ss->b = 0;
289                 ss->c = 1;
290                 ss->d = "TEST2";
291         
292                 return func (a, ss, b);
293         }
294
295         return 1;
296 }
297
298 typedef struct {
299         int a;
300         int (*func) (int);
301 } DelegateStruct;
302
303 int 
304 mono_test_marshal_delegate_struct (DelegateStruct ds)
305 {
306         return ds.func (ds.a);
307 }
308
309 int 
310 mono_test_marshal_struct (simplestruct ss)
311 {
312         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
313             !strcmp (ss.d, "TEST"))
314                 return 0;
315
316         return 1;
317 }
318
319 typedef struct {
320         int a;
321         int b;
322         int c;
323         char *d;
324         unsigned char e;
325         double f;
326         unsigned char g;
327         guint64 h;
328 } simplestruct2;
329
330 int
331 mono_test_marshal_struct2 (simplestruct2 ss)
332 {
333         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
334             !strcmp (ss.d, "TEST") && 
335             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
336                 return 0;
337
338         return 1;
339 }
340
341 /* on HP some of the struct should be on the stack and not in registers */
342 int
343 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
344 {
345         if (i != 10 || j != 11 || k != 12)
346                 return 1;
347         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
348             !strcmp (ss.d, "TEST") && 
349             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
350                 return 0;
351
352         return 1;
353 }
354
355 int
356 mono_test_marshal_struct_array (simplestruct2 *ss)
357 {
358         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
359                    !strcmp (ss[0].d, "TEST") && 
360                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
361                 return 1;
362
363         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
364                    !strcmp (ss[1].d, "TEST2") && 
365                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
366                 return 1;
367
368         return 0;
369 }
370
371 simplestruct2 *
372 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
373 {
374         simplestruct2 *res;
375
376         if (!ss)
377                 return NULL;
378
379         if (i != 10 || j != 11 || k != 12 || l != 14)
380                 return NULL;
381         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
382                    !strcmp (ss->d, "TEST") && 
383                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
384                 return NULL;
385
386         res = g_new0 (simplestruct2, 1);
387         memcpy (res, ss, sizeof (simplestruct2));
388         return res;
389 }
390
391 int
392 mono_test_marshal_byref_class (simplestruct2 **ssp)
393 {
394         simplestruct2 *ss = *ssp;
395         simplestruct2 *res;
396         
397         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
398                    !strcmp (ss->d, "TEST") && 
399                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
400                 return 1;
401
402         res = g_new0 (simplestruct2, 1);
403         memcpy (res, ss, sizeof (simplestruct2));
404         res->d = (char*)"TEST-RES";
405
406         *ssp = res;
407         return 0;
408 }
409
410 #ifdef WIN32
411 typedef int (__stdcall *SimpleDelegate) (int a);
412 #else
413 typedef int (*SimpleDelegate) (int a);
414 #endif
415
416 static void *
417 get_sp (void)
418 {
419         int i;
420         void *p;
421
422         p = &i;
423         return p;
424 }
425
426 int
427 mono_test_marshal_delegate (SimpleDelegate delegate)
428 {
429         void *sp1, *sp2;
430
431         /* Check that the delegate wrapper is stdcall */
432         delegate (2);
433         sp1 = get_sp ();
434         delegate (2);
435         sp2 = get_sp ();
436         g_assert (sp1 == sp2);
437
438         return delegate (2);
439 }
440
441 typedef simplestruct (*SimpleDelegate2) (simplestruct ss);
442
443 int
444 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
445 {
446         simplestruct ss, res;
447
448         ss.a = 0;
449         ss.b = 1;
450         ss.c = 0;
451         ss.d = "TEST";
452
453         res = delegate (ss);
454         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES")))
455                 return 1;
456
457         return 0;
458 }
459
460 typedef simplestruct* (*SimpleDelegate4) (simplestruct *ss);
461
462 int
463 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
464 {
465         simplestruct ss;
466         simplestruct *res;
467
468         ss.a = 0;
469         ss.b = 1;
470         ss.c = 0;
471         ss.d = "TEST";
472
473         /* Check argument */
474         res = delegate (&ss);
475         if (!res)
476                 return 1;
477
478         /* Check return value */
479         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
480                 return 2;
481
482         /* Check NULL argument and NULL result */
483         res = delegate (NULL);
484         if (res)
485                 return 3;
486
487         return 0;
488 }
489
490 typedef int (*SimpleDelegate5) (simplestruct **ss);
491
492 int
493 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
494 {
495         simplestruct ss;
496         int res;
497         simplestruct *ptr;
498
499         ss.a = 0;
500         ss.b = 1;
501         ss.c = 0;
502         ss.d = "TEST";
503
504         ptr = &ss;
505
506         res = delegate (&ptr);
507         if (res != 0)
508                 return 1;
509
510         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
511                 return 2;
512
513         return 0;
514 }
515
516 int
517 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
518 {
519         int res;
520
521         res = delegate (NULL);
522
523         return 0;
524 }
525
526 typedef int (*SimpleDelegate7) (simplestruct **ss);
527
528 int
529 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
530 {
531         int res;
532         simplestruct *ptr;
533
534         /* Check that the input pointer is ignored */
535         ptr = (gpointer)0x12345678;
536
537         res = delegate (&ptr);
538         if (res != 0)
539                 return 1;
540
541         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
542                 return 2;
543
544         return 0;
545 }
546
547 int 
548 mono_test_marshal_stringbuilder (char *s, int n)
549 {
550         const char m[] = "This is my message.  Isn't it nice?";
551         strncpy(s, m, n);
552         return 0;
553 }
554
555 int 
556 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
557 {
558         const char m[] = "This is my message.  Isn't it nice?";
559         gunichar2* s2;
560         glong len;
561
562         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
563         
564         len = (len * 2) + 2;
565         if (len > n)
566                 len = n;
567         memcpy (s, s2, len);
568
569         g_free (s2);
570
571         return 0;
572 }
573
574 typedef struct {
575 #ifndef __GNUC__
576     char a;
577 #endif
578 } EmptyStruct;
579
580 int
581 mono_test_marshal_string_array (char **array)
582 {
583         printf ("%p\n", array);
584         return 0;
585 }
586
587 /* this does not work on Redhat gcc 2.96 */
588 int 
589 mono_test_empty_struct (int a, EmptyStruct es, int b)
590 {
591         printf ("mono_test_empty_struct %d %d\n", a, b);
592
593         if (a == 1 && b == 2)
594                 return 0;
595         return 1;
596 }
597
598 typedef struct {
599        char a[100];
600 } ByValStrStruct;
601
602 ByValStrStruct *
603 mono_test_byvalstr_gen (void)
604 {
605         ByValStrStruct *ret;
606        
607         ret = malloc(sizeof(ByValStrStruct));
608         memset(ret, 'a', sizeof(ByValStrStruct)-1);
609         ret->a[sizeof(ByValStrStruct)-1] = 0;
610
611         return ret;
612 }
613
614 int
615 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
616 {
617         int ret;
618
619         ret = strcmp(data->a, correctString);
620         printf ("T1: %s\n", data->a);
621         printf ("T2: %s\n", correctString);
622
623         g_free(data);
624         return (ret != 0);
625 }
626
627 int 
628 HexDump(char *data)
629 {
630         int i, res = 0;
631         char *p;
632
633         printf ("HEXDUMP DEFAULT VERSION\n");
634
635         p = data;
636         for (i=0; i < 8; ++i)
637         {
638                 res += *p;
639                 printf("%0x ", (int) *(p++));
640         }
641         putchar('\n');
642
643         return res;
644 }
645
646 int 
647 HexDumpA(char *data)
648 {
649         int i, res = 0;
650         char *p;
651
652         printf ("HEXDUMP ANSI VERSION\n");
653
654         p = data;
655         for (i=0; i < 8; ++i)
656         {
657                 res += *p;
658                 printf("%0x ", (int) *(p++));
659         }
660         putchar('\n');
661
662         return res + 100000;
663 }
664
665 int 
666 HexDump1W(char *data)
667 {
668         int i, res = 0;
669         char *p;
670
671         printf ("HEXDUMP UNICODE VERSION\n");
672
673         p = data;
674         for (i=0; i < 8; ++i)
675         {
676                 res += *p;
677                 printf("%0x ", (int) *(p++));
678         }
679         putchar('\n');
680
681         return res + 1000000;
682 }
683
684 typedef int (*intcharFunc)(const char*);
685
686 void 
687 callFunction (intcharFunc f)
688 {
689         f ("ABC");
690 }
691
692 int
693 printInt (int* number)
694 {
695         printf( "<%d>\n", *number );
696         return *number + 1;
697 }
698
699
700 typedef struct {
701         const char* str;
702         int i;
703 } SimpleObj;
704
705 int
706 class_marshal_test0 (SimpleObj *obj1)
707 {
708         printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
709
710         if (strcmp(obj1->str, "T1"))
711                 return -1;
712         if (obj1->i != 4)
713                 return -2;
714
715         return 0;
716 }
717
718 int
719 class_marshal_test4 (SimpleObj *obj1)
720 {
721         if (obj1)
722                 return -1;
723
724         return 0;
725 }
726
727 void
728 class_marshal_test1 (SimpleObj **obj1)
729 {
730         SimpleObj *res = malloc (sizeof (SimpleObj));
731
732         res->str = "ABC";
733         res->i = 5;
734
735         *obj1 = res;
736 }
737
738 int
739 class_marshal_test2 (SimpleObj **obj1)
740 {
741         printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
742
743         if (strcmp((*obj1)->str, "ABC"))
744                 return -1;
745         if ((*obj1)->i != 5)
746                 return -2;
747
748         return 0;
749 }
750
751 int
752 string_marshal_test0 (char *str)
753 {
754         if (strcmp (str, "TEST0"))
755                 return -1;
756
757         return 0;
758 }
759
760 void
761 string_marshal_test1 (const char **str)
762 {
763         *str = "TEST1";
764 }
765
766 int
767 string_marshal_test2 (char **str)
768 {
769         printf ("string_marshal_test2 %s\n", *str);
770
771         if (strcmp (*str, "TEST1"))
772                 return -1;
773
774         return 0;
775 }
776
777 int
778 string_marshal_test3 (char *str)
779 {
780         if (str)
781                 return -1;
782
783         return 0;
784 }
785
786 const char *
787 functionReturningString (void)
788 {
789     return "ABC";
790 }
791
792 typedef struct {
793         int a;
794         int b;
795 } VectorList;
796
797
798 VectorList* TestVectorList (VectorList *vl)
799 {
800         printf ("TestVectorList %d %d\n", vl->a, vl->b);
801
802         vl->a++;
803         vl->b++;
804
805         return vl;
806 }
807
808
809 typedef struct _OSVERSIONINFO
810
811         int a; 
812         int b; 
813 } OSVERSIONINFO; 
814
815 int 
816 GetVersionEx (OSVERSIONINFO *osvi)
817 {
818
819         printf ("GOT %d %d\n", osvi->a, osvi->b);
820
821         osvi->a += 1;
822         osvi->b += 1;
823
824         return osvi->a + osvi->b;
825 }
826
827 int 
828 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO *osvi)
829 {
830
831         printf ("GOT %d %d\n", osvi->a, osvi->b);
832
833         osvi->a += 1;
834         osvi->b += 1;
835
836         return osvi->a + osvi->b;
837 }
838
839 typedef struct {
840         double x;
841         double y;
842 } point;
843
844 int
845 mono_test_marshal_point (point pt)
846 {
847         printf("point %g %g\n", pt.x, pt.y);
848         if (pt.x == 1.25 && pt.y == 3.5)
849                 return 0;
850
851         return 1;
852 }
853
854 typedef struct {
855         int x;
856         double y;
857 } mixed_point;
858
859 int
860 mono_test_marshal_mixed_point (mixed_point pt)
861 {
862         printf("mixed point %d %g\n", pt.x, pt.y);
863         if (pt.x == 5 && pt.y == 6.75)
864                 return 0;
865
866         return 1;
867 }
868
869 int
870 time_t_sizeof (void)
871 {
872         return sizeof (time_t);
873 }
874
875 time_t
876 mono_test_marshal_time_t (time_t *t)
877 {
878         /* Skip forward an hour */
879         return *t + 3600;
880 }
881
882 int 
883 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
884 {
885     int res = 1;
886     if (*b1 != 0 && *b1 != 1)
887         return 1;
888     if (*b2 != 0 && *b2 != -1) /* variant_bool */
889         return 1;
890     if (*b3 != 0 && *b3 != 1)
891         return 1;
892     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
893         res = 0;
894     *b1 = !*b1;
895     *b2 = ~*b2;
896     *b3 = !*b3;
897     return res;
898 }
899
900 struct BoolStruct
901 {
902     int i;
903     char b1;
904     short b2; /* variant_bool */
905     int b3;
906 };
907
908 int 
909 marshal_test_bool_struct(struct BoolStruct *s)
910 {
911     int res = 1;
912     if (s->b1 != 0 && s->b1 != 1)
913         return 1;
914     if (s->b2 != 0 && s->b2 != -1)
915         return 1;
916     if (s->b3 != 0 && s->b3 != 1)
917         return 1;
918     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
919         res = 0;
920     s->b1 = !s->b1;
921     s->b2 = ~s->b2;
922     s->b3 = !s->b3;
923     return res;
924 }
925
926 void
927 mono_test_last_error (int err)
928 {
929 #ifdef WIN32
930         SetLastError (err);
931 #else
932         errno = err;
933 #endif
934 }
935
936
937