PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Lib/octave/octruntime.swg

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