PageRenderTime 12ms CodeModel.GetById 2ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/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