1 %insert(runtime) %{ 2 #include <cstdlib> 3 #include <iostream> 4 #include <octave/oct.h> 5 #include <octave/Cell.h> 6 #include <octave/dynamic-ld.h> 7 #include <octave/oct-env.h> 8 #include <octave/oct-map.h> 9 #include <octave/ov-fcn-handle.h> 10 #include <octave/parse.h> 11 #include <octave/toplev.h> 12 #include <octave/unwind-prot.h> 13 %} 14 15 %insert(runtime) "swigrun.swg"; 16 %insert(runtime) "swigerrors.swg"; 17 %insert(runtime) "octrun.swg"; 18 19 %insert(initbeforefunc) "swiginit.swg" 20 21 %insert(initbeforefunc) %{ 22 23 static bool SWIG_init_user(octave_swig_type* module_ns); 24 25 SWIGINTERN bool SWIG_Octave_LoadModule(std::string name) { 26 bool retn; 27 { 28 #if OCTAVE_API_VERSION_NUMBER < 38 29 unwind_protect::begin_frame("SWIG_Octave_LoadModule"); 30 unwind_protect_int(error_state); 31 unwind_protect_int(warning_state); 32 unwind_protect_bool(discard_error_messages); 33 unwind_protect_bool(discard_warning_messages); 34 #else 35 unwind_protect frame; 36 frame.protect_var(error_state); 37 frame.protect_var(warning_state); 38 frame.protect_var(discard_error_messages); 39 frame.protect_var(discard_warning_messages); 40 #endif 41 error_state = 0; 42 warning_state = 0; 43 discard_error_messages = true; 44 discard_warning_messages = true; 45 feval(name, octave_value_list(), 0); 46 retn = (error_state == 0); 47 #if OCTAVE_API_VERSION_NUMBER < 38 48 unwind_protect::run_frame("SWIG_Octave_LoadModule"); 49 #endif 50 } 51 if (!retn) { 52 error(SWIG_name_d ": could not load module `%s'", name.c_str()); 53 } 54 return retn; 55 } 56 57 SWIGINTERN bool SWIG_Octave_InstallFunction(octave_function *octloadfcn, std::string name) { 58 bool retn; 59 { 60 #if OCTAVE_API_VERSION_NUMBER < 38 61 unwind_protect::begin_frame("SWIG_Octave_InstallFunction"); 62 unwind_protect_int(error_state); 63 unwind_protect_int(warning_state); 64 unwind_protect_bool(discard_error_messages); 65 unwind_protect_bool(discard_warning_messages); 66 #else 67 unwind_protect frame; 68 frame.protect_var(error_state); 69 frame.protect_var(warning_state); 70 frame.protect_var(discard_error_messages); 71 frame.protect_var(discard_warning_messages); 72 #endif 73 error_state = 0; 74 warning_state = 0; 75 discard_error_messages = true; 76 discard_warning_messages = true; 77 octave_value_list args; 78 args.append(name); 79 args.append(octloadfcn->fcn_file_name()); 80 error_state = 0; 81 feval("autoload", args, 0); 82 retn = (error_state == 0); 83 #if OCTAVE_API_VERSION_NUMBER < 38 84 unwind_protect::run_frame("SWIG_Octave_InstallFunction"); 85 #endif 86 } 87 if (!retn) { 88 error(SWIG_name_d ": could not load function `%s'", name.c_str()); 89 } 90 return retn; 91 } 92 93 static const char *const subclass_usage = "-*- texinfo -*- \n\ 94 @deftypefn {Loadable Function} {} subclass()\n\ 95 @deftypefnx{Loadable Function} {} subclass(@var{swigclass}, @var{name}, @var{fcn}, @dots{})\n\ 96 Subclass a C++ class from within Octave, and provide implementations of its virtual methods.\n\ 97 \n\ 98 See the SWIG manual for usage examples.\n\ 99 @end deftypefn"; 100 101 DEFUN_DLD( subclass, args, nargout, subclass_usage ) { 102 octave_swig_type *top = new octave_swig_type; 103 for (int j = 0; j < args.length(); ++j) { 104 if (args(j).type_id() == octave_swig_ref::static_type_id()) { 105 octave_swig_ref *osr = static_cast < octave_swig_ref *>(args(j).internal_rep()); 106 octave_swig_type *ost = osr->get_ptr(); 107 if (!ost->is_owned()) { 108 error("subclass: cannot subclass object not constructed on octave side"); 109 return octave_value_list(); 110 } 111 top->merge(*ost); 112 } else if (args(j).is_function_handle()) { 113 top->assign(args(j).fcn_handle_value()->fcn_name(), args(j)); 114 } else if (args(j).is_string()) { 115 if (j + 1 >= args.length()) { 116 error("subclass: member assignments must be of string,value form"); 117 return octave_value_list(); 118 } 119 top->assign(args(j).string_value(), args(j + 1)); 120 ++j; 121 } else { 122 error("subclass: invalid arguments to subclass()"); 123 return octave_value_list(); 124 } 125 } 126 return octave_value(Swig::swig_value_ref(top)); 127 } 128 129 static const char *const swig_type_usage = "-*- texinfo -*- \n\ 130 @deftypefn {Loadable Function} {} swig_type(@var{swigref})\n\ 131 Return the underlying C/C++ type name of a SWIG-wrapped object.\n\ 132 @end deftypefn"; 133 134 DEFUN_DLD( swig_type, args, nargout, swig_type_usage ) { 135 if (args.length() != 1) { 136 error("swig_type: must be called with only a single object"); 137 return octave_value_list(); 138 } 139 octave_swig_type *ost = Swig::swig_value_deref(args(0)); 140 if (!ost) { 141 error("swig_type: object is not a swig_ref"); 142 return octave_value_list(); 143 } 144 return octave_value(ost->swig_type_name()); 145 } 146 147 static const char *const swig_typequery_usage = "-*- texinfo -*- \n\ 148 @deftypefn {Loadable Function} {} swig_typequery(@var{string})\n\ 149 Return @var{string} if it is a recognised SWIG-wrapped C/C++ type name;\n\ 150 otherwise return `<unknown>'.\n\ 151 @end deftypefn"; 152 153 DEFUN_DLD( swig_typequery, args, nargout, swig_typequery_usage ) { 154 if (args.length() != 1 || !args(0).is_string()) { 155 error("swig_typequery: must be called with single string argument"); 156 return octave_value_list(); 157 } 158 swig_module_info *module = SWIG_GetModule(0); 159 swig_type_info *type = SWIG_TypeQueryModule(module, module, args(0).string_value().c_str()); 160 if (!type) 161 return octave_value("<unknown>"); 162 return octave_value(type->name); 163 } 164 165 static const char *const swig_this_usage = "-*- texinfo -*- \n\ 166 @deftypefn {Loadable Function} {} swig_this(@var{swigref})\n\ 167 Return the underlying C/C++ pointer of a SWIG-wrapped object.\n\ 168 @end deftypefn"; 169 170 DEFUN_DLD( swig_this, args, nargout, swig_this_usage ) { 171 if (args.length() != 1) { 172 error("swig_this: must be called with only a single object"); 173 return octave_value_list(); 174 } 175 if (args(0).is_matrix_type() && args(0).rows() == 0 && args(0).columns() == 0) 176 return octave_value(octave_uint64(0)); 177 octave_swig_type *ost = Swig::swig_value_deref(args(0)); 178 if (!ost) { 179 error("swig_this: object is not a swig_ref"); 180 return octave_value_list(); 181 } 182 return octave_value(octave_uint64((unsigned long long) ost->swig_this())); 183 } 184 185 static const char *const SWIG_name_usage = "-*- texinfo -*- \n\ 186 @deftypefn {Loadable Module} {} " SWIG_name_d "\n\ 187 Loads the SWIG-generated module `" SWIG_name_d "'.\n\ 188 @end deftypefn"; 189 190 DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { 191 192 static octave_swig_type* module_ns = 0; 193 194 // workaround to prevent octave seg-faulting on exit: set Octave exit function 195 // octave_exit to _Exit, which exits immediately without trying to cleanup memory. 196 // definitely affects version 3.2.*, not sure about 3.3.*, seems to be fixed in 197 // version 3.4.* and above. can be turned off with macro definition. 198 #ifndef SWIG_OCTAVE_NO_SEGFAULT_HACK 199 #if 36 < OCTAVE_API_VERSION_NUMBER && OCTAVE_API_VERSION_NUMBER < 45 200 octave_exit = ::_Exit; 201 #endif 202 #endif 203 204 // check for no input and output args 205 if (args.length() != 0 || nargout != 0) { 206 print_usage(); 207 return octave_value_list(); 208 } 209 210 // create module on first function call 211 if (!module_ns) { 212 213 // workaround bug in octave where installing global variable of custom type and then 214 // exiting without explicitly clearing the variable causes octave to segfault. 215 #if OCTAVE_API_VERSION_NUMBER > 36 216 octave_value_list eval_args; 217 eval_args.append("base"); 218 eval_args.append("function __swig_atexit__; " 219 " if mislocked() " 220 " clear -all; " 221 " else " 222 " mlock(); " 223 " endif; " 224 "endfunction; " 225 "__swig_atexit__; " 226 "atexit(\"__swig_atexit__\", false); " 227 "atexit(\"__swig_atexit__\")"); 228 feval("evalin", eval_args, 0); 229 #endif 230 231 octave_swig_ref::register_type(); 232 octave_swig_packed::register_type(); 233 SWIG_InitializeModule(0); 234 SWIG_PropagateClientData(); 235 236 octave_function *me = octave_call_stack::current(); 237 238 if (!SWIG_Octave_InstallFunction(me, "swig_type")) { 239 return octave_value_list(); 240 } 241 if (!SWIG_Octave_InstallFunction(me, "swig_typequery")) { 242 return octave_value_list(); 243 } 244 if (!SWIG_Octave_InstallFunction(me, "swig_this")) { 245 return octave_value_list(); 246 } 247 if (!SWIG_Octave_InstallFunction(me, "subclass")) { 248 return octave_value_list(); 249 } 250 251 octave_swig_type* cvar_ns=0; 252 if (std::string(SWIG_global_name) != ".") { 253 cvar_ns=new octave_swig_type; 254 for (int j=0;swig_globals[j].name;++j) 255 if (swig_globals[j].get_method) 256 cvar_ns->assign(swig_globals[j].name,&swig_globals[j]); 257 } 258 259 module_ns=new octave_swig_type(0, 0, 0, true); 260 if (std::string(SWIG_global_name) != ".") { 261 module_ns->assign(SWIG_global_name,Swig::swig_value_ref(cvar_ns)); 262 } 263 else { 264 for (int j=0;swig_globals[j].name;++j) 265 if (swig_globals[j].get_method) 266 module_ns->assign(swig_globals[j].name,&swig_globals[j]); 267 } 268 for (int j=0;swig_globals[j].name;++j) 269 if (swig_globals[j].method) 270 module_ns->assign(swig_globals[j].name,&swig_globals[j]); 271 272 // * need better solution here; swig_type -> octave_class mapping is 273 // * really n-to-1, in some cases such as template partial spec, etc. 274 // * see failing tests. 275 for (int j=0;swig_types[j];++j) 276 if (swig_types[j]->clientdata) { 277 swig_octave_class* c=(swig_octave_class*)swig_types[j]->clientdata; 278 module_ns->assign(c->name, 279 Swig::swig_value_ref 280 (new octave_swig_type(0,swig_types[j]))); 281 } 282 283 if (!SWIG_init_user(module_ns)) { 284 delete module_ns; 285 module_ns=0; 286 return octave_value_list(); 287 } 288 289 SWIG_InstallOps(octave_swig_ref::static_type_id()); 290 291 octave_swig_type::swig_member_const_iterator mb; 292 for (mb = module_ns->swig_members_begin(); mb != module_ns->swig_members_end(); ++mb) { 293 if (mb->second.first && mb->second.first->method) { 294 if (!SWIG_Octave_InstallFunction(me, mb->first)) { 295 return octave_value_list(); 296 } 297 } 298 } 299 300 #if OCTAVE_API_VERSION_NUMBER < 37 301 mlock(me->name()); 302 #else 303 mlock(); 304 #endif 305 306 } 307 308 octave_swig_type::swig_member_const_iterator mb; 309 for (mb = module_ns->swig_members_begin(); mb != module_ns->swig_members_end(); ++mb) { 310 if (mb->second.second.is_defined()) { 311 SWIG_Octave_SetGlobalValue(mb->first, mb->second.second); 312 SWIG_Octave_LinkGlobalValue(mb->first); 313 } 314 } 315 316 SWIG_Octave_SetGlobalValue(SWIG_name_d, module_ns->as_value()); 317 SWIG_Octave_LinkGlobalValue(SWIG_name_d); 318 319 return octave_value_list(); 320 321 } 322 323 %} 324