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