~ubuntu-branches/ubuntu/maverick/swig1.3/maverick

« back to all changes in this revision

Viewing changes to Lib/ruby/typemaps.i

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Landschoff
  • Date: 2002-03-29 01:56:07 UTC
  • Revision ID: james.westby@ubuntu.com-20020329015607-c0wt03xu8oy9ioj7
Tags: upstream-1.3.11
ImportĀ upstreamĀ versionĀ 1.3.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// typemaps for Ruby
 
3
//
 
4
// $Header: /cvs/projects/SWIG/Lib/ruby/typemaps.i,v 1.1.4.2 2001/12/10 17:18:08 beazley 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
#ifdef AUTODOC
 
13
%section "Typemap Library (Ruby)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0
 
14
%text %{
 
15
%include typemaps.i
 
16
 
 
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
 
21
pointers.
 
22
%}
 
23
 
 
24
#endif
 
25
 
 
26
// ------------------------------------------------------------------------
 
27
// Pointer handling
 
28
//
 
29
// These mappings provide support for input/output arguments and common
 
30
// uses for C/C++ pointers.
 
31
// ------------------------------------------------------------------------
 
32
 
 
33
// INPUT typemaps.
 
34
// These remap a C pointer to be an "INPUT" value which is passed by value
 
35
// instead of reference.
 
36
 
 
37
 
 
38
#ifdef AUTODOC
 
39
%subsection "Input Methods"
 
40
 
 
41
%text %{
 
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.
 
45
 
 
46
         int            *INPUT
 
47
         short          *INPUT
 
48
         long           *INPUT
 
49
         unsigned int   *INPUT
 
50
         unsigned short *INPUT
 
51
         unsigned long  *INPUT
 
52
         unsigned char  *INPUT
 
53
         float          *INPUT
 
54
         double         *INPUT
 
55
         
 
56
To use these, suppose you had a C function like this :
 
57
 
 
58
        double fadd(double *a, double *b) {
 
59
               return *a+*b;
 
60
        }
 
61
 
 
62
You could wrap it with SWIG as follows :
 
63
        
 
64
        %include typemaps.i
 
65
        double fadd(double *INPUT, double *INPUT);
 
66
 
 
67
or you can use the %apply directive :
 
68
 
 
69
        %include typemaps.i
 
70
        %apply double *INPUT { double *a, double *b };
 
71
        double fadd(double *a, double *b);
 
72
 
 
73
%}
 
74
#endif
 
75
 
 
76
%typemap(ruby,in) double *INPUT(double temp)
 
77
{
 
78
  temp = NUM2DBL($input);
 
79
  $1 = &temp;
 
80
}
 
81
 
 
82
%typemap(ruby,in) float  *INPUT(float temp)
 
83
{
 
84
  temp = (float) NUM2DBL($input);
 
85
  $1 = &temp;
 
86
}
 
87
 
 
88
%typemap(ruby,in) int            *INPUT(int temp)
 
89
{
 
90
  temp = NUM2INT($input);
 
91
  $1 = &temp;
 
92
}
 
93
 
 
94
%typemap(ruby,in) short          *INPUT(short temp)
 
95
{
 
96
  temp = NUM2SHRT($input);
 
97
  $1 = &temp;
 
98
}
 
99
 
 
100
%typemap(ruby,in) long           *INPUT(long temp)
 
101
{
 
102
  temp = NUM2LONG($input);
 
103
  $1 = &temp;
 
104
}
 
105
%typemap(ruby,in) unsigned int   *INPUT(unsigned int temp)
 
106
{
 
107
  temp = NUM2UINT($input);
 
108
  $1 = &temp;
 
109
}
 
110
%typemap(ruby,in) unsigned short *INPUT(unsigned short temp)
 
111
{
 
112
  temp = NUM2USHRT($input);
 
113
  $1 = &temp;
 
114
}
 
115
%typemap(ruby,in) unsigned long  *INPUT(unsigned long temp)
 
116
{
 
117
  temp = NUM2ULONG($input);
 
118
  $1 = &temp;
 
119
}
 
120
%typemap(ruby,in) unsigned char  *INPUT(unsigned char temp)
 
121
{
 
122
  temp = (unsigned char)NUM2UINT($input);
 
123
  $1 = &temp;
 
124
}
 
125
 
 
126
%typemap(ruby,in) signed char  *INPUT(signed char temp)
 
127
{
 
128
  temp = (signed char)NUM2INT($input);
 
129
  $1 = &temp;
 
130
}
 
131
                 
 
132
// OUTPUT typemaps.   These typemaps are used for parameters that
 
133
// are output only.   The output value is appended to the result as
 
134
// a array element.
 
135
 
 
136
#ifdef AUTODOC
 
137
%subsection "Output Methods"
 
138
 
 
139
%text %{
 
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.
 
144
 
 
145
         int            *OUTPUT
 
146
         short          *OUTPUT
 
147
         long           *OUTPUT
 
148
         unsigned int   *OUTPUT
 
149
         unsigned short *OUTPUT
 
150
         unsigned long  *OUTPUT
 
151
         unsigned char  *OUTPUT
 
152
         float          *OUTPUT
 
153
         double         *OUTPUT
 
154
         
 
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:
 
158
 
 
159
        double modf(double x, double *ip);
 
160
 
 
161
You could wrap it with SWIG as follows :
 
162
 
 
163
        %include typemaps.i
 
164
        double modf(double x, double *OUTPUT);
 
165
 
 
166
or you can use the %apply directive :
 
167
 
 
168
        %include typemaps.i
 
169
        %apply double *OUTPUT { double *ip };
 
170
        double modf(double x, double *ip);
 
171
 
 
172
The Ruby output of the function would be a Array containing both
 
173
output values. 
 
174
%}
 
175
#endif
 
176
 
 
177
// Helper function for Array output
 
178
 
 
179
%{
 
180
static VALUE output_helper(VALUE target, VALUE o) {
 
181
    if (NIL_P(target)) {
 
182
        target = o;
 
183
    } else {
 
184
        if (TYPE(target) != T_ARRAY) {
 
185
            VALUE o2 = target;
 
186
            target = rb_ary_new();
 
187
            rb_ary_push(target, o2);
 
188
        }
 
189
        rb_ary_push(target, o);
 
190
    }
 
191
    return target;
 
192
}
 
193
%}
 
194
 
 
195
// Force the argument to be ignored.
 
196
 
 
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)
 
207
{
 
208
    $1 = &temp;
 
209
}
 
210
 
 
211
%typemap(ruby,argout) int            *OUTPUT,
 
212
                      short          *OUTPUT,
 
213
                      long           *OUTPUT,
 
214
                      signed char    *OUTPUT
 
215
{
 
216
    $result = output_helper($result, INT2NUM(*$1));
 
217
}
 
218
 
 
219
%typemap(ruby,argout) unsigned int   *OUTPUT,
 
220
                      unsigned short *OUTPUT,
 
221
                      unsigned long  *OUTPUT,
 
222
                      unsigned char  *OUTPUT
 
223
{
 
224
    $result = output_helper($result, UINT2NUM(*$1));
 
225
}
 
226
 
 
227
%typemap(ruby,argout) float    *OUTPUT,
 
228
                      double   *OUTPUT
 
229
{
 
230
    $result = output_helper($result, rb_float_new(*$1));
 
231
}
 
232
 
 
233
// INOUT
 
234
// Mappings for an argument that is both an input and output
 
235
// parameter
 
236
 
 
237
 
 
238
#ifdef AUTODOC
 
239
%subsection "Input/Output Methods"
 
240
 
 
241
%text %{
 
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.
 
246
 
 
247
         int            *INOUT
 
248
         short          *INOUT
 
249
         long           *INOUT
 
250
         unsigned int   *INOUT
 
251
         unsigned short *INOUT
 
252
         unsigned long  *INOUT
 
253
         unsigned char  *INOUT
 
254
         float          *INOUT
 
255
         double         *INOUT
 
256
         
 
257
For example, suppose you were trying to wrap the following function :
 
258
 
 
259
        void neg(double *x) {
 
260
             *x = -(*x);
 
261
        }
 
262
 
 
263
You could wrap it with SWIG as follows :
 
264
 
 
265
        %include typemaps.i
 
266
        void neg(double *INOUT);
 
267
 
 
268
or you can use the %apply directive :
 
269
 
 
270
        %include typemaps.i
 
271
        %apply double *INOUT { double *x };
 
272
        void neg(double *x);
 
273
 
 
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 :
 
278
 
 
279
       x = neg(x)
 
280
 
 
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.
 
284
%}
 
285
 
 
286
#endif
 
287
 
 
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;
 
297
 
 
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;
 
307
 
 
308
// Backwards compatibility
 
309
 
 
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 };
 
319
 
 
320
// --------------------------------------------------------------------
 
321
// OUTPUT typemaps for user defined type.
 
322
//
 
323
// --------------------------------------------------------------------
 
324
 
 
325
#ifdef AUTODOC
 
326
%subsection "Output Methods for User-defined types"
 
327
 
 
328
%text %{
 
329
The following method can be applied to turn a pointer to
 
330
user-defined type returned through function aruguments into
 
331
an output value.
 
332
 
 
333
         User **OUTPUT
 
334
         
 
335
You can use the %apply directive :
 
336
 
 
337
        %include typemaps.i
 
338
        %apply User **OUTPUT { Foo **OUTPUT };
 
339
        int foo_func(Foo **OUTPUT);
 
340
 
 
341
%}
 
342
#endif
 
343
 
 
344
%typemap(ruby,ignore) User **OUTPUT(void *temp)
 
345
{
 
346
  $1 = ($type)&temp;
 
347
}
 
348
%typemap(ruby,argout) User **OUTPUT
 
349
{
 
350
  $result = output_helper($result, Wrap_$basetype(*$1));
 
351
}
 
352
 
 
353
 
 
354
// --------------------------------------------------------------------
 
355
// Special types
 
356
//
 
357
// --------------------------------------------------------------------
 
358
 
 
359
#ifdef AUTODOC
 
360
%subsection "Special Methods"
 
361
 
 
362
%text %{
 
363
The typemaps.i library also provides the following mappings :
 
364
 
 
365
struct timeval *
 
366
time_t
 
367
 
 
368
    Ruby has builtin class Time.  INPUT/OUPUT typemap for timeval and
 
369
    time_t is provided.
 
370
 
 
371
int PROG_ARGC
 
372
char **PROG_ARGV
 
373
 
 
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.
 
377
%}
 
378
 
 
379
#endif
 
380
 
 
381
 
 
382
// struct timeval *
 
383
%{
 
384
#ifdef __cplusplus
 
385
extern "C" {
 
386
#endif
 
387
#ifdef HAVE_SYS_TIME_H
 
388
# include <sys/time.h>
 
389
struct timeval rb_time_timeval(VALUE);
 
390
#endif
 
391
#ifdef __cplusplus
 
392
}
 
393
#endif
 
394
%}
 
395
 
 
396
%typemap(ruby,in) struct timeval *INPUT (struct timeval temp)
 
397
{
 
398
    if (NIL_P($input))
 
399
        $1 = NULL;
 
400
    else {
 
401
        temp = rb_time_timeval($input);
 
402
        $1 = &temp;
 
403
    }
 
404
}
 
405
 
 
406
%typemap(ruby,ignore) struct timeval *OUTPUT(struct timeval temp)
 
407
{
 
408
    $1 = &temp;
 
409
}
 
410
 
 
411
%typemap(ruby,argout) struct timeval *OUTPUT
 
412
{
 
413
    $result = rb_time_new($1->tv_sec, $1->tv_usec);
 
414
}
 
415
 
 
416
%typemap(ruby,out) struct timeval *
 
417
{
 
418
    $result = rb_time_new($1->tv_sec, $1->tv_usec);
 
419
}
 
420
 
 
421
%typemap(ruby,out) struct timespec *
 
422
{
 
423
    $result = rb_time_new($1->tv_sec, $1->tv_nsec / 1000);
 
424
}
 
425
 
 
426
// time_t
 
427
%typemap(ruby,in) time_t
 
428
{
 
429
    if (NIL_P($input))
 
430
        $1 = (time_t)-1;
 
431
    else
 
432
        $1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0));
 
433
}
 
434
 
 
435
%typemap(ruby,out) time_t
 
436
{
 
437
    $result = rb_time_new($1, 0);
 
438
}
 
439
 
 
440
// argc and argv
 
441
%typemap(ruby,ignore) int PROG_ARGC {
 
442
    $1 = RARRAY(rb_argv)->len + 1;
 
443
}
 
444
 
 
445
%typemap(ruby,ignore) char **PROG_ARGV {
 
446
    int i, n;
 
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);
 
454
    }
 
455
}
 
456
 
 
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]);
 
460
    free($1);
 
461
}
 
462
 
 
463
// FILE *
 
464
%{
 
465
#ifdef __cplusplus
 
466
extern "C" {
 
467
#endif
 
468
#include "rubyio.h"
 
469
#ifdef __cplusplus
 
470
}
 
471
#endif
 
472
%}
 
473
%typemap(ruby,in) FILE *READ {
 
474
    OpenFile *of;
 
475
    GetOpenFile($input, of);
 
476
    rb_io_check_readable(of);
 
477
    $1 = GetReadFile(of);
 
478
    rb_read_check($1);
 
479
}
 
480
%typemap(ruby,in) FILE *READ_NOCHECK {
 
481
    OpenFile *of;
 
482
    GetOpenFile($input, of);
 
483
    rb_io_check_readable(of);
 
484
    $1 = GetReadFile(of);
 
485
}
 
486
%typemap(ruby,in) FILE *WRITE {
 
487
    OpenFile *of;
 
488
    GetOpenFile($input, of);
 
489
    rb_io_check_writable(of);
 
490
    $1 = GetWriteFile(of);
 
491
}