/trunk/Lib/octave/octruntime.swg
Unknown | 181 lines | 153 code | 28 blank | 0 comment | 0 complexity | 8e5fb837c3b3d56e678a25e45112801e MD5 | raw file
1%insert(runtime) %{ 2#include <iostream> 3#include <octave/oct.h> 4#include <octave/parse.h> 5#include <octave/ov-fcn-handle.h> 6#include <octave/Cell.h> 7#include <octave/oct-map.h> 8#include <octave/toplev.h> 9%} 10 11%insert(runtime) "swigrun.swg"; 12%insert(runtime) "swigerrors.swg"; 13%insert(runtime) "octrun.swg"; 14 15%insert(initbeforefunc) "swiginit.swg" 16 17%insert(initbeforefunc) %{ 18 19static void SWIG_init_user(octave_swig_type* module_ns); 20 21#if OCTAVE_API_VERSION_NUMBER>=37 22octave_value_list SWIG_atexit_func(const octave_value_list &args, int nargout); 23#endif 24 25DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { 26 27 // determine if module is already loaded 28 bool already_load; 29#if OCTAVE_API_VERSION_NUMBER<37 30 { 31 symbol_record *rec = curr_sym_tab->lookup(SWIG_name_d); 32 already_load = (rec && rec->is_linked_to_global()); 33 } 34#else 35 already_load = symbol_table::is_global(SWIG_name_d); 36#endif 37 if (!already_load) { 38 39 // parse command line 40 const char* usage="usage: " SWIG_name_d " [-global|-noglobal] [-globals {<name>|.}]"; 41 bool global_load=SWIG_global_load; 42 std::string global_name=SWIG_global_name; 43 for (int j=0;j<args.length();++j) 44 if (args(j).is_string()) { 45 if (args(j).string_value()=="-help") { 46 std::cout << usage << std::endl; 47 return octave_value_list(); 48 } else if (args(j).string_value()=="-global") { 49 global_load = true; 50 } else if (args(j).string_value()=="-noglobal") { 51 global_load = false; 52 } else if (args(j).string_value()=="-globals") { 53 if (j+1<args.length()&&args(j+1).is_string()) { 54 global_name = args(j+1).string_value(); 55 ++j; 56 } else { 57 std::cerr << "error: " SWIG_name_d ": option '-globals' requires an argument." << std::endl; 58 std::cerr << usage << std::endl; 59 return octave_value_list(); 60 } 61 } else { 62 std::cerr << "error: " SWIG_name_d ": unrecognised argument '" << args(j).string_value() << "'." << std::endl; 63 std::cerr << usage << std::endl; 64 return octave_value_list(); 65 } 66 } else { 67 std::cerr << "error: " SWIG_name_d ": unrecognised non-string argument." << std::endl; 68 std::cerr << usage << std::endl; 69 return octave_value_list(); 70 } 71 72 if (global_name != "." && !valid_identifier(global_name)) { 73 std::cerr << "error: " SWIG_name_d ": '" << global_name << "' is not a valid Octave identifier." << std::endl; 74 return octave_value_list(); 75 } 76 77 // load module in base frame 78#if OCTAVE_API_VERSION_NUMBER<37 79 symbol_table *prev_sym_tab = curr_sym_tab; 80 curr_sym_tab = top_level_sym_tab; 81#else 82 octave_call_stack::goto_base_frame(); 83#endif 84 85 octave_swig_ref::register_type(); 86 octave_swig_packed::register_type(); 87 SWIG_InitializeModule(0); 88 SWIG_PropagateClientData(); 89 90 install_builtin_function(swig_type,"swig_type",std::string()); 91 install_builtin_function(swig_typequery,"swig_typequery",std::string()); 92 install_builtin_function(swig_this,"swig_this",std::string()); 93 install_builtin_function(swig_subclass,"subclass",std::string()); 94 95 octave_swig_type* cvar_ns=0; 96 if (global_name != ".") { 97 cvar_ns=new octave_swig_type; 98 for (int j=0;swig_globals[j].name;++j) 99 if (swig_globals[j].get_method) 100 cvar_ns->assign(swig_globals[j].name,&swig_globals[j]); 101 } 102 103 octave_swig_type* module_ns=new octave_swig_type(0, 0, 0, true); 104 if (global_name != ".") { 105 module_ns->assign(global_name,Swig::swig_value_ref(cvar_ns)); 106 } 107 else { 108 for (int j=0;swig_globals[j].name;++j) 109 if (swig_globals[j].get_method) 110 module_ns->assign(swig_globals[j].name,&swig_globals[j]); 111 } 112 for (int j=0;swig_globals[j].name;++j) 113 if (swig_globals[j].method) 114 module_ns->assign(swig_globals[j].name,&swig_globals[j]); 115 116 // * need better solution here; swig_type -> octave_class mapping is 117 // * really n-to-1, in some cases such as template partial spec, etc. 118 // * see failing tests. 119 for (int j=0;swig_types[j];++j) 120 if (swig_types[j]->clientdata) { 121 swig_octave_class* c=(swig_octave_class*)swig_types[j]->clientdata; 122 module_ns->assign(c->name, 123 Swig::swig_value_ref 124 (new octave_swig_type(0,swig_types[j]))); 125 } 126 127 SWIG_init_user(module_ns); 128 129 SWIG_InstallOps(octave_swig_ref::static_type_id()); 130 131 // the incref is necessary so install_global doesn't destroy module_ns, 132 // as it would if it installed something with the same name as the module. 133 module_ns->incref(); 134 module_ns->install_global(global_load); 135 module_ns->decref(); 136 137 // create global variable containing module 138 set_global_value(SWIG_name_d,Swig::swig_value_ref(module_ns)); 139 140#if OCTAVE_API_VERSION_NUMBER>=37 141 install_builtin_function(SWIG_atexit_func,"__swig_atexit_" SWIG_name_d "__",std::string()); 142 octave_add_atexit_function("__swig_atexit_" SWIG_name_d "__"); 143 octave_remove_atexit_function("__finish__"); 144#endif 145 146 // return from base frame 147#if OCTAVE_API_VERSION_NUMBER<37 148 curr_sym_tab = prev_sym_tab; 149#else 150 octave_call_stack::pop(); 151#endif 152 153#if OCTAVE_API_VERSION_NUMBER>=37 154 mlock(); 155#endif 156 157 } // !already_load 158 159 // link variable to module in current context 160#if OCTAVE_API_VERSION_NUMBER<37 161 link_to_global_variable(curr_sym_tab->lookup(SWIG_name_d,true)); 162#else 163 symbol_table::varref(SWIG_name_d); 164 symbol_table::mark_global(SWIG_name_d); 165#endif 166 167 return octave_value_list(); 168} 169 170// workaround bug in octave where installing global variable of custom type and then 171// exiting without explicitly clearing the variable causes octave to segfault. 172#if OCTAVE_API_VERSION_NUMBER>=37 173octave_value_list SWIG_atexit_func(const octave_value_list &args, int nargout) { 174 symbol_table::clear_global_pattern("*"); 175 symbol_table::clear_functions(); 176 return octave_value(); 177} 178#endif 179 180%} 181