Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* list-vector.i --- Guile typemaps for converting between -*- c -*- arrays |
2 | and Scheme lists or vectors | |
3 | ||
4 | Copyright (C) 2001, 2002 Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de> | |
5 | ||
6 | $Header: /cvsroot/swig/SWIG/Lib/guile/list-vector.i,v 1.6 2003/09/10 11:22:12 mkoeppe Exp $ | |
7 | */ | |
8 | ||
9 | /* Here is a macro that will define typemaps for converting between C | |
10 | arrays and Scheme lists or vectors when passing arguments to the C | |
11 | function. | |
12 | ||
13 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) | |
14 | ||
15 | Supported calling conventions: | |
16 | ||
17 | func(int VECTORLENINPUT, [const] C_TYPE *VECTORINPUT) | |
18 | ||
19 | Scheme wrapper will take one argument, a vector. A temporary C | |
20 | array of elements of type C_TYPE will be allocated and filled | |
21 | with the elements of the vectors, converted to C with the | |
22 | SCM_TO_C function. Length and address of the array are passed | |
23 | to the C function. | |
24 | ||
25 | SCM_TYPE is used to describe the Scheme type of the elements in | |
26 | the Guile procedure documentation. | |
27 | ||
28 | func(int LISTLENINPUT, [const] C_TYPE *LISTINPUT) | |
29 | ||
30 | Likewise, but the Scheme wrapper will take one argument, a list. | |
31 | ||
32 | func(int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) | |
33 | ||
34 | Scheme wrapper will take no arguments. Addresses of an integer | |
35 | and a C_TYPE * variable will be passed to the C function. The | |
36 | C function is expected to return address and length of a | |
37 | freshly allocated array of elements of type C_TYPE through | |
38 | these pointers. The elements of this array are converted to | |
39 | Scheme with the C_TO_SCM function and returned as a Scheme | |
40 | vector. | |
41 | ||
42 | If the function has a void return value, the vector constructed | |
43 | by this typemap becomes the return value of the Scheme wrapper. | |
44 | Otherwise, the function returns multiple values. (See | |
45 | the documentation on how to deal with multiple values.) | |
46 | ||
47 | func(int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) | |
48 | ||
49 | Likewise, but the Scheme wrapper will return a list instead of | |
50 | a vector. | |
51 | ||
52 | It is also allowed to use "size_t LISTLENINPUT" rather than "int | |
53 | LISTLENINPUT". */ | |
54 | ||
55 | %define TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) | |
56 | ||
57 | /* input */ | |
58 | ||
59 | /* We make use of the new multi-dispatch typemaps here. */ | |
60 | ||
61 | %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values") | |
62 | (int VECTORLENINPUT, C_TYPE *VECTORINPUT), | |
63 | (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT) | |
64 | { | |
65 | SCM_VALIDATE_VECTOR($argnum, $input); | |
66 | $1 = gh_vector_length($input); | |
67 | if ($1 > 0) { | |
68 | $1_ltype i; | |
69 | $2 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * $1); | |
70 | for (i = 0; i<$1; i++) { | |
71 | SCM swig_scm_value = gh_vector_ref($input, gh_int2scm(i)); | |
72 | $2[i] = SCM_TO_C_EXPR; | |
73 | } | |
74 | } | |
75 | else $2 = NULL; | |
76 | } | |
77 | ||
78 | %typemap(in, doc="$NAME is a list of " #SCM_TYPE " values") | |
79 | (int LISTLENINPUT, C_TYPE *LISTINPUT), | |
80 | (size_t LISTLENINPUT, C_TYPE *LISTINPUT) | |
81 | { | |
82 | SCM_VALIDATE_LIST($argnum, $input); | |
83 | $1 = gh_length($input); | |
84 | if ($1 > 0) { | |
85 | $1_ltype i; | |
86 | SCM rest; | |
87 | $2 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * $1); | |
88 | for (i = 0, rest = $input; | |
89 | i<$1; | |
90 | i++, rest = gh_cdr(rest)) { | |
91 | SCM swig_scm_value = gh_car(rest); | |
92 | $2[i] = SCM_TO_C_EXPR; | |
93 | } | |
94 | } | |
95 | else $2 = NULL; | |
96 | } | |
97 | ||
98 | /* Do not check for NULL pointers (override checks). */ | |
99 | ||
100 | %typemap(check) (int VECTORLENINPUT, C_TYPE *VECTORINPUT), | |
101 | (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT), | |
102 | (int LISTLENINPUT, C_TYPE *LISTINPUT), | |
103 | (size_t LISTLENINPUT, C_TYPE *LISTINPUT) | |
104 | "/* no check for NULL pointer */"; | |
105 | ||
106 | /* Discard the temporary array after the call. */ | |
107 | ||
108 | %typemap(freearg) (int VECTORLENINPUT, C_TYPE *VECTORINPUT), | |
109 | (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT), | |
110 | (int LISTLENINPUT, C_TYPE *LISTINPUT), | |
111 | (size_t LISTLENINPUT, C_TYPE *LISTINPUT) | |
112 | {if ($2!=NULL) SWIG_free($2);} | |
113 | ||
114 | %enddef | |
115 | ||
116 | /* output */ | |
117 | ||
118 | %define TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) | |
119 | ||
120 | /* First we make temporary variables ARRAYLENTEMP and ARRAYTEMP, | |
121 | whose addresses we pass to the C function. We ignore both | |
122 | arguments for Scheme. */ | |
123 | ||
124 | %typemap(in,numinputs=0) (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) | |
125 | (int arraylentemp, C_TYPE *arraytemp), | |
126 | (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) | |
127 | (int arraylentemp, C_TYPE *arraytemp), | |
128 | (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) | |
129 | (int arraylentemp, C_TYPE *arraytemp), | |
130 | (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) | |
131 | (int arraylentemp, C_TYPE *arraytemp) | |
132 | %{ | |
133 | $1 = &arraylentemp; | |
134 | $2 = &arraytemp; | |
135 | %} | |
136 | ||
137 | /* In the ARGOUT typemaps, we convert the array into a vector or | |
138 | a list and append it to the results. */ | |
139 | ||
140 | %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)") | |
141 | (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), | |
142 | (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) | |
143 | { | |
144 | $*1_ltype i; | |
145 | SCM res = gh_make_vector(gh_int2scm(*$1), | |
146 | SCM_BOOL_F); | |
147 | for (i = 0; i<*$1; i++) { | |
148 | C_TYPE swig_c_value = (*$2)[i]; | |
149 | SCM elt = C_TO_SCM_EXPR; | |
150 | gh_vector_set_x(res, gh_int2scm(i), elt); | |
151 | } | |
152 | SWIG_APPEND_VALUE(res); | |
153 | } | |
154 | ||
155 | %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)") | |
156 | (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT), | |
157 | (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) | |
158 | { | |
159 | int i; | |
160 | SCM res = SCM_EOL; | |
161 | for (i = ((int)(*$1)) - 1; i>=0; i--) { | |
162 | C_TYPE swig_c_value = (*$2)[i]; | |
163 | SCM elt = C_TO_SCM_EXPR; | |
164 | res = gh_cons(elt, res); | |
165 | } | |
166 | SWIG_APPEND_VALUE(res); | |
167 | } | |
168 | ||
169 | /* In the FREEARG typemaps, get rid of the C vector. | |
170 | (This can be overridden if you want to keep the C vector.) */ | |
171 | ||
172 | %typemap(freearg) | |
173 | (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), | |
174 | (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), | |
175 | (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT), | |
176 | (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) | |
177 | { | |
178 | if ((*$2)!=NULL) free(*$2); | |
179 | } | |
180 | ||
181 | %enddef | |
182 | ||
183 | %define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE) | |
184 | TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) | |
185 | TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) | |
186 | %enddef | |
187 | ||
188 | %define TYPEMAP_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE) | |
189 | TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR | |
190 | (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE) | |
191 | %enddef | |
192 | ||
193 | %define TYPEMAP_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE) | |
194 | TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR | |
195 | (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE) | |
196 | %enddef | |
197 | ||
198 | %define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) | |
199 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR | |
200 | (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE) | |
201 | %enddef | |
202 | ||
203 | /* We use the macro to define typemaps for some standard types. */ | |
204 | ||
205 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(bool, gh_scm2bool, gh_bool2scm, boolean); | |
206 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char, gh_scm2char, gh_char2scm, char); | |
207 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned char, gh_scm2char, gh_char2scm, char); | |
208 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(int, gh_scm2int, gh_int2scm, integer); | |
209 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(short, gh_scm2int, gh_int2scm, integer); | |
210 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(long, gh_scm2long, gh_long2scm, integer); | |
211 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, gh_scm2long, gh_long2scm, integer); | |
212 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned int, gh_scm2ulong, gh_ulong2scm, integer); | |
213 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned short, gh_scm2ulong, gh_ulong2scm, integer); | |
214 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned long, gh_scm2ulong, gh_ulong2scm, integer); | |
215 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(size_t, gh_scm2ulong, gh_ulong2scm, integer); | |
216 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(float, gh_scm2double, gh_double2scm, real); | |
217 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(double, gh_scm2double, gh_double2scm, real); | |
218 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, gh_str02scm, string); | |
219 | TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, gh_str02scm, string); | |
220 | ||
221 | /* For the char *, free all strings after converting */ | |
222 | ||
223 | %typemap(freearg) | |
224 | (int *VECTORLENOUTPUT, char ***VECTOROUTPUT), | |
225 | (size_t *VECTORLENOUTPUT, char ***VECTOROUTPUT), | |
226 | (int *LISTLENOUTPUT, char ***LISTOUTPUT), | |
227 | (size_t *LISTLENOUTPUT, char ***LISTOUTPUT), | |
228 | (int *VECTORLENOUTPUT, const char ***VECTOROUTPUT), | |
229 | (size_t *VECTORLENOUTPUT, const char ***VECTOROUTPUT), | |
230 | (int *LISTLENOUTPUT, const char ***LISTOUTPUT), | |
231 | (size_t *LISTLENOUTPUT, const char ***LISTOUTPUT) | |
232 | { | |
233 | if ((*$2)!=NULL) { | |
234 | int i; | |
235 | for (i = 0; i < *$1; i++) { | |
236 | if ((*$2)[i] != NULL) free((*$2)[i]); | |
237 | } | |
238 | free(*$2); | |
239 | } | |
240 | } | |
241 | ||
242 | %typemap(freearg) (int VECTORLENINPUT, char **VECTORINPUT), | |
243 | (size_t VECTORLENINPUT, char **VECTORINPUT), | |
244 | (int LISTLENINPUT, char **LISTINPUT), | |
245 | (size_t LISTLENINPUT, char **LISTINPUT), | |
246 | (int VECTORLENINPUT, const char **VECTORINPUT), | |
247 | (size_t VECTORLENINPUT, const char **VECTORINPUT), | |
248 | (int LISTLENINPUT, const char **LISTINPUT), | |
249 | (size_t LISTLENINPUT, const char **LISTINPUT) | |
250 | { | |
251 | if (($2)!=NULL) { | |
252 | int i; | |
253 | for (i = 0; i< $1; i++) | |
254 | if (($2)[i] != NULL) free(($2)[i]); | |
255 | free($2); | |
256 | } | |
257 | } | |
258 | ||
259 | ||
260 | /* Following is a macro that emits typemaps that are much more | |
261 | flexible. (They are also messier.) It supports multiple parallel | |
262 | lists and vectors (sharing one length argument each). | |
263 | ||
264 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) | |
265 | ||
266 | Supported calling conventions: | |
267 | ||
268 | func(int PARALLEL_VECTORLENINPUT, [const] C_TYPE *PARALLEL_VECTORINPUT, ...) or | |
269 | func([const] C_TYPE *PARALLEL_VECTORINPUT, ..., int PARALLEL_VECTORLENINPUT) | |
270 | ||
271 | func(int PARALLEL_LISTLENINPUT, [const] C_TYPE *PARALLEL_LISTINPUT, ...) or | |
272 | func([const] C_TYPE *PARALLEL_LISTINPUT, ..., int PARALLEL_LISTLENINPUT) | |
273 | ||
274 | func(int *PARALLEL_VECTORLENOUTPUT, C_TYPE **PARALLEL_VECTOROUTPUT, ...) or | |
275 | func(C_TYPE **PARALLEL_VECTOROUTPUT, int *PARALLEL_VECTORLENOUTPUT, ...) | |
276 | ||
277 | func(int *PARALLEL_LISTLENOUTPUT, C_TYPE **PARALLEL_LISTOUTPUT) or | |
278 | func(C_TYPE **PARALLEL_LISTOUTPUT, int *PARALLEL_LISTLENOUTPUT) | |
279 | ||
280 | It is also allowed to use "size_t PARALLEL_LISTLENINPUT" rather than "int | |
281 | PARALLEL_LISTLENINPUT". */ | |
282 | ||
283 | %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) | |
284 | ||
285 | /* input */ | |
286 | ||
287 | /* Passing data is a little complicated here; just remember: | |
288 | IGNORE typemaps come first, then IN, then CHECK. But if | |
289 | IGNORE is given, IN won't be used for this type. | |
290 | ||
291 | We need to "ignore" one of the parameters because there shall | |
292 | be only one argument on the Scheme side. Here we only | |
293 | initialize the array length to 0 but save its address for a | |
294 | later change. */ | |
295 | ||
296 | %typemap(in,numinputs=0) int PARALLEL_VECTORLENINPUT (int *_global_vector_length), | |
297 | size_t PARALLEL_VECTORLENINPUT (size_t *_global_vector_length) | |
298 | { | |
299 | $1 = 0; | |
300 | _global_vector_length = &$1; | |
301 | } | |
302 | ||
303 | %typemap(in,numinputs=0) int PARALLEL_LISTLENINPUT (int *_global_list_length), | |
304 | size_t PARALLEL_LISTLENINPUT (int *_global_list_length) | |
305 | { | |
306 | $1 = 0; | |
307 | _global_list_length = &$1; | |
308 | } | |
309 | ||
310 | /* All the work is done in IN. */ | |
311 | ||
312 | %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values") | |
313 | C_TYPE *PARALLEL_VECTORINPUT, | |
314 | const C_TYPE *PARALLEL_VECTORINPUT | |
315 | { | |
316 | SCM_VALIDATE_VECTOR($argnum, $input); | |
317 | *_global_vector_length = gh_vector_length($input); | |
318 | if (*_global_vector_length > 0) { | |
319 | int i; | |
320 | $1 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) | |
321 | * (*_global_vector_length)); | |
322 | for (i = 0; i<*_global_vector_length; i++) { | |
323 | SCM swig_scm_value = gh_vector_ref($input, gh_int2scm(i)); | |
324 | $1[i] = SCM_TO_C_EXPR; | |
325 | } | |
326 | } | |
327 | else $1 = NULL; | |
328 | } | |
329 | ||
330 | %typemap(in, doc="$NAME is a list of " #SCM_TYPE " values") | |
331 | C_TYPE *PARALLEL_LISTINPUT, | |
332 | const C_TYPE *PARALLEL_LISTINPUT | |
333 | { | |
334 | SCM_VALIDATE_LIST($argnum, $input); | |
335 | *_global_list_length = gh_length($input); | |
336 | if (*_global_list_length > 0) { | |
337 | int i; | |
338 | SCM rest; | |
339 | $1 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) | |
340 | * (*_global_list_length)); | |
341 | for (i = 0, rest = $input; | |
342 | i<*_global_list_length; | |
343 | i++, rest = gh_cdr(rest)) { | |
344 | SCM swig_scm_value = gh_car(rest); | |
345 | $1[i] = SCM_TO_C_EXPR; | |
346 | } | |
347 | } | |
348 | else $1 = NULL; | |
349 | } | |
350 | ||
351 | /* Don't check for NULL pointers (override checks). */ | |
352 | ||
353 | %typemap(check) C_TYPE *PARALLEL_VECTORINPUT, | |
354 | const C_TYPE *PARALLEL_VECTORINPUT, | |
355 | C_TYPE *PARALLEL_LISTINPUT, | |
356 | const C_TYPE *PARALLEL_LISTINPUT | |
357 | "/* no check for NULL pointer */"; | |
358 | ||
359 | /* Discard the temporary array after the call. */ | |
360 | ||
361 | %typemap(freearg) C_TYPE *PARALLEL_VECTORINPUT, | |
362 | const C_TYPE *PARALLEL_VECTORINPUT, | |
363 | C_TYPE *PARALLEL_LISTINPUT, | |
364 | const C_TYPE *PARALLEL_LISTINPUT | |
365 | {if ($1!=NULL) SWIG_free($1);} | |
366 | ||
367 | %enddef | |
368 | ||
369 | %define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) | |
370 | ||
371 | /* output */ | |
372 | ||
373 | /* First we make a temporary variable ARRAYLENTEMP, use its | |
374 | address as the ...LENOUTPUT argument for the C function and | |
375 | "ignore" the ...LENOUTPUT argument for Scheme. */ | |
376 | ||
377 | %typemap(in,numinputs=0) int *PARALLEL_VECTORLENOUTPUT (int _global_arraylentemp), | |
378 | size_t *PARALLEL_VECTORLENOUTPUT (size_t _global_arraylentemp), | |
379 | int *PARALLEL_LISTLENOUTPUT (int _global_arraylentemp), | |
380 | size_t *PARALLEL_LISTLENOUTPUT (size_t _global_arraylentemp) | |
381 | "$1 = &_global_arraylentemp;"; | |
382 | ||
383 | /* We also need to ignore the ...OUTPUT argument. */ | |
384 | ||
385 | %typemap(in,numinputs=0) C_TYPE **PARALLEL_VECTOROUTPUT (C_TYPE *arraytemp), | |
386 | C_TYPE **PARALLEL_LISTOUTPUT (C_TYPE *arraytemp) | |
387 | "$1 = &arraytemp;"; | |
388 | ||
389 | /* In the ARGOUT typemaps, we convert the array into a vector or | |
390 | a list and append it to the results. */ | |
391 | ||
392 | %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)") | |
393 | C_TYPE **PARALLEL_VECTOROUTPUT | |
394 | { | |
395 | int i; | |
396 | SCM res = gh_make_vector(gh_int2scm(_global_arraylentemp), | |
397 | SCM_BOOL_F); | |
398 | for (i = 0; i<_global_arraylentemp; i++) { | |
399 | C_TYPE swig_c_value = (*$1)[i]; | |
400 | SCM elt = C_TO_SCM_EXPR; | |
401 | gh_vector_set_x(res, gh_int2scm(i), elt); | |
402 | } | |
403 | SWIG_APPEND_VALUE(res); | |
404 | } | |
405 | ||
406 | %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)") | |
407 | C_TYPE **PARALLEL_LISTOUTPUT | |
408 | { | |
409 | int i; | |
410 | SCM res = SCM_EOL; | |
411 | if (_global_arraylentemp > 0) { | |
412 | for (i = _global_arraylentemp - 1; i>=0; i--) { | |
413 | C_TYPE swig_c_value = (*$1)[i]; | |
414 | SCM elt = C_TO_SCM_EXPR; | |
415 | res = gh_cons(elt, res); | |
416 | } | |
417 | } | |
418 | SWIG_APPEND_VALUE(res); | |
419 | } | |
420 | ||
421 | /* In the FREEARG typemaps, get rid of the C vector. | |
422 | (This can be overridden if you want to keep the C vector.) */ | |
423 | ||
424 | %typemap(freearg) C_TYPE **PARALLEL_VECTOROUTPUT, | |
425 | C_TYPE **PARALLEL_LISTOUTPUT | |
426 | { | |
427 | if ((*$1)!=NULL) free(*$1); | |
428 | } | |
429 | ||
430 | %enddef | |
431 | ||
432 | %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE) | |
433 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) | |
434 | TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) | |
435 | %enddef | |
436 | ||
437 | %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE) | |
438 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR | |
439 | (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE) | |
440 | %enddef | |
441 | ||
442 | %define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE) | |
443 | TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR | |
444 | (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE) | |
445 | %enddef | |
446 | ||
447 | %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) | |
448 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR | |
449 | (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE) | |
450 | %enddef | |
451 | ||
452 | /* We use the macro to define typemaps for some standard types. */ | |
453 | ||
454 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(bool, gh_scm2bool, gh_bool2scm, boolean); | |
455 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char, gh_scm2char, gh_char2scm, char); | |
456 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned char, gh_scm2char, gh_char2scm, char); | |
457 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(int, gh_scm2int, gh_int2scm, integer); | |
458 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(short, gh_scm2int, gh_int2scm, integer); | |
459 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(long, gh_scm2long, gh_long2scm, integer); | |
460 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, gh_scm2long, gh_long2scm, integer); | |
461 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned int, gh_scm2ulong, gh_ulong2scm, integer); | |
462 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned short, gh_scm2ulong, gh_ulong2scm, integer); | |
463 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned long, gh_scm2ulong, gh_ulong2scm, integer); | |
464 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(size_t, gh_scm2ulong, gh_ulong2scm, integer); | |
465 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(float, gh_scm2double, gh_double2scm, real); | |
466 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(double, gh_scm2double, gh_double2scm, real); | |
467 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, gh_str02scm, string); | |
468 | TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, gh_str02scm, string); | |
469 | ||
470 | %typemap(freearg) char **PARALLEL_LISTINPUT, char **PARALLEL_VECTORINPUT, | |
471 | const char **PARALLEL_LISTINPUT, const char **PARALLEL_VECTORINPUT | |
472 | { | |
473 | if (($1)!=NULL) { | |
474 | int i; | |
475 | for (i = 0; i<*_global_list_length; i++) | |
476 | if (($1)[i] != NULL) SWIG_free(($1)[i]); | |
477 | SWIG_free($1); | |
478 | } | |
479 | } | |
480 | ||
481 | %typemap(freearg) char ***PARALLEL_LISTOUTPUT, char ***PARALLEL_VECTOROUTPUT, | |
482 | const char ***PARALLEL_LISTOUTPUT, const char ***PARALLEL_VECTOROUTPUT | |
483 | { | |
484 | if ((*$1)!=NULL) { | |
485 | int i; | |
486 | for (i = 0; i<_global_arraylentemp; i++) | |
487 | if ((*$1)[i] != NULL) free((*$1)[i]); | |
488 | free(*$1); | |
489 | } | |
490 | } |