1/* -----------------------------------------------------------------------------
2 * rubyrun.swg
3 *
4 * This file contains the runtime support for Ruby modules
5 * and includes code for managing global variables and pointer
6 * type checking.
7 * ----------------------------------------------------------------------------- */
8
9/* For backward compatibility only */
10#define SWIG_POINTER_EXCEPTION  0
11
12/* for raw pointers */
13#define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Ruby_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
14#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_Ruby_ConvertPtrAndOwn(obj, pptr, type, flags, own)
15#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Ruby_NewPointerObj(ptr, type, flags)
16#define SWIG_AcquirePtr(ptr, own)                       SWIG_Ruby_AcquirePtr(ptr, own)
17#define swig_owntype                                    ruby_owntype
18
19/* for raw packed data */
20#define SWIG_ConvertPacked(obj, ptr, sz, ty)            SWIG_Ruby_ConvertPacked(obj, ptr, sz, ty, flags)
21#define SWIG_NewPackedObj(ptr, sz, type)                SWIG_Ruby_NewPackedObj(ptr, sz, type)
22
23/* for class or struct pointers */
24#define SWIG_ConvertInstance(obj, pptr, type, flags)    SWIG_ConvertPtr(obj, pptr, type, flags)
25#define SWIG_NewInstanceObj(ptr, type, flags)           SWIG_NewPointerObj(ptr, type, flags)
26
27/* for C or C++ function pointers */
28#define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_ConvertPtr(obj, pptr, type, 0)
29#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_NewPointerObj(ptr, type, 0)
30
31/* for C++ member pointers, ie, member methods */
32#define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_Ruby_ConvertPacked(obj, ptr, sz, ty)
33#define SWIG_NewMemberObj(ptr, sz, type)                SWIG_Ruby_NewPackedObj(ptr, sz, type)
34
35
36/* Runtime API */
37
38#define SWIG_GetModule(clientdata)                      SWIG_Ruby_GetModule(clientdata)
39#define SWIG_SetModule(clientdata, pointer) 		SWIG_Ruby_SetModule(pointer)
40
41
42/* Error manipulation */
43
44#define SWIG_ErrorType(code)                            SWIG_Ruby_ErrorType(code)
45#define SWIG_Error(code, msg)            		rb_raise(SWIG_Ruby_ErrorType(code), "%s", msg)
46#define SWIG_fail                        		goto fail
47
48
49/* Ruby-specific SWIG API */
50
51#define SWIG_InitRuntime()                              SWIG_Ruby_InitRuntime()
52#define SWIG_define_class(ty)                        	SWIG_Ruby_define_class(ty)
53#define SWIG_NewClassInstance(value, ty)             	SWIG_Ruby_NewClassInstance(value, ty)
54#define SWIG_MangleStr(value)                        	SWIG_Ruby_MangleStr(value)
55#define SWIG_CheckConvert(value, ty)                 	SWIG_Ruby_CheckConvert(value, ty)
56
57#include "assert.h"
58
59/* -----------------------------------------------------------------------------
60 * pointers/data manipulation
61 * ----------------------------------------------------------------------------- */
62
63#ifdef __cplusplus
64extern "C" {
65#endif
66
67typedef struct {
68  VALUE klass;
69  VALUE mImpl;
70  void  (*mark)(void *);
71  void  (*destroy)(void *);
72  int trackObjects;
73} swig_class;
74
75
76/* Global pointer used to keep some internal SWIG stuff */
77static VALUE _cSWIG_Pointer = Qnil;
78static VALUE swig_runtime_data_type_pointer = Qnil;
79
80/* Global IDs used to keep some internal SWIG stuff */
81static ID swig_arity_id = 0;
82static ID swig_call_id  = 0;
83
84/*
85  If your swig extension is to be run within an embedded ruby and has
86  director callbacks, you should set -DRUBY_EMBEDDED during compilation.
87  This will reset ruby's stack frame on each entry point from the main
88  program the first time a virtual director function is invoked (in a
89  non-recursive way).
90  If this is not done, you run the risk of Ruby trashing the stack.
91*/
92
93#ifdef RUBY_EMBEDDED
94
95#  define SWIG_INIT_STACK                            \
96      if ( !swig_virtual_calls ) { RUBY_INIT_STACK } \
97      ++swig_virtual_calls;
98#  define SWIG_RELEASE_STACK --swig_virtual_calls;
99#  define Ruby_DirectorTypeMismatchException(x) \
100          rb_raise( rb_eTypeError, "%s", x ); return c_result;
101
102      static unsigned int swig_virtual_calls = 0;
103
104#else  /* normal non-embedded extension */
105
106#  define SWIG_INIT_STACK
107#  define SWIG_RELEASE_STACK
108#  define Ruby_DirectorTypeMismatchException(x) \
109          throw Swig::DirectorTypeMismatchException( x );
110
111#endif  /* RUBY_EMBEDDED */
112
113
114SWIGRUNTIME VALUE
115getExceptionClass(void) {
116  static int init = 0;
117  static VALUE rubyExceptionClass ;
118  if (!init) {
119    init = 1;
120    rubyExceptionClass = rb_const_get(_mSWIG, rb_intern("Exception"));
121  }
122  return rubyExceptionClass;
123}
124
125/* This code checks to see if the Ruby object being raised as part
126   of an exception inherits from the Ruby class Exception.  If so,
127   the object is simply returned.  If not, then a new Ruby exception
128   object is created and that will be returned to Ruby.*/
129SWIGRUNTIME VALUE
130SWIG_Ruby_ExceptionType(swig_type_info *desc, VALUE obj) {
131  VALUE exceptionClass = getExceptionClass();
132  if (rb_obj_is_kind_of(obj, exceptionClass)) {
133    return obj;
134  }  else {
135    return rb_exc_new3(rb_eRuntimeError, rb_obj_as_string(obj));
136  }
137}
138
139/* Initialize Ruby runtime support */
140SWIGRUNTIME void
141SWIG_Ruby_InitRuntime(void)
142{
143  if (_mSWIG == Qnil) {
144    _mSWIG = rb_define_module("SWIG");
145    swig_call_id  = rb_intern("call");
146    swig_arity_id = rb_intern("arity");
147  }
148}
149
150/* Define Ruby class for C type */
151SWIGRUNTIME void
152SWIG_Ruby_define_class(swig_type_info *type)
153{
154  VALUE klass;
155  char *klass_name = (char *) malloc(4 + strlen(type->name) + 1);
156  sprintf(klass_name, "TYPE%s", type->name);
157  if (NIL_P(_cSWIG_Pointer)) {
158    _cSWIG_Pointer = rb_define_class_under(_mSWIG, "Pointer", rb_cObject);
159    rb_undef_method(CLASS_OF(_cSWIG_Pointer), "new");
160  }
161  klass = rb_define_class_under(_mSWIG, klass_name, _cSWIG_Pointer);
162  free((void *) klass_name);
163}
164
165/* Create a new pointer object */
166SWIGRUNTIME VALUE
167SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
168{
169  int own =  flags & SWIG_POINTER_OWN;
170  int track;
171  char *klass_name;
172  swig_class *sklass;
173  VALUE klass;
174  VALUE obj;
175
176  if (!ptr)
177    return Qnil;
178
179  if (type->clientdata) {
180    sklass = (swig_class *) type->clientdata;
181
182    /* Are we tracking this class and have we already returned this Ruby object? */
183    track = sklass->trackObjects;
184    if (track) {
185      obj = SWIG_RubyInstanceFor(ptr);
186
187      /* Check the object's type and make sure it has the correct type.
188        It might not in cases where methods do things like
189        downcast methods. */
190      if (obj != Qnil) {
191        VALUE value = rb_iv_get(obj, "@__swigtype__");
192        const char* type_name = RSTRING_PTR(value);
193
194        if (strcmp(type->name, type_name) == 0) {
195          return obj;
196        }
197      }
198    }
199
200    /* Create a new Ruby object */
201    obj = Data_Wrap_Struct(sklass->klass, VOIDFUNC(sklass->mark),
202			   ( own ? VOIDFUNC(sklass->destroy) :
203			     (track ? VOIDFUNC(SWIG_RubyRemoveTracking) : 0 )
204			     ), ptr);
205
206    /* If tracking is on for this class then track this object. */
207    if (track) {
208      SWIG_RubyAddTracking(ptr, obj);
209    }
210  } else {
211    klass_name = (char *) malloc(4 + strlen(type->name) + 1);
212    sprintf(klass_name, "TYPE%s", type->name);
213    klass = rb_const_get(_mSWIG, rb_intern(klass_name));
214    free((void *) klass_name);
215    obj = Data_Wrap_Struct(klass, 0, 0, ptr);
216  }
217  rb_iv_set(obj, "@__swigtype__", rb_str_new2(type->name));
218
219  return obj;
220}
221
222/* Create a new class instance (always owned) */
223SWIGRUNTIME VALUE
224SWIG_Ruby_NewClassInstance(VALUE klass, swig_type_info *type)
225{
226  VALUE obj;
227  swig_class *sklass = (swig_class *) type->clientdata;
228  obj = Data_Wrap_Struct(klass, VOIDFUNC(sklass->mark), VOIDFUNC(sklass->destroy), 0);
229  rb_iv_set(obj, "@__swigtype__", rb_str_new2(type->name));
230  return obj;
231}
232
233/* Get type mangle from class name */
234SWIGRUNTIMEINLINE char *
235SWIG_Ruby_MangleStr(VALUE obj)
236{
237  VALUE stype = rb_iv_get(obj, "@__swigtype__");
238  return StringValuePtr(stype);
239}
240
241/* Acquire a pointer value */
242typedef void (*ruby_owntype)(void*);
243
244SWIGRUNTIME ruby_owntype
245SWIG_Ruby_AcquirePtr(VALUE obj, ruby_owntype own) {
246  if (obj) {
247    ruby_owntype oldown = RDATA(obj)->dfree;
248    RDATA(obj)->dfree = own;
249    return oldown;
250  } else {
251    return 0;
252  }
253}
254
255/* Convert a pointer value */
256SWIGRUNTIME int
257SWIG_Ruby_ConvertPtrAndOwn(VALUE obj, void **ptr, swig_type_info *ty, int flags, ruby_owntype *own)
258{
259  char *c;
260  swig_cast_info *tc;
261  void *vptr = 0;
262
263  /* Grab the pointer */
264  if (NIL_P(obj)) {
265    *ptr = 0;
266    return SWIG_OK;
267  } else {
268    if (TYPE(obj) != T_DATA) {
269      return SWIG_ERROR;
270    }
271    Data_Get_Struct(obj, void, vptr);
272  }
273
274  if (own) *own = RDATA(obj)->dfree;
275
276  /* Check to see if the input object is giving up ownership
277     of the underlying C struct or C++ object.  If so then we
278     need to reset the destructor since the Ruby object no
279     longer owns the underlying C++ object.*/
280  if (flags & SWIG_POINTER_DISOWN) {
281    /* Is tracking on for this class? */
282    int track = 0;
283    if (ty && ty->clientdata) {
284      swig_class *sklass = (swig_class *) ty->clientdata;
285      track = sklass->trackObjects;
286    }
287
288    if (track) {
289      /* We are tracking objects for this class.  Thus we change the destructor
290       * to SWIG_RubyRemoveTracking.  This allows us to
291       * remove the mapping from the C++ to Ruby object
292       * when the Ruby object is garbage collected.  If we don't
293       * do this, then it is possible we will return a reference
294       * to a Ruby object that no longer exists thereby crashing Ruby. */
295      RDATA(obj)->dfree = SWIG_RubyRemoveTracking;
296    } else {
297      RDATA(obj)->dfree = 0;
298    }
299  }
300
301  /* Do type-checking if type info was provided */
302  if (ty) {
303    if (ty->clientdata) {
304      if (rb_obj_is_kind_of(obj, ((swig_class *) (ty->clientdata))->klass)) {
305        if (vptr == 0) {
306          /* The object has already been deleted */
307          return SWIG_ObjectPreviouslyDeletedError;
308        }
309        *ptr = vptr;
310        return SWIG_OK;
311      }
312    }
313    if ((c = SWIG_MangleStr(obj)) == NULL) {
314      return SWIG_ERROR;
315    }
316    tc = SWIG_TypeCheck(c, ty);
317    if (!tc) {
318      return SWIG_ERROR;
319    } else {
320      int newmemory = 0;
321      *ptr = SWIG_TypeCast(tc, vptr, &newmemory);
322      assert(!newmemory); /* newmemory handling not yet implemented */
323    }
324  } else {
325    *ptr = vptr;
326  }
327
328  return SWIG_OK;
329}
330
331/* Check convert */
332SWIGRUNTIMEINLINE int
333SWIG_Ruby_CheckConvert(VALUE obj, swig_type_info *ty)
334{
335  char *c = SWIG_MangleStr(obj);
336  if (!c) return 0;
337  return SWIG_TypeCheck(c,ty) != 0;
338}
339
340SWIGRUNTIME VALUE
341SWIG_Ruby_NewPackedObj(void *ptr, int sz, swig_type_info *type) {
342  char result[1024];
343  char *r = result;
344  if ((2*sz + 1 + strlen(type->name)) > 1000) return 0;
345  *(r++) = '_';
346  r = SWIG_PackData(r, ptr, sz);
347  strcpy(r, type->name);
348  return rb_str_new2(result);
349}
350
351/* Convert a packed value value */
352SWIGRUNTIME int
353SWIG_Ruby_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty) {
354  swig_cast_info *tc;
355  const char  *c;
356
357  if (TYPE(obj) != T_STRING) goto type_error;
358  c = StringValuePtr(obj);
359  /* Pointer values must start with leading underscore */
360  if (*c != '_') goto type_error;
361  c++;
362  c = SWIG_UnpackData(c, ptr, sz);
363  if (ty) {
364    tc = SWIG_TypeCheck(c, ty);
365    if (!tc) goto type_error;
366  }
367  return SWIG_OK;
368
369 type_error:
370  return SWIG_ERROR;
371}
372
373SWIGRUNTIME swig_module_info *
374SWIG_Ruby_GetModule(void *SWIGUNUSEDPARM(clientdata))
375{
376  VALUE pointer;
377  swig_module_info *ret = 0;
378  VALUE verbose = rb_gv_get("VERBOSE");
379
380 /* temporarily disable warnings, since the pointer check causes warnings with 'ruby -w' */
381  rb_gv_set("VERBOSE", Qfalse);
382
383  /* first check if pointer already created */
384  pointer = rb_gv_get("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
385  if (pointer != Qnil) {
386    Data_Get_Struct(pointer, swig_module_info, ret);
387  }
388
389  /* reinstate warnings */
390  rb_gv_set("VERBOSE", verbose);
391  return ret;
392}
393
394SWIGRUNTIME void
395SWIG_Ruby_SetModule(swig_module_info *pointer)
396{
397  /* register a new class */
398  VALUE cl = rb_define_class("swig_runtime_data", rb_cObject);
399  /* create and store the structure pointer to a global variable */
400  swig_runtime_data_type_pointer = Data_Wrap_Struct(cl, 0, 0, pointer);
401  rb_define_readonly_variable("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, &swig_runtime_data_type_pointer);
402}
403
404/* This function can be used to check whether a proc or method or similarly
405   callable function has been passed.  Usually used in a %typecheck, like:
406
407   %typecheck(c_callback_t, precedence=SWIG_TYPECHECK_POINTER) {
408        $result = SWIG_Ruby_isCallable( $input );
409   }
410 */
411SWIGINTERN
412int SWIG_Ruby_isCallable( VALUE proc )
413{
414  if ( rb_respond_to( proc, swig_call_id ) )
415    return 1;
416  return 0;
417}
418
419/* This function can be used to check the arity (number of arguments)
420   a proc or method can take.  Usually used in a %typecheck.
421   Valid arities will be that equal to minimal or those < 0
422   which indicate a variable number of parameters at the end.
423 */
424SWIGINTERN
425int SWIG_Ruby_arity( VALUE proc, int minimal )
426{
427  if ( rb_respond_to( proc, swig_arity_id ) )
428    {
429      VALUE num = rb_funcall( proc, swig_arity_id, 0 );
430      int arity = NUM2INT(num);
431      if ( arity < 0 && (arity+1) < -minimal ) return 1;
432      if ( arity == minimal ) return 1;
433      return 1;
434    }
435  return 0;
436}
437
438
439#ifdef __cplusplus
440}
441#endif
442