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