2 Copyright (C) 2001-2007, Parrot Foundation.
7 src/nci_test.c - shared library used for testing the Native Call Interface
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'.
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'.
39 #include <parrot/config.h>
46 /* Declarations of structs */
48 typedef struct Nested
{
52 typedef struct Outer
{
57 typedef struct Rect_Like
{
62 typedef struct Opaque
{
66 /* Function declarations.
68 *** If you add a new test function here,
69 *** please update src/libnci_test.def and src/call_list.txt too. ***
73 PARROT_EXPORT
int call_back(const char *str
);
74 PARROT_EXPORT
char nci_c(void);
75 PARROT_EXPORT
char nci_csc(short, char);
76 PARROT_EXPORT
double nci_d(void);
77 PARROT_EXPORT
double nci_dd(double);
78 PARROT_EXPORT
float nci_f(void);
79 PARROT_EXPORT
float nci_fff(float, float);
80 PARROT_EXPORT
int nci_i(void);
81 PARROT_EXPORT
int nci_ib(int *);
82 PARROT_EXPORT
int nci_iiii(int, int, int);
83 PARROT_EXPORT
int nci_ii3(int, int *);
84 PARROT_EXPORT
int nci_ip(void *);
85 PARROT_EXPORT
int nci_isc(short, char);
86 PARROT_EXPORT
int nci_it(void *);
87 PARROT_EXPORT
int nci_i33(int *, int *);
88 PARROT_EXPORT
int nci_i4i(long *, int);
89 PARROT_EXPORT
long nci_l(void);
90 PARROT_EXPORT
int * nci_p(void);
91 PARROT_EXPORT
void * nci_pi(int);
92 PARROT_EXPORT
void * nci_pii(int, int);
93 PARROT_EXPORT
void * nci_piiii(int, int, int, int);
94 PARROT_EXPORT
void nci_pip(int, Rect_Like
*);
95 PARROT_EXPORT
void * nci_pp(void *);
96 PARROT_EXPORT
short nci_s(void);
97 PARROT_EXPORT
short nci_ssc(short, char);
98 PARROT_EXPORT
char * nci_t(void);
99 PARROT_EXPORT
char * nci_tb(void *);
100 PARROT_EXPORT
char * nci_tB(void **);
101 PARROT_EXPORT
char * nci_tt(void *);
102 PARROT_EXPORT
void nci_v(void);
103 PARROT_EXPORT
void nci_vP(void *);
104 PARROT_EXPORT
void nci_vpii(Outer
*, int, int);
105 PARROT_EXPORT
void nci_vv(void);
106 PARROT_EXPORT
void nci_vVi(Opaque
**, int);
107 PARROT_EXPORT
void nci_vp(Opaque
*);
108 PARROT_EXPORT
char * nci_ttt(char *, char *);
109 PARROT_EXPORT
void nci_vfff(float, float, float);
110 PARROT_EXPORT
void nci_vV(const char **);
111 PARROT_EXPORT
void nci_vVVV(const char **, const char **, const char **);
113 /* Declarations for callback tests */
115 typedef void (*cb_C1_func
)(const char*, void*);
116 PARROT_EXPORT
void nci_cb_C1(cb_C1_func
, void*);
118 typedef void (*cb_C2_func
)(int, void*);
119 PARROT_EXPORT
void nci_cb_C2(cb_C2_func
, void*);
121 typedef void (*cb_C3_func
)(void*, void*);
122 PARROT_EXPORT
void nci_cb_C3(cb_C3_func
, void*);
124 typedef void (*cb_D1_func
)(void*, const char*);
125 PARROT_EXPORT
void nci_cb_D1(cb_D1_func
, void*);
127 typedef void (*cb_D2_func
)(void*, int);
128 PARROT_EXPORT
void nci_cb_D2(cb_D2_func
, void*);
130 typedef void (*cb_D3_func
)(void*, void*);
131 PARROT_EXPORT
void nci_cb_D3(cb_D3_func
, void*);
133 typedef void (*cb_D4_func
)(void*, void*);
134 PARROT_EXPORT
void nci_cb_D4(cb_D4_func
, void*);
136 /* Variable definitions */
138 PARROT_EXPORT
int int_cb_D4
= -55555;
139 PARROT_EXPORT
int nci_dlvar_char
= 22;
140 PARROT_EXPORT
int nci_dlvar_short
= 333;
141 PARROT_EXPORT
int nci_dlvar_int
= -4444;
142 PARROT_EXPORT
long nci_dlvar_long
= -7777777;
143 PARROT_EXPORT
float nci_dlvar_float
= -333.0;
144 PARROT_EXPORT
double nci_dlvar_double
= -55555.55555;
145 PARROT_EXPORT
char nci_dlvar_cstring
[] = "This is a C-string.\n";
148 /* Function definitions */
152 =item C<PARROT_EXPORT char
155 Returns the value of the variable C<nci_dlvar_char>, which is set to 22 by
164 return nci_dlvar_char
;
169 =item C<PARROT_EXPORT char
170 nci_csc(short l1, char l2)>
172 Multiplies C<l1> and C<l2> together and returns the first byte of the result.
179 nci_csc(short l1
, char l2
)
186 =item C<PARROT_EXPORT double
189 Multiplies the current value of C<nci_dlvar_double> by 10.0, and returns
199 nci_dlvar_double
*= 10.0;
201 return nci_dlvar_double
;
206 =item C<PARROT_EXPORT double
209 Returns the value C<d> multiplied by 2.0.
223 =item C<PARROT_EXPORT float
226 Multiplies the value C<nci_dlvar_float> by 10.0 and returns the new
236 nci_dlvar_float
*= 10.0;
238 return nci_dlvar_float
;
243 =item C<PARROT_EXPORT float
244 nci_fff(float l1, float l2)>
246 Returns the result of C<l1> / C<l2>.
253 nci_fff(float l1
, float l2
)
260 =item C<PARROT_EXPORT int
263 Returns the current value of <nci_dlvar_int>.
272 return nci_dlvar_int
;
277 =item C<PARROT_EXPORT int
278 nci_isc(short l1, char l2)>
280 Returns the int product of C<l1 * l2>.
287 nci_isc(short l1
, char l2
)
294 =item C<PARROT_EXPORT int
297 Performs a series of operations on values stored at pointer C<p>.
306 typedef struct _dfi
{
316 return (int) (sp
->d
+ sp
->f
+ sp
->i
);
321 =item C<PARROT_EXPORT int
324 test calls this with a string
333 fprintf(stderr
, "%c%c\n", ((char*) p
)[1], ((char *) p
)[0]);
341 =item C<PARROT_EXPORT long
344 Returns the value of C<nci_dlvar_long>.
353 return nci_dlvar_long
;
358 =item C<PARROT_EXPORT int *
361 Returns the address of C<nci_dlvar_int>.
370 return &nci_dlvar_int
;
375 =item C<PARROT_EXPORT char *
378 Returns the value of C<nci_dlvar_cstring>.
387 return nci_dlvar_cstring
;
392 =item C<PARROT_EXPORT char *
395 Prints "xx worked", where "xx" is replaced with the first two character values
396 of C<p>, in reverse order.
402 static char b
[] = "xx worked\n";
407 b
[0] = ((char*) p
)[1];
408 b
[1] = ((char*) p
)[0];
415 =item C<PARROT_EXPORT char *
418 Prints "xx worked", where "xx" is replaced with the first two character values
419 of C<p>, in reverse order.
425 static char s
[] = "xx worked\n";
430 s
[0] = ((char*) p
)[1];
431 s
[1] = ((char*) p
)[0];
438 =item C<PARROT_EXPORT char *
441 Prints "xx done", where "xx" is replaced with the first two character values
442 of C<p>, in reverse order.
448 static char B
[] = "xx done\n";
453 B
[0] = (*(char**) p
)[1];
454 B
[1] = (*(char**) p
)[0];
461 =item C<PARROT_EXPORT void *
464 Returns the value C<p> directly.
478 =item C<PARROT_EXPORT int
479 nci_iiii(int i1, int i2, int i3)>
481 Prints three integers separated by whitespace to C<stderr>.
488 nci_iiii(int i1
, int i2
, int i3
)
490 fprintf(stderr
, "%d %d %d\n", i1
, i2
, i3
);
498 =item C<PARROT_EXPORT int
499 nci_i4i(long * l, int i)>
501 Returns the product of C<*l> and C<i>, as an int.
508 nci_i4i(long * l
, int i
)
511 return (int) (*l
* i
);
516 =item C<PARROT_EXPORT int
517 nci_ii3(int a, int *bp)>
519 Multiplies C<a> and C<*bp> together and returns the result. Updates C<*bp>
527 nci_ii3(int a
, int *bp
)
537 =item C<PARROT_EXPORT int
538 call_back(const char *str)>
540 writes the string C<str> to stdout and returns the value 4711.
547 call_back(const char *str
)
557 =item C<PARROT_EXPORT void *
560 Performs one from a series of tests, depending on the value given for C<test>.
620 } xx
= { 100, 77, 200.0 };
633 int (*f
)(const char *);
692 static int i
= 55555;
696 fprintf(stderr
, "unknown test number\n");
704 =item C<PARROT_EXPORT short
707 Returns the value of C<nci_dlvar_short>.
716 return nci_dlvar_short
;
721 =item C<PARROT_EXPORT short
722 nci_ssc(short l1, char l2)>
724 Returns the product of C<l1 * l2>.
731 nci_ssc(short l1
, char l2
)
738 =item C<PARROT_EXPORT void
741 Prints "ok" if C<PMC> is not null, prints "got null" otherwise.
761 =head2 Functions used for pdd16 tests
771 =item C<PARROT_EXPORT void
772 nci_cb_C1(cb_C1_func cb, void* user_data)>
774 Calls C<cb> function with the string "result" and the given C<user_data>.
782 nci_cb_C1(cb_C1_func cb
, void* user_data
)
784 const char *result
= "succeeded";
785 /* call the cb synchronously */
786 (cb
)(result
, user_data
);
793 =item C<PARROT_EXPORT void
794 nci_cb_C2(cb_C2_func cb, void* user_data)>
796 Calls the function C<cb> with the pointer C<user_data>. No return value.
803 nci_cb_C2(cb_C2_func cb
, void* user_data
)
805 /* call the cb synchronously */
813 =item C<PARROT_EXPORT void
814 nci_cb_C3(cb_C3_func cb, void* user_data)>
816 Calls function C<cb> with data C<user_data>. No return value.
822 static int int_cb_C3
= 99;
825 nci_cb_C3(cb_C3_func cb
, void* user_data
)
827 /* call the cb synchronously */
828 (cb
)(&int_cb_C3
, user_data
);
835 =item C<PARROT_EXPORT void
836 nci_cb_D1(cb_D1_func cb, void* user_data)>
838 Calls function C<cb> with data C<user_data>. No return value.
845 nci_cb_D1(cb_D1_func cb
, void* user_data
)
847 const char *result
= "succeeded";
848 /* call the cb synchronously */
849 (cb
)(user_data
, result
);
856 =item C<PARROT_EXPORT void
857 nci_cb_D2(cb_D2_func cb, void* user_data)>
859 Calls function C<cb> with data C<user_data>.
866 nci_cb_D2(cb_D2_func cb
, void* user_data
)
868 /* call the cb synchronously */
876 =item C<PARROT_EXPORT void
877 nci_cb_D3(cb_D3_func cb, void* user_data)>
879 Calls function C<cb> with data C<user_data>.
885 static int int_cb_D3
= 111;
888 nci_cb_D3(cb_D3_func cb
, void* user_data
)
890 /* call the cb synchronously */
891 (cb
)(user_data
, &int_cb_D3
);
898 =item C<PARROT_EXPORT void
899 nci_cb_D4(cb_D4_func times_ten, void* user_data)>
901 Calls function C<times_ten> with data C<user_data> 10 times in a loop.
908 nci_cb_D4(cb_D4_func times_ten
, void* user_data
)
911 for (cnt
= 0; cnt
< 9; cnt
++)
913 (times_ten
)(user_data
, &int_cb_D4
);
922 =item C<PARROT_EXPORT void
923 nci_pip(int count, Rect_Like *rects)>
925 Prints a count integer and the coordinates of 4 rectangles.
932 nci_pip(int count
, Rect_Like
*rects
)
935 printf("Count: %d\n", count
);
936 for (i
= 0; i
< 4; ++i
)
937 printf("X: %d\nY: %d\nW: %d\nH: %d\n",
938 rects
[i
].x
, rects
[i
].y
, rects
[i
].w
, rects
[i
].h
);
943 =item C<PARROT_EXPORT int
944 nci_i33(int *double_me, int *triple_me)>
946 Returns the result C<*double_me * 2 + *triple_me * 3>.
953 nci_i33(int *double_me
, int *triple_me
)
958 return (*double_me
+ *triple_me
);
963 =item C<PARROT_EXPORT void
964 nci_vpii(Outer *my_data, int my_x, int my_y)>
966 Updates data in structure pointer C<my_data> with the given data C<my_x> and
974 nci_vpii(Outer
*my_data
, int my_x
, int my_y
)
977 my_data
->nested
->y
= my_y
;
982 =item C<PARROT_EXPORT void *
983 nci_piiii(int alpha, int beta, int gamma, int delta)>
985 Stores 4 integer values into an array structure, and returns the address
992 static int my_array
[4];
995 nci_piiii(int alpha
, int beta
, int gamma
, int delta
)
997 static struct array_container
1003 my_array
[0] = alpha
;
1005 my_array
[2] = gamma
;
1006 my_array
[3] = delta
;
1009 container
.array
= my_array
;
1016 =item C<PARROT_EXPORT void *
1017 nci_pii(int fac1, int fac2)>
1019 Returns the address of global variable C<nci_dlvar_int> whose value is set
1020 to the product of C<fac1 * fac2>.
1026 PARROT_EXPORT
void *
1027 nci_pii(int fac1
, int fac2
)
1029 nci_dlvar_int
= fac1
* fac2
;
1031 return &nci_dlvar_int
;
1036 =item C<PARROT_EXPORT void
1039 Multiplies the global variable C<nci_dlvar_int> times 10.
1048 nci_dlvar_int
*= 10;
1053 =item C<PARROT_EXPORT void
1056 Multiplies the global variable C<nci_dlvar_int> by 3.
1070 =item C<PARROT_EXPORT void
1071 nci_vVi(Opaque**, int)>
1073 Test an NCI opaque struct out value.
1080 nci_vVi(Opaque
**outOpaque
, int x
)
1082 static Opaque opaque
;
1084 *outOpaque
= &opaque
;
1089 =item C<PARROT_EXPORT int
1092 Test that a previously generated opaque struct gets passed back
1093 to an NCI function correctly.
1100 nci_vp(Opaque
*inOpaque
)
1103 printf("got %d\n", inOpaque
->x
);
1110 =item C<PARROT_EXPORT char *
1113 Prints "s2, s1, s1d"
1119 PARROT_EXPORT
char *
1120 nci_ttt(char *s1
, char *s2
)
1122 char* s
= (char*) malloc(strlen(s2
) + (2 * strlen(s1
)) + 5);
1123 sprintf(s
, "%s, %s, %s", s2
, s2
, s1
);
1129 static void validate_float(float f
, double checkval
) {
1132 error_ratio
= (((double)f
) - checkval
) / checkval
;
1133 valid
= error_ratio
<= 0.01 && error_ratio
>= -0.01;
1134 printf("%i\n", valid
);
1139 =item C<PARROT_EXPORT float
1140 nci_fff(float l1, float l2)>
1142 Returns the result of C<l1> / C<l2>.
1149 nci_vfff(float l1
, float l2
, float l3
)
1151 validate_float(l1
, 3456.54);
1152 validate_float(l2
, 10.1999);
1153 validate_float(l3
, 14245.567);
1159 =item C<PARROT_EXPORT float
1160 nci_fff(float l1, float l2)>
1162 Returns the result of C<l1> / C<l2>.
1169 nci_vV(const char **ptr
)
1171 *ptr
= "Hello bright new world\n";
1176 =item C<PARROT_EXPORT float
1177 nci_fff(float l1, float l2)>
1179 Returns the result of C<l1> / C<l2>.
1186 nci_vVVV(const char **ptr1
, const char **ptr2
, const char **ptr3
)
1188 *ptr1
= "Hello bright new world!\n";
1189 *ptr2
= "It is a beautiful day!\n";
1190 *ptr3
= "Go suck a lemon.\n";
1203 Calls test functions C<nci_ssc> and C<nci_fff> and prints their results.
1214 int l
= nci_ssc(l1
, l2
);
1216 f
= nci_fff(f1
, f2
);
1234 F<docs/pdds/pdd16_native_call.pod>
1235 F<config/gen/makefiles/root.in>
1245 * c-file-style: "parrot"
1247 * vim: expandtab shiftwidth=4: