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