Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | // |
2 | // typemaps for Ruby | |
3 | // | |
4 | // $Header: /cvsroot/swig/SWIG/Lib/ruby/typemaps.i,v 1.7 2005/02/22 23:16:30 marcelomatus Exp $ | |
5 | // | |
6 | // Copyright (C) 2000 Network Applied Communication Laboratory, Inc. | |
7 | // Copyright (C) 2000 Information-technology Promotion Agency, Japan | |
8 | // | |
9 | // Masaki Fukushima | |
10 | // | |
11 | ||
12 | /* | |
13 | The SWIG typemap library provides a language independent mechanism for | |
14 | supporting output arguments, input values, and other C function | |
15 | calling mechanisms. The primary use of the library is to provide a | |
16 | better interface to certain C function--especially those involving | |
17 | pointers. | |
18 | */ | |
19 | ||
20 | // ------------------------------------------------------------------------ | |
21 | // Pointer handling | |
22 | // | |
23 | // These mappings provide support for input/output arguments and common | |
24 | // uses for C/C++ pointers. | |
25 | // ------------------------------------------------------------------------ | |
26 | ||
27 | // INPUT typemaps. | |
28 | // These remap a C pointer to be an "INPUT" value which is passed by value | |
29 | // instead of reference. | |
30 | ||
31 | /* | |
32 | The following methods can be applied to turn a pointer into a simple | |
33 | "input" value. That is, instead of passing a pointer to an object, | |
34 | you would use a real value instead. | |
35 | ||
36 | int *INPUT | |
37 | short *INPUT | |
38 | long *INPUT | |
39 | long long *INPUT | |
40 | unsigned int *INPUT | |
41 | unsigned short *INPUT | |
42 | unsigned long *INPUT | |
43 | unsigned long long *INPUT | |
44 | unsigned char *INPUT | |
45 | bool *INPUT | |
46 | float *INPUT | |
47 | double *INPUT | |
48 | ||
49 | To use these, suppose you had a C function like this : | |
50 | ||
51 | double fadd(double *a, double *b) { | |
52 | return *a+*b; | |
53 | } | |
54 | ||
55 | You could wrap it with SWIG as follows : | |
56 | ||
57 | %include typemaps.i | |
58 | double fadd(double *INPUT, double *INPUT); | |
59 | ||
60 | or you can use the %apply directive : | |
61 | ||
62 | %include typemaps.i | |
63 | %apply double *INPUT { double *a, double *b }; | |
64 | double fadd(double *a, double *b); | |
65 | ||
66 | */ | |
67 | ||
68 | %define INPUT_TYPEMAP(type, converter) | |
69 | %typemap(in) type *INPUT($*1_ltype temp), type &INPUT($*1_ltype temp) | |
70 | { | |
71 | temp = ($*1_ltype) converter($input); | |
72 | $1 = &temp; | |
73 | } | |
74 | %typemap(typecheck) type *INPUT = type; | |
75 | %typemap(typecheck) type &INPUT = type; | |
76 | %enddef | |
77 | ||
78 | INPUT_TYPEMAP(float, NUM2DBL); | |
79 | INPUT_TYPEMAP(double, NUM2DBL); | |
80 | INPUT_TYPEMAP(int, NUM2INT); | |
81 | INPUT_TYPEMAP(short, NUM2SHRT); | |
82 | INPUT_TYPEMAP(long, NUM2LONG); | |
83 | INPUT_TYPEMAP(long long, NUM2LL); | |
84 | INPUT_TYPEMAP(unsigned int, NUM2UINT); | |
85 | INPUT_TYPEMAP(unsigned short, NUM2USHRT); | |
86 | INPUT_TYPEMAP(unsigned long, NUM2ULONG); | |
87 | INPUT_TYPEMAP(unsigned long long, NUM2ULL); | |
88 | INPUT_TYPEMAP(unsigned char, NUM2UINT); | |
89 | INPUT_TYPEMAP(signed char, NUM2INT); | |
90 | INPUT_TYPEMAP(bool, RTEST); | |
91 | ||
92 | #undef INPUT_TYPEMAP | |
93 | ||
94 | // OUTPUT typemaps. These typemaps are used for parameters that | |
95 | // are output only. The output value is appended to the result as | |
96 | // a array element. | |
97 | ||
98 | /* | |
99 | The following methods can be applied to turn a pointer into an "output" | |
100 | value. When calling a function, no input value would be given for | |
101 | a parameter, but an output value would be returned. In the case of | |
102 | multiple output values, they are returned in the form of a Ruby Array. | |
103 | ||
104 | int *OUTPUT | |
105 | short *OUTPUT | |
106 | long *OUTPUT | |
107 | long long *OUTPUT | |
108 | unsigned int *OUTPUT | |
109 | unsigned short *OUTPUT | |
110 | unsigned long *OUTPUT | |
111 | unsigned long long *OUTPUT | |
112 | unsigned char *OUTPUT | |
113 | bool *OUTPUT | |
114 | float *OUTPUT | |
115 | double *OUTPUT | |
116 | ||
117 | For example, suppose you were trying to wrap the modf() function in the | |
118 | C math library which splits x into integral and fractional parts (and | |
119 | returns the integer part in one of its parameters).K: | |
120 | ||
121 | double modf(double x, double *ip); | |
122 | ||
123 | You could wrap it with SWIG as follows : | |
124 | ||
125 | %include typemaps.i | |
126 | double modf(double x, double *OUTPUT); | |
127 | ||
128 | or you can use the %apply directive : | |
129 | ||
130 | %include typemaps.i | |
131 | %apply double *OUTPUT { double *ip }; | |
132 | double modf(double x, double *ip); | |
133 | ||
134 | The Ruby output of the function would be a Array containing both | |
135 | output values. | |
136 | */ | |
137 | ||
138 | %include "fragments.i" | |
139 | ||
140 | %define OUTPUT_TYPEMAP(type, converter, convtype) | |
141 | %typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;"; | |
142 | %typemap(argout, fragment="output_helper") type *OUTPUT, type &OUTPUT { | |
143 | VALUE o = converter(convtype (*$1)); | |
144 | $result = output_helper($result, o); | |
145 | } | |
146 | %enddef | |
147 | ||
148 | OUTPUT_TYPEMAP(int, INT2NUM, (int)); | |
149 | OUTPUT_TYPEMAP(short, INT2NUM, (int)); | |
150 | OUTPUT_TYPEMAP(long, INT2NUM, (long)); | |
151 | OUTPUT_TYPEMAP(long long, LL2NUM, (long long)); | |
152 | OUTPUT_TYPEMAP(unsigned int, UINT2NUM, (unsigned int)); | |
153 | OUTPUT_TYPEMAP(unsigned short, UINT2NUM, (unsigned int)); | |
154 | OUTPUT_TYPEMAP(unsigned long, UINT2NUM, (unsigned long)); | |
155 | OUTPUT_TYPEMAP(unsigned long long, ULL2NUM, (unsigned long long)); | |
156 | OUTPUT_TYPEMAP(unsigned char, UINT2NUM, (unsigned int)); | |
157 | OUTPUT_TYPEMAP(signed char, INT2NUM, (int)); | |
158 | OUTPUT_TYPEMAP(float, rb_float_new, (double)); | |
159 | OUTPUT_TYPEMAP(double, rb_float_new, (double)); | |
160 | ||
161 | #undef OUTPUT_TYPEMAP | |
162 | ||
163 | %typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;"; | |
164 | %typemap(argout, fragment="output_helper") bool *OUTPUT, bool &OUTPUT { | |
165 | VALUE o = (*$1) ? Qtrue : Qfalse; | |
166 | $result = output_helper($result, o); | |
167 | } | |
168 | ||
169 | // INOUT | |
170 | // Mappings for an argument that is both an input and output | |
171 | // parameter | |
172 | ||
173 | /* | |
174 | The following methods can be applied to make a function parameter both | |
175 | an input and output value. This combines the behavior of both the | |
176 | "INPUT" and "OUTPUT" methods described earlier. Output values are | |
177 | returned in the form of a Ruby array. | |
178 | ||
179 | int *INOUT | |
180 | short *INOUT | |
181 | long *INOUT | |
182 | long long *INOUT | |
183 | unsigned int *INOUT | |
184 | unsigned short *INOUT | |
185 | unsigned long *INOUT | |
186 | unsigned long long *INOUT | |
187 | unsigned char *INOUT | |
188 | bool *INOUT | |
189 | float *INOUT | |
190 | double *INOUT | |
191 | ||
192 | For example, suppose you were trying to wrap the following function : | |
193 | ||
194 | void neg(double *x) { | |
195 | *x = -(*x); | |
196 | } | |
197 | ||
198 | You could wrap it with SWIG as follows : | |
199 | ||
200 | %include typemaps.i | |
201 | void neg(double *INOUT); | |
202 | ||
203 | or you can use the %apply directive : | |
204 | ||
205 | %include typemaps.i | |
206 | %apply double *INOUT { double *x }; | |
207 | void neg(double *x); | |
208 | ||
209 | Unlike C, this mapping does not directly modify the input value (since | |
210 | this makes no sense in Ruby). Rather, the modified input value shows | |
211 | up as the return value of the function. Thus, to apply this function | |
212 | to a Ruby variable you might do this : | |
213 | ||
214 | x = neg(x) | |
215 | ||
216 | Note : previous versions of SWIG used the symbol 'BOTH' to mark | |
217 | input/output arguments. This is still supported, but will be slowly | |
218 | phased out in future releases. | |
219 | ||
220 | */ | |
221 | ||
222 | %typemap(in) int *INOUT = int *INPUT; | |
223 | %typemap(in) short *INOUT = short *INPUT; | |
224 | %typemap(in) long *INOUT = long *INPUT; | |
225 | %typemap(in) long long *INOUT = long long *INPUT; | |
226 | %typemap(in) unsigned *INOUT = unsigned *INPUT; | |
227 | %typemap(in) unsigned short *INOUT = unsigned short *INPUT; | |
228 | %typemap(in) unsigned long *INOUT = unsigned long *INPUT; | |
229 | %typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; | |
230 | %typemap(in) unsigned char *INOUT = unsigned char *INPUT; | |
231 | %typemap(in) signed char *INOUT = signed char *INPUT; | |
232 | %typemap(in) bool *INOUT = bool *INPUT; | |
233 | %typemap(in) float *INOUT = float *INPUT; | |
234 | %typemap(in) double *INOUT = double *INPUT; | |
235 | ||
236 | %typemap(in) int &INOUT = int &INPUT; | |
237 | %typemap(in) short &INOUT = short &INPUT; | |
238 | %typemap(in) long &INOUT = long &INPUT; | |
239 | %typemap(in) long long &INOUT = long long &INPUT; | |
240 | %typemap(in) unsigned &INOUT = unsigned &INPUT; | |
241 | %typemap(in) unsigned short &INOUT = unsigned short &INPUT; | |
242 | %typemap(in) unsigned long &INOUT = unsigned long &INPUT; | |
243 | %typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; | |
244 | %typemap(in) unsigned char &INOUT = unsigned char &INPUT; | |
245 | %typemap(in) signed char &INOUT = signed char &INPUT; | |
246 | %typemap(in) bool &INOUT = bool &INPUT; | |
247 | %typemap(in) float &INOUT = float &INPUT; | |
248 | %typemap(in) double &INOUT = double &INPUT; | |
249 | ||
250 | %typemap(argout) int *INOUT = int *OUTPUT; | |
251 | %typemap(argout) short *INOUT = short *OUTPUT; | |
252 | %typemap(argout) long *INOUT = long *OUTPUT; | |
253 | %typemap(argout) long long *INOUT = long long *OUTPUT; | |
254 | %typemap(argout) unsigned *INOUT = unsigned *OUTPUT; | |
255 | %typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; | |
256 | %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; | |
257 | %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; | |
258 | %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; | |
259 | %typemap(argout) signed char *INOUT = signed char *OUTPUT; | |
260 | %typemap(argout) bool *INOUT = bool *OUTPUT; | |
261 | %typemap(argout) float *INOUT = float *OUTPUT; | |
262 | %typemap(argout) double *INOUT = double *OUTPUT; | |
263 | ||
264 | %typemap(argout) int &INOUT = int &OUTPUT; | |
265 | %typemap(argout) short &INOUT = short &OUTPUT; | |
266 | %typemap(argout) long &INOUT = long &OUTPUT; | |
267 | %typemap(argout) long long &INOUT = long long &OUTPUT; | |
268 | %typemap(argout) unsigned &INOUT = unsigned &OUTPUT; | |
269 | %typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; | |
270 | %typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; | |
271 | %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; | |
272 | %typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; | |
273 | %typemap(argout) signed char &INOUT = signed char &OUTPUT; | |
274 | %typemap(argout) bool &INOUT = bool &OUTPUT; | |
275 | %typemap(argout) float &INOUT = float &OUTPUT; | |
276 | %typemap(argout) double &INOUT = double &OUTPUT; | |
277 | ||
278 | // -------------------------------------------------------------------- | |
279 | // Special types | |
280 | // -------------------------------------------------------------------- | |
281 | ||
282 | /* | |
283 | The typemaps.i library also provides the following mappings : | |
284 | ||
285 | struct timeval * | |
286 | time_t | |
287 | ||
288 | Ruby has builtin class Time. INPUT/OUTPUT typemap for timeval and | |
289 | time_t is provided. | |
290 | ||
291 | int PROG_ARGC | |
292 | char **PROG_ARGV | |
293 | ||
294 | Some C function receive argc and argv from C main function. | |
295 | This typemap provides ignore typemap which pass Ruby ARGV contents | |
296 | as argc and argv to C function. | |
297 | */ | |
298 | ||
299 | ||
300 | // struct timeval * | |
301 | %{ | |
302 | #ifdef __cplusplus | |
303 | extern "C" { | |
304 | #endif | |
305 | #ifdef HAVE_SYS_TIME_H | |
306 | # include <sys/time.h> | |
307 | struct timeval rb_time_timeval(VALUE); | |
308 | #endif | |
309 | #ifdef __cplusplus | |
310 | } | |
311 | #endif | |
312 | %} | |
313 | ||
314 | %typemap(in) struct timeval *INPUT (struct timeval temp) | |
315 | { | |
316 | if (NIL_P($input)) | |
317 | $1 = NULL; | |
318 | else { | |
319 | temp = rb_time_timeval($input); | |
320 | $1 = &temp; | |
321 | } | |
322 | } | |
323 | ||
324 | %typemap(in,numinputs=0) struct timeval *OUTPUT(struct timeval temp) | |
325 | { | |
326 | $1 = &temp; | |
327 | } | |
328 | ||
329 | %typemap(argout) struct timeval *OUTPUT | |
330 | { | |
331 | $result = rb_time_new($1->tv_sec, $1->tv_usec); | |
332 | } | |
333 | ||
334 | %typemap(out) struct timeval * | |
335 | { | |
336 | $result = rb_time_new($1->tv_sec, $1->tv_usec); | |
337 | } | |
338 | ||
339 | %typemap(out) struct timespec * | |
340 | { | |
341 | $result = rb_time_new($1->tv_sec, $1->tv_nsec / 1000); | |
342 | } | |
343 | ||
344 | // time_t | |
345 | %typemap(in) time_t | |
346 | { | |
347 | if (NIL_P($input)) | |
348 | $1 = (time_t)-1; | |
349 | else | |
350 | $1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0)); | |
351 | } | |
352 | ||
353 | %typemap(out) time_t | |
354 | { | |
355 | $result = rb_time_new($1, 0); | |
356 | } | |
357 | ||
358 | // argc and argv | |
359 | %typemap(in,numinputs=0) int PROG_ARGC { | |
360 | $1 = RARRAY(rb_argv)->len + 1; | |
361 | } | |
362 | ||
363 | %typemap(in,numinputs=0) char **PROG_ARGV { | |
364 | int i, n; | |
365 | VALUE ary = rb_eval_string("[$0] + ARGV"); | |
366 | n = RARRAY(ary)->len; | |
367 | $1 = (char **)malloc(n + 1); | |
368 | for (i = 0; i < n; i++) { | |
369 | VALUE v = rb_obj_as_string(RARRAY(ary)->ptr[i]); | |
370 | $1[i] = (char *)malloc(RSTRING(v)->len + 1); | |
371 | strcpy($1[i], RSTRING(v)->ptr); | |
372 | } | |
373 | } | |
374 | ||
375 | %typemap(freearg) char **PROG_ARGV { | |
376 | int i, n = RARRAY(rb_argv)->len + 1; | |
377 | for (i = 0; i < n; i++) free($1[i]); | |
378 | free($1); | |
379 | } | |
380 | ||
381 | // FILE * | |
382 | %{ | |
383 | #ifdef __cplusplus | |
384 | extern "C" { | |
385 | #endif | |
386 | #include "rubyio.h" | |
387 | #ifdef __cplusplus | |
388 | } | |
389 | #endif | |
390 | %} | |
391 | ||
392 | %typemap(in) FILE *READ { | |
393 | OpenFile *of; | |
394 | GetOpenFile($input, of); | |
395 | rb_io_check_readable(of); | |
396 | $1 = GetReadFile(of); | |
397 | rb_read_check($1); | |
398 | } | |
399 | ||
400 | %typemap(in) FILE *READ_NOCHECK { | |
401 | OpenFile *of; | |
402 | GetOpenFile($input, of); | |
403 | rb_io_check_readable(of); | |
404 | $1 = GetReadFile(of); | |
405 | } | |
406 | ||
407 | %typemap(in) FILE *WRITE { | |
408 | OpenFile *of; | |
409 | GetOpenFile($input, of); | |
410 | rb_io_check_writable(of); | |
411 | $1 = GetWriteFile(of); | |
412 | } | |
413 | ||
414 | /* Overloading information */ | |
415 | ||
416 | %typemap(typecheck) double *INOUT = double; | |
417 | %typemap(typecheck) signed char *INOUT = signed char; | |
418 | %typemap(typecheck) unsigned char *INOUT = unsigned char; | |
419 | %typemap(typecheck) unsigned long *INOUT = unsigned long; | |
420 | %typemap(typecheck) unsigned long long *INOUT = unsigned long long; | |
421 | %typemap(typecheck) unsigned short *INOUT = unsigned short; | |
422 | %typemap(typecheck) unsigned int *INOUT = unsigned int; | |
423 | %typemap(typecheck) long *INOUT = long; | |
424 | %typemap(typecheck) long long *INOUT = long long; | |
425 | %typemap(typecheck) short *INOUT = short; | |
426 | %typemap(typecheck) int *INOUT = int; | |
427 | %typemap(typecheck) float *INOUT = float; | |
428 | ||
429 | %typemap(typecheck) double &INOUT = double; | |
430 | %typemap(typecheck) signed char &INOUT = signed char; | |
431 | %typemap(typecheck) unsigned char &INOUT = unsigned char; | |
432 | %typemap(typecheck) unsigned long &INOUT = unsigned long; | |
433 | %typemap(typecheck) unsigned long long &INOUT = unsigned long long; | |
434 | %typemap(typecheck) unsigned short &INOUT = unsigned short; | |
435 | %typemap(typecheck) unsigned int &INOUT = unsigned int; | |
436 | %typemap(typecheck) long &INOUT = long; | |
437 | %typemap(typecheck) long long &INOUT = long long; | |
438 | %typemap(typecheck) short &INOUT = short; | |
439 | %typemap(typecheck) int &INOUT = int; | |
440 | %typemap(typecheck) float &INOUT = float; | |
441 |