4
// $Header: /cvs/projects/SWIG/Lib/ruby/typemaps.i,v 1.1.4.2 2001/12/10 17:18:08 beazley Exp $
6
// Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
7
// Copyright (C) 2000 Information-technology Promotion Agency, Japan
13
%section "Typemap Library (Ruby)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0
17
The SWIG typemap library provides a language independent mechanism for
18
supporting output arguments, input values, and other C function
19
calling mechanisms. The primary use of the library is to provide a
20
better interface to certain C function--especially those involving
26
// ------------------------------------------------------------------------
29
// These mappings provide support for input/output arguments and common
30
// uses for C/C++ pointers.
31
// ------------------------------------------------------------------------
34
// These remap a C pointer to be an "INPUT" value which is passed by value
35
// instead of reference.
39
%subsection "Input Methods"
42
The following methods can be applied to turn a pointer into a simple
43
"input" value. That is, instead of passing a pointer to an object,
44
you would use a real value instead.
56
To use these, suppose you had a C function like this :
58
double fadd(double *a, double *b) {
62
You could wrap it with SWIG as follows :
65
double fadd(double *INPUT, double *INPUT);
67
or you can use the %apply directive :
70
%apply double *INPUT { double *a, double *b };
71
double fadd(double *a, double *b);
76
%typemap(ruby,in) double *INPUT(double temp)
78
temp = NUM2DBL($input);
82
%typemap(ruby,in) float *INPUT(float temp)
84
temp = (float) NUM2DBL($input);
88
%typemap(ruby,in) int *INPUT(int temp)
90
temp = NUM2INT($input);
94
%typemap(ruby,in) short *INPUT(short temp)
96
temp = NUM2SHRT($input);
100
%typemap(ruby,in) long *INPUT(long temp)
102
temp = NUM2LONG($input);
105
%typemap(ruby,in) unsigned int *INPUT(unsigned int temp)
107
temp = NUM2UINT($input);
110
%typemap(ruby,in) unsigned short *INPUT(unsigned short temp)
112
temp = NUM2USHRT($input);
115
%typemap(ruby,in) unsigned long *INPUT(unsigned long temp)
117
temp = NUM2ULONG($input);
120
%typemap(ruby,in) unsigned char *INPUT(unsigned char temp)
122
temp = (unsigned char)NUM2UINT($input);
126
%typemap(ruby,in) signed char *INPUT(signed char temp)
128
temp = (signed char)NUM2INT($input);
132
// OUTPUT typemaps. These typemaps are used for parameters that
133
// are output only. The output value is appended to the result as
137
%subsection "Output Methods"
140
The following methods can be applied to turn a pointer into an "output"
141
value. When calling a function, no input value would be given for
142
a parameter, but an output value would be returned. In the case of
143
multiple output values, they are returned in the form of a Ruby Array.
149
unsigned short *OUTPUT
150
unsigned long *OUTPUT
151
unsigned char *OUTPUT
155
For example, suppose you were trying to wrap the modf() function in the
156
C math library which splits x into integral and fractional parts (and
157
returns the integer part in one of its parameters).K:
159
double modf(double x, double *ip);
161
You could wrap it with SWIG as follows :
164
double modf(double x, double *OUTPUT);
166
or you can use the %apply directive :
169
%apply double *OUTPUT { double *ip };
170
double modf(double x, double *ip);
172
The Ruby output of the function would be a Array containing both
177
// Helper function for Array output
180
static VALUE output_helper(VALUE target, VALUE o) {
184
if (TYPE(target) != T_ARRAY) {
186
target = rb_ary_new();
187
rb_ary_push(target, o2);
189
rb_ary_push(target, o);
195
// Force the argument to be ignored.
197
%typemap(ruby,ignore) int *OUTPUT(int temp),
198
short *OUTPUT(short temp),
199
long *OUTPUT(long temp),
200
unsigned int *OUTPUT(unsigned int temp),
201
unsigned short *OUTPUT(unsigned short temp),
202
unsigned long *OUTPUT(unsigned long temp),
203
unsigned char *OUTPUT(unsigned char temp),
204
signed char *OUTPUT(signed char temp),
205
float *OUTPUT(float temp),
206
double *OUTPUT(double temp)
211
%typemap(ruby,argout) int *OUTPUT,
216
$result = output_helper($result, INT2NUM(*$1));
219
%typemap(ruby,argout) unsigned int *OUTPUT,
220
unsigned short *OUTPUT,
221
unsigned long *OUTPUT,
222
unsigned char *OUTPUT
224
$result = output_helper($result, UINT2NUM(*$1));
227
%typemap(ruby,argout) float *OUTPUT,
230
$result = output_helper($result, rb_float_new(*$1));
234
// Mappings for an argument that is both an input and output
239
%subsection "Input/Output Methods"
242
The following methods can be applied to make a function parameter both
243
an input and output value. This combines the behavior of both the
244
"INPUT" and "OUTPUT" methods described earlier. Output values are
245
returned in the form of a Ruby array.
251
unsigned short *INOUT
257
For example, suppose you were trying to wrap the following function :
259
void neg(double *x) {
263
You could wrap it with SWIG as follows :
266
void neg(double *INOUT);
268
or you can use the %apply directive :
271
%apply double *INOUT { double *x };
274
Unlike C, this mapping does not directly modify the input value (since
275
this makes no sense in Ruby). Rather, the modified input value shows
276
up as the return value of the function. Thus, to apply this function
277
to a Ruby variable you might do this :
281
Note : previous versions of SWIG used the symbol 'BOTH' to mark
282
input/output arguments. This is still supported, but will be slowly
283
phased out in future releases.
288
%typemap(ruby,in) int *INOUT = int *INPUT;
289
%typemap(ruby,in) short *INOUT = short *INPUT;
290
%typemap(ruby,in) long *INOUT = long *INPUT;
291
%typemap(ruby,in) unsigned *INOUT = unsigned *INPUT;
292
%typemap(ruby,in) unsigned short *INOUT = unsigned short *INPUT;
293
%typemap(ruby,in) unsigned long *INOUT = unsigned long *INPUT;
294
%typemap(ruby,in) unsigned char *INOUT = unsigned char *INPUT;
295
%typemap(ruby,in) float *INOUT = float *INPUT;
296
%typemap(ruby,in) double *INOUT = double *INPUT;
298
%typemap(ruby,argout) int *INOUT = int *OUTPUT;
299
%typemap(ruby,argout) short *INOUT = short *OUTPUT;
300
%typemap(ruby,argout) long *INOUT = long *OUTPUT;
301
%typemap(ruby,argout) unsigned *INOUT = unsigned *OUTPUT;
302
%typemap(ruby,argout) unsigned short *INOUT = unsigned short *OUTPUT;
303
%typemap(ruby,argout) unsigned long *INOUT = unsigned long *OUTPUT;
304
%typemap(ruby,argout) unsigned char *INOUT = unsigned char *OUTPUT;
305
%typemap(ruby,argout) float *INOUT = float *OUTPUT;
306
%typemap(ruby,argout) double *INOUT = double *OUTPUT;
308
// Backwards compatibility
310
%apply int *INOUT { int *BOTH };
311
%apply short *INOUT { short *BOTH };
312
%apply long *INOUT { long *BOTH };
313
%apply unsigned int *INOUT { unsigned int *BOTH };
314
%apply unsigned long *INOUT { unsigned long *BOTH };
315
%apply unsigned short *INOUT { unsigned short *BOTH };
316
%apply unsigned char *INOUT { unsigned char *BOTH };
317
%apply float *INOUT { float *BOTH };
318
%apply double *INOUT { double *BOTH };
320
// --------------------------------------------------------------------
321
// OUTPUT typemaps for user defined type.
323
// --------------------------------------------------------------------
326
%subsection "Output Methods for User-defined types"
329
The following method can be applied to turn a pointer to
330
user-defined type returned through function aruguments into
335
You can use the %apply directive :
338
%apply User **OUTPUT { Foo **OUTPUT };
339
int foo_func(Foo **OUTPUT);
344
%typemap(ruby,ignore) User **OUTPUT(void *temp)
348
%typemap(ruby,argout) User **OUTPUT
350
$result = output_helper($result, Wrap_$basetype(*$1));
354
// --------------------------------------------------------------------
357
// --------------------------------------------------------------------
360
%subsection "Special Methods"
363
The typemaps.i library also provides the following mappings :
368
Ruby has builtin class Time. INPUT/OUPUT typemap for timeval and
374
Some C function receive argc and argv from C main function.
375
This typemap provides ignore typemap which pass Ruby ARGV contents
376
as argc and argv to C function.
387
#ifdef HAVE_SYS_TIME_H
388
# include <sys/time.h>
389
struct timeval rb_time_timeval(VALUE);
396
%typemap(ruby,in) struct timeval *INPUT (struct timeval temp)
401
temp = rb_time_timeval($input);
406
%typemap(ruby,ignore) struct timeval *OUTPUT(struct timeval temp)
411
%typemap(ruby,argout) struct timeval *OUTPUT
413
$result = rb_time_new($1->tv_sec, $1->tv_usec);
416
%typemap(ruby,out) struct timeval *
418
$result = rb_time_new($1->tv_sec, $1->tv_usec);
421
%typemap(ruby,out) struct timespec *
423
$result = rb_time_new($1->tv_sec, $1->tv_nsec / 1000);
427
%typemap(ruby,in) time_t
432
$1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0));
435
%typemap(ruby,out) time_t
437
$result = rb_time_new($1, 0);
441
%typemap(ruby,ignore) int PROG_ARGC {
442
$1 = RARRAY(rb_argv)->len + 1;
445
%typemap(ruby,ignore) char **PROG_ARGV {
447
VALUE ary = rb_eval_string("[$0] + ARGV");
448
n = RARRAY(ary)->len;
449
$1 = (char **)malloc(n + 1);
450
for (i = 0; i < n; i++) {
451
VALUE v = rb_obj_as_string(RARRAY(ary)->ptr[i]);
452
$1[i] = (char *)malloc(RSTRING(v)->len + 1);
453
strcpy($1[i], RSTRING(v)->ptr);
457
%typemap(ruby,freearg) char **PROG_ARGV {
458
int i, n = RARRAY(rb_argv)->len + 1;
459
for (i = 0; i < n; i++) free($1[i]);
473
%typemap(ruby,in) FILE *READ {
475
GetOpenFile($input, of);
476
rb_io_check_readable(of);
477
$1 = GetReadFile(of);
480
%typemap(ruby,in) FILE *READ_NOCHECK {
482
GetOpenFile($input, of);
483
rb_io_check_readable(of);
484
$1 = GetReadFile(of);
486
%typemap(ruby,in) FILE *WRITE {
488
GetOpenFile($input, of);
489
rb_io_check_writable(of);
490
$1 = GetWriteFile(of);