File: ffitest.c

package info (click to toggle)
newlisp 10.7.5-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 6,248 kB
  • sloc: ansic: 33,280; lisp: 4,181; sh: 609; makefile: 215
file content (230 lines) | stat: -rw-r--r-- 4,016 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

/*
 testffi.c
 test FFI correct passing of parameter and return types

 this file is used in qa-specific-tests/qa-libffi

 compile using either:
     gcc -m32 ffitest.c -shared -o ffitest.dylib
 or
     gcc -m64 ffitest.c -shared -o ffitest.dylib


 all intx tupes must correctly handle sign-extension
 and unsigning
 e.g.: (ret_uint8 -1) => 255
       (ret_int8 255) => -1

    user API type  ffi type
    -------------  --------
    "byte"         &ffi_type_uint8
    "char"         &ffi_type_sint8
    "short int"    &ffi_type_sint16
    "unsigned short int"    &ffi_type_uint16
    "unsigned int" &ffi_type_uint32
    "int"          &ffi_type_sint32
#ifdef NEWLISP64
    "long"          &ffi_type_sint64
#else
    "long"          &ffi_type_sint32
#endif
    "long long"    &ffi_type_sint64
    "float"        &ffi_type_float
    "double"       &ffi_type_double
    "char*"        &ffi_type_pointer  input string or address, return string 
    "void*"        &ffi_type_pointer  input string or address, return address
#endif
*/

char ret_sint8(char number)
    {
    return(number);
    }

char ret_uint8(unsigned char number)
    {
    return(number);
    }

short int ret_sint16(int number)
    {
    return(number);
    }

short int ret_uint16(unsigned int number)
    {
    return(number);
    }

int ret_sint32(int number)
    {
    return(number);
    }

int ret_sint32_void(void)
    {
    return(-1);
    }

unsigned int ret_uint32(unsigned int number)
    {
    return(number);
    }

long long ret_sint64(long long number)
    {
    return(number);
    }

float ret_float(float number)
    {
    return(number);
    }

double ret_double(double number)
    {
    return(number);
    }

double add_double(double number1, double number2)
    {
    return(number1 + number2);
    }

char * ret_pointer(char * ptr)
    {
    char * upper;
    upper = ptr;
    while(*ptr) { *ptr = toupper(*ptr); ptr++; }
    return(upper);
    }

char * string_copy(char * from, char * to)
    {
    strcpy(to, from);
    return(to);
    }

/* test ffi closure API */

void (*function)(char * str, int inum, double fnum);

void register_callback(void * ptr)
    {
    function = ptr;
    }

void trigger_callback()
    {
    double dnum = 12345.67890;

    (*function)(">>>>> callback API ", 1234567890, dnum);
    }

/* test simple ffi */

void (*function_simple)(char * str, int inum);

void register_callback_simple(void * ptr)
    {
    function_simple = ptr;
    }

void trigger_callback_simple() /* only handles strings and integers */
    {
    long inum = 1234567890;

    (*function_simple)(">>>>> callback API ", inum);
    }

/* test struct API */

typedef struct clock
    {
    char hour;
    int min;
    short int sec;
    } clock;

clock addClock(clock in)
    {
    in.hour += 1;
    in.min += 1;
    in.sec += 1;
    return in;
    }

typedef struct foo
	{
	char first;
	int second;
	short int third;
	char * word;
	} foo;

foo * useFoo(int value)
	{
	foo * bar = malloc(sizeof(foo));
	bar->first = 1 + value;	
	bar->second = 2 + value;	
	bar->third = 3 + value;	
	bar->word = "hello world";
	return bar;
	}


/* miscellanous tests */

typedef struct 
{
double dat[2];
} gsl_complex;

/* structure return
(struct 'complex "double" "double")
(import LIB "gsl_complex_rect" "complex" "double" "double")
(gsl_complex_rect 3.0 4.0) ;=> (3 4)
*/

gsl_complex complex_test(gsl_complex gs)
{
return(gs);
}


/* mixed floats intd for simple ffi and 32bit
(import "ffitest.dylib" "mixed_int_float")
(get-string (mixed_int_float 123 (flt 123.456) 456 (flt 789.123)))
;=> "123 123.456001 456 789.122986\n"
*/

char * mixed_int_float(int x, float a, int y, float b)
{
static char buff[100];

sprintf(buff, "%d %f %d %f\n", x, a, y, b);

return(buff);
}

/* arrays */

int array_test(int n, int m, double * ptr[])
{
int i , j;

for(i = 0; i < n; i++)
    for(j = 0; j < m; j++)
        printf("%lf ", ptr[i][j]);

return(0);
}



/* eof */