octruntime.swg 10 KB

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