1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * typemaps.i
6 *
7 * The Ocaml module handles all types uniformly via typemaps. Here
8 * are the definitions.
9 * ----------------------------------------------------------------------------- */
10
11/* Pointers */
12
13%typemap(in) void ""
14
15%typemap(out) void "$result = Val_int(0);"
16
17%typemap(in) void * {
18    $1 = caml_ptr_val($input,$descriptor);
19}
20
21%typemap(varin) void * {
22    $1 = ($ltype)caml_ptr_val($input,$descriptor);
23}
24
25%typemap(out) void * {
26    $result = caml_val_ptr($1,$descriptor);
27}
28
29%typemap(varout) void * {
30    $result = caml_val_ptr($1,$descriptor);
31}
32
33#ifdef __cplusplus
34
35%typemap(in) SWIGTYPE & {
36    /* %typemap(in) SWIGTYPE & */
37    $1 = ($ltype) caml_ptr_val($input,$1_descriptor);
38}
39
40%typemap(varin) SWIGTYPE & {
41    /* %typemap(varin) SWIGTYPE & */
42    $1 = *(($ltype) caml_ptr_val($input,$1_descriptor));
43}
44
45%typemap(out) SWIGTYPE & {
46    /* %typemap(out) SWIGTYPE & */
47    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
48    if( fromval ) {
49	$result = callback(*fromval,caml_val_ptr((void *) &$1,$1_descriptor));
50    } else {
51	$result = caml_val_ptr ((void *) &$1,$1_descriptor);
52    }
53}
54
55#if 0
56%typemap(argout) SWIGTYPE & {
57    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
58    if( fromval ) {
59	swig_result =
60	    caml_list_append(swig_result,
61			     callback(*fromval,caml_val_ptr((void *) $1,
62							    $1_descriptor)));
63    } else {
64	swig_result =
65	    caml_list_append(swig_result,
66			     caml_val_ptr ((void *) $1,$1_descriptor));
67    }
68}
69#endif
70
71%typemap(argout) const SWIGTYPE & { }
72
73%typemap(in) SWIGTYPE {
74    $1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ;
75}
76
77%typemap(out) SWIGTYPE {
78    /* %typemap(out) SWIGTYPE */
79    $&1_ltype temp = new $ltype((const $1_ltype &) $1);
80    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
81    if( fromval ) {
82	$result = callback(*fromval,caml_val_ptr((void *)temp,$&1_descriptor));
83    } else {
84	$result = caml_val_ptr ((void *)temp,$&1_descriptor);
85    }
86}
87
88#else
89
90%typemap(in) SWIGTYPE {
91    $1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ;
92}
93
94%typemap(out) SWIGTYPE {
95    /* %typemap(out) SWIGTYPE */
96    void *temp = calloc(1,sizeof($ltype));
97    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
98    memmove( temp, &$1, sizeof( $1_type ) );
99    if( fromval ) {
100	$result = callback(*fromval,caml_val_ptr((void *)temp,$&1_descriptor));
101    } else {
102	$result = caml_val_ptr ((void *)temp,$&1_descriptor);
103    }
104}
105
106%apply SWIGTYPE { const SWIGTYPE & };
107
108#endif
109
110/* The SIMPLE_MAP macro below defines the whole set of typemaps needed
111   for simple types. */
112
113%define SIMPLE_MAP(C_NAME, C_TO_MZ, MZ_TO_C)
114/* In */
115%typemap(in) C_NAME {
116    $1 = MZ_TO_C($input);
117}
118%typemap(varin) C_NAME {
119    $1 = MZ_TO_C($input);
120}
121%typemap(in) C_NAME & ($*1_ltype temp) {
122    temp = ($*1_ltype) MZ_TO_C($input);
123    $1 = &temp;
124}
125%typemap(varin) C_NAME & {
126    $1 = MZ_TO_C($input);
127}
128%typemap(directorout) C_NAME {
129    $1 = MZ_TO_C($input);
130}
131%typemap(in) C_NAME *INPUT ($*1_ltype temp) {
132    temp = ($*1_ltype) MZ_TO_C($input);
133    $1 = &temp;
134}
135%typemap(in,numinputs=0) C_NAME *OUTPUT ($*1_ltype temp) {
136    $1 = &temp;
137}
138/* Out */
139%typemap(out) C_NAME {
140    $result = C_TO_MZ($1);
141}
142%typemap(varout) C_NAME {
143    $result = C_TO_MZ($1);
144}
145%typemap(varout) C_NAME & {
146    /* %typemap(varout) C_NAME & (generic) */
147    $result = C_TO_MZ($1);
148}
149%typemap(argout) C_NAME *OUTPUT {
150    swig_result = caml_list_append(swig_result,C_TO_MZ((long)*$1));
151}
152%typemap(out) C_NAME & {
153    /* %typemap(out) C_NAME & (generic) */
154    $result = C_TO_MZ(*$1);
155}
156%typemap(argout) C_NAME & {
157    swig_result = caml_list_append(swig_result,C_TO_MZ((long)*$1));
158}
159%typemap(directorin) C_NAME {
160    args = caml_list_append(args,C_TO_MZ($1_name));
161}
162%enddef
163
164SIMPLE_MAP(bool, caml_val_bool, caml_long_val);
165SIMPLE_MAP(oc_bool, caml_val_bool, caml_long_val);
166SIMPLE_MAP(char, caml_val_char, caml_long_val);
167SIMPLE_MAP(signed char, caml_val_char, caml_long_val);
168SIMPLE_MAP(unsigned char, caml_val_uchar, caml_long_val);
169SIMPLE_MAP(int, caml_val_int, caml_long_val);
170SIMPLE_MAP(short, caml_val_short, caml_long_val);
171SIMPLE_MAP(wchar_t, caml_val_short, caml_long_val);
172SIMPLE_MAP(long, caml_val_long, caml_long_val);
173SIMPLE_MAP(ptrdiff_t, caml_val_int, caml_long_val);
174SIMPLE_MAP(unsigned int, caml_val_uint, caml_long_val);
175SIMPLE_MAP(unsigned short, caml_val_ushort, caml_long_val);
176SIMPLE_MAP(unsigned long, caml_val_ulong, caml_long_val);
177SIMPLE_MAP(size_t, caml_val_int, caml_long_val);
178SIMPLE_MAP(float, caml_val_float, caml_double_val);
179SIMPLE_MAP(double, caml_val_double, caml_double_val);
180SIMPLE_MAP(long long,caml_val_ulong,caml_long_val);
181SIMPLE_MAP(unsigned long long,caml_val_ulong,caml_long_val);
182
183/* Void */
184
185%typemap(out) void "$result = Val_unit;";
186
187/* Pass through value */
188
189%typemap (in) value,caml::value,CAML_VALUE "$1=$input;";
190%typemap (out) value,caml::value,CAML_VALUE "$result=$1;";
191
192/* Arrays */
193
194%typemap(in) ArrayCarrier * {
195    $1 = ($ltype)caml_ptr_val($input,$1_descriptor);
196}
197
198%typemap(out) ArrayCarrier * {
199    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
200    if( fromval ) {
201	$result = callback(*fromval,caml_val_ptr((void *)$1,$1_descriptor));
202    } else {
203	$result = caml_val_ptr ((void *)$1,$1_descriptor);
204    }
205}
206
207#if 0
208%include <carray.i>
209#endif
210
211/* Handle char arrays as strings */
212
213%define %char_ptr_in(how)
214%typemap(how)  char *, signed char *, unsigned char * {
215    /* %typemap(how) char * ... */
216    $1 = ($ltype)caml_string_val($input);
217}
218/* Again work around the empty array bound bug */
219%typemap(how) char [ANY], signed char [ANY], unsigned char [ANY] {
220    /* %typemap(how) char [ANY] ... */
221    char *temp = caml_string_val($input);
222    strcpy((char *)$1,temp);
223    /* strncpy would be better but we might not have an array size */
224}
225%enddef
226
227%char_ptr_in(in);
228%char_ptr_in(varin);
229%char_ptr_in(directorout);
230
231%define %char_ptr_out(how)
232%typemap(how)
233    char *, signed char *, unsigned char *,
234    const char *, const signed char *, const unsigned char * {
235    $result = caml_val_string((char *)$1);
236}
237/* I'd like to use the length here but can't because it might be empty */
238%typemap(how)
239    char [ANY], signed char [ANY], unsigned char [ANY],
240    const char [ANY], const signed char [ANY], const unsigned char [ANY] {
241    $result = caml_val_string((char *)$1);
242}
243%enddef
244
245%char_ptr_out(out);
246%char_ptr_out(varout);
247%char_ptr_out(directorin);
248
249%define %swigtype_ptr_in(how)
250%typemap(how) SWIGTYPE * {
251    /* %typemap(how) SWIGTYPE * */
252    $1 = ($ltype)caml_ptr_val($input,$1_descriptor);
253}
254%typemap(how) SWIGTYPE (CLASS::*) {
255    /* %typemap(how) SWIGTYPE (CLASS::*) */
256    void *v = caml_ptr_val($input,$1_descriptor);
257    memcpy(& $1, &v, sizeof(v));
258}
259%enddef
260
261%define %swigtype_ptr_out(how)
262%typemap(out) SWIGTYPE * {
263    /* %typemap(how) SWIGTYPE *, SWIGTYPE (CLASS::*) */
264    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
265    if( fromval ) {
266	$result = callback(*fromval,caml_val_ptr((void *)$1,$1_descriptor));
267    } else {
268	$result = caml_val_ptr ((void *)$1,$1_descriptor);
269    }
270}
271%typemap(how) SWIGTYPE (CLASS::*) {
272    /* %typemap(how) SWIGTYPE *, SWIGTYPE (CLASS::*) */
273    void *v;
274    memcpy(&v,& $1, sizeof(void *));
275    $result = caml_val_ptr (v,$1_descriptor);
276}
277%enddef
278
279%swigtype_ptr_in(in);
280%swigtype_ptr_in(varin);
281%swigtype_ptr_in(directorout);
282%swigtype_ptr_out(out);
283%swigtype_ptr_out(varout);
284%swigtype_ptr_out(directorin);
285
286%define %swigtype_array_fail(how,msg)
287%typemap(how) SWIGTYPE [] {
288    failwith(msg);
289}
290%enddef
291
292%swigtype_array_fail(in,"Array arguments for arbitrary types need a typemap");
293%swigtype_array_fail(varin,"Assignment to global arrays for arbitrary types need a typemap");
294%swigtype_array_fail(out,"Array arguments for arbitrary types need a typemap");
295%swigtype_array_fail(varout,"Array variables need a typemap");
296%swigtype_array_fail(directorin,"Array results with arbitrary types need a typemap");
297%swigtype_array_fail(directorout,"Array arguments with arbitrary types need a typemap");
298
299/* C++ References */
300
301/* Enums */
302%define %swig_enum_in(how)
303%typemap(how) enum SWIGTYPE {
304    $1 = ($type)caml_long_val_full($input,"$type_marker");
305}
306%enddef
307
308%define %swig_enum_out(how)
309%typemap(how) enum SWIGTYPE {
310    $result = callback2(*caml_named_value(SWIG_MODULE "_int_to_enum"),*caml_named_value("$type_marker"),Val_int((int)$1));
311}
312%enddef
313
314%swig_enum_in(in)
315%swig_enum_in(varin)
316%swig_enum_in(directorout)
317%swig_enum_out(out)
318%swig_enum_out(varout)
319%swig_enum_out(directorin)
320