* src/pbc_merge.c:
[parrot.git] / src / nci_test.c
blob28c86b55e5c6fc6db5a688aa7b4283a8cdea8d5f
1 /*
2 Copyright (C) 2001-2007, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/nci_test.c - shared library used for testing the Native Call Interface
9 =head1 DESCRIPTION
11 From this code a shared library can be compiled and linked with a command like:
13 cc -shared -fpic nci_test.c -o libnci_test.so -g
15 For non-Unix platforms the above command has to be modified appropriately.
17 The resulting shared library should be copied to a location like:
19 parrot/runtime/parrot/dynext/libnci_test.so
21 At that location the shared library is loadable with the opcode 'loadlib'.
22 The functions in the library are available with the opcode 'dlfunc'.
23 The variables in the library are available with the opcode 'dlvar'.
25 =head2 Functions
27 The name of a test function is usually 'nci_<signature>'. E.g. the function
28 'nci_ip' takes a 'pointer' and returns a 'int'.
30 =over 4
32 =cut
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <parrot/config.h>
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
45 /* Declarations of structs */
47 typedef struct Nested {
48 int y;
49 } Nested;
51 typedef struct Outer {
52 int x;
53 Nested *nested;
54 } Outer;
56 typedef struct Rect_Like {
57 int x, y;
58 int w, h;
59 } Rect_Like;
61 typedef struct Opaque {
62 int x;
63 } Opaque;
65 /* Function declarations.
67 *** If you add a new test function here,
68 *** please update src/libnci_test.def and src/call_list.txt too. ***
72 PARROT_API int call_back(const char *str);
73 PARROT_API char nci_c(void);
74 PARROT_API char nci_csc(short, char);
75 PARROT_API double nci_d(void);
76 PARROT_API double nci_dd(double);
77 PARROT_API float nci_f(void);
78 PARROT_API float nci_fff(float, float);
79 PARROT_API int nci_i(void);
80 PARROT_API int nci_ib(int *);
81 PARROT_API int nci_iiii(int, int, int);
82 PARROT_API int nci_ii3(int, int *);
83 PARROT_API int nci_ip(void *);
84 PARROT_API int nci_isc(short, char);
85 PARROT_API int nci_it(void *);
86 PARROT_API int nci_i33(int *, int *);
87 PARROT_API int nci_i4i(long *, int);
88 PARROT_API long nci_l(void);
89 PARROT_API int * nci_p(void);
90 PARROT_API void * nci_pi(int);
91 PARROT_API void * nci_pii(int, int);
92 PARROT_API void * nci_piiii(int, int, int, int);
93 PARROT_API void nci_pip(int, Rect_Like *);
94 PARROT_API void * nci_pp(void *);
95 PARROT_API short nci_s(void);
96 PARROT_API short nci_ssc(short, char);
97 PARROT_API char * nci_t(void);
98 PARROT_API char * nci_tb(void *);
99 PARROT_API char * nci_tB(void **);
100 PARROT_API char * nci_tt(void *);
101 PARROT_API void nci_v(void);
102 PARROT_API void nci_vP(void *);
103 PARROT_API void nci_vpii(Outer *, int, int);
104 PARROT_API void nci_vv(void);
105 PARROT_API void nci_vVi(Opaque**, int);
106 PARROT_API void nci_vp(Opaque*);
109 /* Declarations for callback tests */
111 typedef void (*cb_C1_func)(const char*, void*);
112 PARROT_API void nci_cb_C1(cb_C1_func, void*);
114 typedef void (*cb_C2_func)(int, void*);
115 PARROT_API void nci_cb_C2(cb_C2_func, void*);
117 typedef void (*cb_C3_func)(void*, void*);
118 PARROT_API void nci_cb_C3(cb_C3_func, void*);
120 typedef void (*cb_D1_func)(void*, const char*);
121 PARROT_API void nci_cb_D1(cb_D1_func, void*);
123 typedef void (*cb_D2_func)(void*, int);
124 PARROT_API void nci_cb_D2(cb_D2_func, void*);
126 typedef void (*cb_D3_func)(void*, void*);
127 PARROT_API void nci_cb_D3(cb_D3_func, void*);
129 typedef void (*cb_D4_func)(void*, void*);
130 PARROT_API void nci_cb_D4(cb_D4_func, void*);
132 /* Variable definitions */
134 PARROT_API int int_cb_D4 = -55555;
135 PARROT_API int nci_dlvar_char = 22;
136 PARROT_API int nci_dlvar_short = 333;
137 PARROT_API int nci_dlvar_int = -4444;
138 PARROT_API long nci_dlvar_long = -7777777;
139 PARROT_API float nci_dlvar_float = -333.0;
140 PARROT_API double nci_dlvar_double = -55555.55555;
141 PARROT_API char nci_dlvar_cstring[] = "This is a C-string.\n";
144 /* Function definitions */
148 =item C<PARROT_API char
149 nci_c(void)>
151 Returns the value of the variable C<nci_dlvar_char>, which is set to 22 by
152 default.
154 =cut
158 PARROT_API char
159 nci_c(void) {
160 return nci_dlvar_char;
165 =item C<PARROT_API char
166 nci_csc(short l1, char l2)>
168 Multiplies C<l1> and C<l2> together and returns the first byte of the result.
170 =cut
174 PARROT_API char
175 nci_csc(short l1, char l2)
177 return l1 * l2;
182 =item C<PARROT_API double
183 nci_d(void)>
185 Multiplies the current value of C<nci_dlvar_double> by 10.0, and returns
186 the new value.
188 =cut
192 PARROT_API double
193 nci_d(void)
195 nci_dlvar_double *= 10.0;
197 return nci_dlvar_double;
202 =item C<PARROT_API double
203 nci_dd(double d)>
205 Returns the value C<d> multiplied by 2.0.
207 =cut
211 PARROT_API double
212 nci_dd(double d)
214 return d * 2.0;
219 =item C<PARROT_API float
220 nci_f(void)>
222 Multiplies the value C<nci_dlvar_float> by 10.0 and returns the new
223 value.
225 =cut
229 PARROT_API float
230 nci_f(void)
232 nci_dlvar_float *= 10.0;
234 return nci_dlvar_float;
239 =item C<PARROT_API float
240 nci_fff(float l1, float l2)>
242 Returns the result of C<l1> / C<l2>.
244 =cut
248 PARROT_API float
249 nci_fff(float l1, float l2)
251 return l1 / l2;
256 =item C<PARROT_API int
257 nci_i(void)>
259 Returns the current value of <nci_dlvar_int>.
261 =cut
265 PARROT_API int
266 nci_i(void)
268 return nci_dlvar_int;
273 =item C<PARROT_API int
274 nci_isc(short l1, char l2)>
276 Returns the int product of C<l1 * l2>.
278 =cut
282 PARROT_API int
283 nci_isc(short l1, char l2)
285 return l1 * l2;
290 =item C<PARROT_API int
291 nci_ip(void *p)>
293 Performs a series of operations on values stored at pointer C<p>.
295 =cut
299 PARROT_API int
300 nci_ip(void *p)
302 typedef struct _dfi {
303 double d;
304 float f;
305 int i;
306 char *s;
307 } dfi;
308 dfi *sp = (dfi*) p;
309 puts(sp->s);
310 fflush(stdout);
312 return (int) (sp->d + sp->f + sp->i);
317 =item C<PARROT_API int
318 nci_it(void *p)>
320 test calls this with a string
322 =cut
326 PARROT_API int
327 nci_it(void *p)
329 fprintf(stderr, "%c%c\n", ((char*) p)[1], ((char *) p)[0]);
330 fflush(stderr);
332 return 2;
337 =item C<PARROT_API long
338 nci_l(void)>
340 Returns the value of C<nci_dlvar_long>.
342 =cut
346 PARROT_API long
347 nci_l(void)
349 return nci_dlvar_long;
354 =item C<PARROT_API int *
355 nci_p(void)>
357 Returns the address of C<nci_dlvar_int>.
359 =cut
363 PARROT_API int *
364 nci_p(void)
366 return &nci_dlvar_int;
371 =item C<PARROT_API char *
372 nci_t(void)>
374 Returns the value of C<nci_dlvar_cstring>.
376 =cut
380 PARROT_API char *
381 nci_t(void)
383 return nci_dlvar_cstring;
388 =item C<PARROT_API char *
389 nci_tb(void *p)>
391 Prints "xx worked", where "xx" is replaced with the first two character values
392 of C<p>, in reverse order.
394 =cut
398 static char b[] = "xx worked\n";
400 PARROT_API char *
401 nci_tb(void *p)
403 b[0] = ((char*) p)[1];
404 b[1] = ((char*) p)[0];
406 return b;
411 =item C<PARROT_API char *
412 nci_tt(void *p)>
414 Prints "xx worked", where "xx" is replaced with the first two character values
415 of C<p>, in reverse order.
417 =cut
421 static char s[] = "xx worked\n";
423 PARROT_API char *
424 nci_tt(void *p)
426 s[0] = ((char*) p)[1];
427 s[1] = ((char*) p)[0];
429 return s;
434 =item C<PARROT_API char *
435 nci_tB(void **p)>
437 Prints "xx done", where "xx" is replaced with the first two character values
438 of C<p>, in reverse order.
440 =cut
444 static char B[] = "xx done\n";
446 PARROT_API char *
447 nci_tB(void **p)
449 B[0] = (*(char**) p)[1];
450 B[1] = (*(char**) p)[0];
452 return B;
457 =item C<PARROT_API void *
458 nci_pp(void *p)>
460 Returns the value C<p> directly.
462 =cut
466 PARROT_API void *
467 nci_pp(void *p)
469 return p;
474 =item C<PARROT_API int
475 nci_iiii(int i1, int i2, int i3)>
477 Prints three integers separated by whitespace to C<stderr>.
479 =cut
483 PARROT_API int
484 nci_iiii(int i1, int i2, int i3)
486 fprintf(stderr, "%d %d %d\n", i1, i2, i3);
487 fflush(stderr);
489 return 2;
494 =item C<PARROT_API int
495 nci_i4i(long * l, int i)>
497 Returns the product of C<*l> and C<i>, as an int.
499 =cut
503 PARROT_API int
504 nci_i4i(long * l, int i)
507 return (int) (*l * i);
512 =item C<PARROT_API int
513 nci_ii3(int a, int *bp)>
515 Multiplies C<a> and C<*bp> together and returns the result. Updates C<*bp>
516 to the value 4711.
518 =cut
522 PARROT_API int
523 nci_ii3(int a, int *bp)
525 int r = a * *bp;
526 *bp = 4711;
528 return r;
533 =item C<PARROT_API int
534 call_back(const char *str)>
536 writes the string C<str> to stdout and returns the value 4711.
538 =cut
542 PARROT_API int
543 call_back(const char *str)
545 puts(str);
546 fflush(stdout);
548 return 4711;
553 =item C<PARROT_API void *
554 nci_pi(int test)>
556 Performs one from a series of tests, depending on the value given for C<test>.
558 =cut
562 PARROT_API void *
563 nci_pi(int test)
565 switch (test) {
566 case 0:
568 static struct {
569 int i[2];
570 char c;
571 } t = {
572 {42, 100},
575 return &t;
577 case 1:
579 static struct {
580 float f[2];
581 double d;
582 } t = {
583 {42.0, 100.0},
584 47.11
586 return &t;
588 case 2:
590 static struct {
591 char c;
592 int i;
593 } t = {
597 return &t;
599 case 3:
601 static struct {
602 const char *c;
603 int i;
604 } t = {
605 "hello",
608 return &t;
610 case 4:
612 static struct _x {
613 int i;
614 int j;
615 double d;
616 } xx = { 100, 77, 200.0 };
617 static struct {
618 char c;
619 struct _x *x;
620 } t = {
624 return &t;
626 case 5:
628 static struct {
629 int (*f)(const char *);
630 } t = {
631 call_back
633 return &t;
635 case 6:
637 static struct xt {
638 int x;
639 struct yt {
640 int i;
641 int j;
642 } _y;
643 int z;
644 } _x = {
646 { 127, 12345 },
649 return &_x;
651 case 7:
653 static struct xt {
654 char x;
655 struct yt {
656 char i;
657 int j;
658 } _y;
659 char z;
660 } _x = {
662 { 127, 12345 },
665 return &_x;
667 case 8:
669 static struct _z {
670 int i;
671 int j;
672 } zz = { 100, 77 };
673 static struct xt {
674 int x;
675 struct yt {
676 int i;
677 int j;
678 struct _z *z;
679 } _y;
680 } _x = {
682 { 127, 12345, &zz },
684 return &_x;
686 case 9:
688 static int i = 55555;
689 return &i;
691 default:
692 fprintf(stderr, "unknown test number\n");
695 return NULL;
700 =item C<PARROT_API short
701 nci_s(void)>
703 Returns the value of C<nci_dlvar_short>.
705 =cut
709 PARROT_API short
710 nci_s(void)
712 return nci_dlvar_short;
717 =item C<PARROT_API short
718 nci_ssc(short l1, char l2)>
720 Returns the product of C<l1 * l2>.
722 =cut
726 PARROT_API short
727 nci_ssc(short l1, char l2)
729 return l1 * l2;
734 =item C<PARROT_API void
735 nci_vP(void *pmc)>
737 Prints "ok" if C<PMC> is not null, prints "got null" otherwise.
739 =cut
743 PARROT_API void
744 nci_vP(void *pmc)
746 if (pmc)
747 puts("ok");
748 else
749 puts("got null");
755 =back
757 =head2 Functions used for pdd16 tests
759 =over 4
761 =cut
767 =item C<PARROT_API void
768 nci_cb_C1(cb_C1_func cb, void* user_data)>
770 Calls C<cb> function with the string "result" and the given C<user_data>.
771 No return value.
773 =cut
777 PARROT_API void
778 nci_cb_C1(cb_C1_func cb, void* user_data)
780 const char *result = "succeeded";
781 /* call the cb synchronously */
782 (cb)(result, user_data);
784 return;
789 =item C<PARROT_API void
790 nci_cb_C2(cb_C2_func cb, void* user_data)>
792 Calls the function C<cb> with the pointer C<user_data>. No return value.
794 =cut
798 PARROT_API void
799 nci_cb_C2(cb_C2_func cb, void* user_data)
801 /* call the cb synchronously */
802 (cb)(77, user_data);
804 return;
809 =item C<PARROT_API void
810 nci_cb_C3(cb_C3_func cb, void* user_data)>
812 Calls function C<cb> with data C<user_data>. No return value.
814 =cut
818 static int int_cb_C3 = 99;
820 PARROT_API void
821 nci_cb_C3(cb_C3_func cb, void* user_data)
823 /* call the cb synchronously */
824 (cb)(&int_cb_C3, user_data);
826 return;
831 =item C<PARROT_API void
832 nci_cb_D1(cb_D1_func cb, void* user_data)>
834 Calls function C<cb> with data C<user_data>. No return value.
836 =cut
840 PARROT_API void
841 nci_cb_D1(cb_D1_func cb, void* user_data)
843 const char *result = "succeeded";
844 /* call the cb synchronously */
845 (cb)(user_data, result);
847 return;
852 =item C<PARROT_API void
853 nci_cb_D2(cb_D2_func cb, void* user_data)>
855 Calls function C<cb> with data C<user_data>.
857 =cut
861 PARROT_API void
862 nci_cb_D2(cb_D2_func cb, void* user_data)
864 /* call the cb synchronously */
865 (cb)(user_data, 88);
867 return;
872 =item C<PARROT_API void
873 nci_cb_D3(cb_D3_func cb, void* user_data)>
875 Calls function C<cb> with data C<user_data>.
877 =cut
881 static int int_cb_D3 = 111;
883 PARROT_API void
884 nci_cb_D3(cb_D3_func cb, void* user_data)
886 /* call the cb synchronously */
887 (cb)(user_data, &int_cb_D3);
889 return;
894 =item C<PARROT_API void
895 nci_cb_D4(cb_D4_func times_ten, void* user_data)>
897 Calls function C<times_ten> with data C<user_data> 10 times in a loop.
899 =cut
903 PARROT_API void
904 nci_cb_D4(cb_D4_func times_ten, void* user_data)
906 int cnt;
907 for (cnt = 0; cnt < 9; cnt++)
909 (times_ten)(user_data, &int_cb_D4);
910 int_cb_D4++;
913 return;
918 =item C<PARROT_API void
919 nci_pip(int count, Rect_Like *rects)>
921 Prints a count integer and the coordinates of 4 rectangles.
923 =cut
927 PARROT_API void
928 nci_pip(int count, Rect_Like *rects)
930 int i;
931 printf("Count: %d\n", count);
932 for (i = 0; i < 4; ++i)
933 printf("X: %d\nY: %d\nW: %d\nH: %d\n",
934 rects[i].x, rects[i].y, rects[i].w, rects[i].h);
939 =item C<PARROT_API int
940 nci_i33(int *double_me, int *triple_me)>
942 Returns the result C<*double_me * 2 + *triple_me * 3>.
944 =cut
948 PARROT_API int
949 nci_i33(int *double_me, int *triple_me)
951 *double_me *= 2;
952 *triple_me *= 3;
954 return (*double_me + *triple_me);
959 =item C<PARROT_API void
960 nci_vpii(Outer *my_data, int my_x, int my_y)>
962 Updates data in structure pointer C<my_data> with the given data C<my_x> and
963 C<my_y>.
965 =cut
969 PARROT_API void
970 nci_vpii(Outer *my_data, int my_x, int my_y)
972 my_data->x = my_x;
973 my_data->nested->y = my_y;
978 =item C<PARROT_API void *
979 nci_piiii(int alpha, int beta, int gamma, int delta)>
981 Stores 4 integer values into an array structure, and returns the address
982 of that structure.
984 =cut
988 static int my_array[4];
990 PARROT_API void *
991 nci_piiii(int alpha, int beta, int gamma, int delta)
993 static struct array_container
995 int x;
996 int *array;
997 } container;
999 my_array[0] = alpha;
1000 my_array[1] = beta;
1001 my_array[2] = gamma;
1002 my_array[3] = delta;
1004 container.x = 4;
1005 container.array = my_array;
1007 return &container;
1012 =item C<PARROT_API void *
1013 nci_pii(int fac1, int fac2)>
1015 Returns the address of global variable C<nci_dlvar_int> whose value is set
1016 to the product of C<fac1 * fac2>.
1018 =cut
1022 PARROT_API void *
1023 nci_pii(int fac1, int fac2)
1025 nci_dlvar_int = fac1 * fac2;
1027 return &nci_dlvar_int;
1032 =item C<PARROT_API void
1033 nci_v(void)>
1035 Multiplies the global variable C<nci_dlvar_int> times 10.
1037 =cut
1041 PARROT_API void
1042 nci_v(void)
1044 nci_dlvar_int *= 10;
1049 =item C<PARROT_API void
1050 nci_vv(void)>
1052 Multiplies the global variable C<nci_dlvar_int> by 3.
1054 =cut
1058 PARROT_API void
1059 nci_vv(void)
1061 nci_dlvar_int *= 3;
1066 =item C<PARROT_API void
1067 nci_vVi(Opaque**, int)>
1069 Test an NCI opaque struct out value.
1071 =cut
1075 PARROT_API void
1076 nci_vVi(Opaque **outOpaque, int x)
1078 static Opaque opaque;
1079 opaque.x = x;
1080 *outOpaque = &opaque;
1085 =item C<PARROT_API int
1086 nci_vp(Opaque*)>
1088 Test that a previously generated opaque struct gets passed back
1089 to an NCI function correctly.
1091 =cut
1095 PARROT_API void
1096 nci_vp(Opaque *inOpaque)
1098 if (inOpaque)
1099 printf("got %d\n", inOpaque->x);
1100 else
1101 printf("got null");
1105 #ifdef TEST
1107 char l2 = 4;
1108 float f2 = 4.0;
1112 =item C<int
1113 main(void)>
1115 Calls test functions C<nci_ssc> and C<nci_fff> and prints their results.
1117 =cut
1122 main(void)
1124 short l1 = 3;
1125 float f, f1 = 3.0;
1126 int l = nci_ssc(l1, l2);
1127 printf("%d\n", l);
1128 f = nci_fff(f1, f2);
1129 printf("%f\n", f);
1131 return 0;
1134 #endif
1136 #ifdef __cplusplus
1138 #endif
1142 =back
1144 =head1 SEE ALSO:
1146 F<docs/pdds/pdd16_native_call.pod>
1147 F<config/gen/makefiles/root.in>
1148 F<t/pmc/nci.t>
1150 =cut
1156 * Local variables:
1157 * c-file-style: "parrot"
1158 * End:
1159 * vim: expandtab shiftwidth=4: