1#ifdef SWIG_OCTAVE_EXTERNAL_OCTHEADERS
2%insert(runtime) %{
3#include "octheaders.hpp"
4%}
5#else
6%insert(runtime) "octheaders.hpp";
7#endif
8
9%insert(runtime) "swigrun.swg";
10%insert(runtime) "swigerrors.swg";
11%insert(runtime) "octrun.swg";
12
13%insert(initbeforefunc) "swiginit.swg"
14
15%insert(initbeforefunc) %{
16
17static bool SWIG_init_user(octave_swig_type* module_ns);
18
19SWIGINTERN bool SWIG_Octave_LoadModule(std::string name) {
20  bool retn = false;
21  {
22#if SWIG_OCTAVE_PREREQ(4,2,0)
23    octave::unwind_protect frame;
24    frame.protect_var(discard_error_messages);          discard_error_messages = true;
25    frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
26#elif SWIG_OCTAVE_PREREQ(3,3,50)
27    unwind_protect frame;
28    frame.protect_var(error_state);                     error_state = 0;
29    frame.protect_var(warning_state);                   warning_state = 0;
30    frame.protect_var(discard_error_messages);          discard_error_messages = true;
31    frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
32#else
33    unwind_protect::begin_frame("SWIG_Octave_LoadModule");
34    unwind_protect_int(error_state);                    error_state = 0;
35    unwind_protect_int(warning_state);                  warning_state = 0;
36    unwind_protect_bool(discard_error_messages);        discard_error_messages = true;
37    unwind_protect_bool(discard_warning_messages);      discard_warning_messages = true;
38#endif
39#if SWIG_OCTAVE_PREREQ(4,2,0)
40    try {
41#if SWIG_OCTAVE_PREREQ(4,4,0)
42      octave::feval(name, octave_value_list(), 0);
43#else
44      feval(name, octave_value_list(), 0);
45#endif
46      retn = true;
47    } catch (octave::execution_exception&) { }
48#else
49    feval(name, octave_value_list(), 0);
50    retn = (error_state == 0);
51#endif
52#if !SWIG_OCTAVE_PREREQ(3,3,50)
53    unwind_protect::run_frame("SWIG_Octave_LoadModule");
54#endif
55  }
56  if (!retn) {
57    error(SWIG_name_d ": could not load module `%s'", name.c_str());
58  }
59  return retn;
60}
61
62SWIGINTERN bool SWIG_Octave_InstallFunction(octave_function *octloadfcn, std::string name) {
63  bool retn = false;
64  {
65#if SWIG_OCTAVE_PREREQ(4,2,0)
66    octave::unwind_protect frame;
67    frame.protect_var(discard_error_messages);          discard_error_messages = true;
68    frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
69#elif SWIG_OCTAVE_PREREQ(3,3,50)
70    unwind_protect frame;
71    frame.protect_var(error_state);                     error_state = 0;
72    frame.protect_var(warning_state);                   warning_state = 0;
73    frame.protect_var(discard_error_messages);          discard_error_messages = true;
74    frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
75#else
76    unwind_protect::begin_frame("SWIG_Octave_InstallFunction");
77    unwind_protect_int(error_state);                    error_state = 0;
78    unwind_protect_int(warning_state);                  warning_state = 0;
79    unwind_protect_bool(discard_error_messages);        discard_error_messages = true;
80    unwind_protect_bool(discard_warning_messages);      discard_warning_messages = true;
81#endif
82    octave_value_list args;
83    args.append(name);
84    args.append(octloadfcn->fcn_file_name());
85#if SWIG_OCTAVE_PREREQ(4,2,0)
86    try {
87#if SWIG_OCTAVE_PREREQ(4,4,0)
88      octave::feval("autoload", args, 0);
89#else
90      feval("autoload", args, 0);
91#endif
92      retn = true;
93    } catch (octave::execution_exception&) { }
94#else
95    feval("autoload", args, 0);
96    retn = (error_state == 0);
97#endif
98#if !SWIG_OCTAVE_PREREQ(3,3,50)
99    unwind_protect::run_frame("SWIG_Octave_InstallFunction");
100#endif
101  }
102  if (!retn) {
103    error(SWIG_name_d ": could not load function `%s'", name.c_str());
104  }
105  return retn;
106}
107
108static const char *const subclass_usage = "-*- texinfo -*- \n\
109@deftypefn {Loadable Function} {} subclass()\n\
110@deftypefnx{Loadable Function} {} subclass(@var{swigclass}, @var{name}, @var{fcn}, @dots{})\n\
111Subclass a C++ class from within Octave, and provide implementations of its virtual methods.\n\
112\n\
113See the SWIG manual for usage examples.\n\
114@end deftypefn";
115
116DEFUN_DLD( subclass, args, nargout, subclass_usage ) {
117  octave_swig_type *top = new octave_swig_type;
118  for (int j = 0; j < args.length(); ++j) {
119    if (args(j).type_id() == octave_swig_ref::static_type_id()) {
120      octave_swig_ref *osr = static_cast < octave_swig_ref *>(args(j).internal_rep());
121      octave_swig_type *ost = osr->get_ptr();
122      if (!ost->is_owned()) {
123        error("subclass: cannot subclass object not constructed on octave side");
124        return octave_value_list();
125      }
126      top->merge(*ost);
127    } else if (args(j).is_function_handle()) {
128      top->assign(args(j).fcn_handle_value()->fcn_name(), args(j));
129    } else if (args(j).is_string()) {
130      if (j + 1 >= args.length()) {
131        error("subclass: member assignments must be of string,value form");
132        return octave_value_list();
133      }
134      top->assign(args(j).string_value(), args(j + 1));
135      ++j;
136    } else {
137      error("subclass: invalid arguments to subclass()");
138      return octave_value_list();
139    }
140  }
141  return octave_value(Swig::swig_value_ref(top));
142}
143
144static const char *const swig_type_usage = "-*- texinfo -*- \n\
145@deftypefn {Loadable Function} {} swig_type(@var{swigref})\n\
146Return the underlying C/C++ type name of a SWIG-wrapped object.\n\
147@end deftypefn";
148
149DEFUN_DLD( swig_type, args, nargout, swig_type_usage ) {
150  if (args.length() != 1) {
151    error("swig_type: must be called with only a single object");
152    return octave_value_list();
153  }
154  octave_swig_type *ost = Swig::swig_value_deref(args(0));
155  if (!ost) {
156    error("swig_type: object is not a swig_ref");
157    return octave_value_list();
158  }
159  return octave_value(ost->swig_type_name());
160}
161
162static const char *const swig_typequery_usage = "-*- texinfo -*- \n\
163@deftypefn {Loadable Function} {} swig_typequery(@var{string})\n\
164Return @var{string} if it is a recognised SWIG-wrapped C/C++ type name;\n\
165otherwise return `<unknown>'.\n\
166@end deftypefn";
167
168DEFUN_DLD( swig_typequery, args, nargout, swig_typequery_usage ) {
169  if (args.length() != 1 || !args(0).is_string()) {
170    error("swig_typequery: must be called with single string argument");
171    return octave_value_list();
172  }
173  swig_module_info *module = SWIG_GetModule(0);
174  swig_type_info *type = SWIG_TypeQueryModule(module, module, args(0).string_value().c_str());
175  if (!type)
176    return octave_value("<unknown>");
177  return octave_value(type->name);
178}
179
180static const char *const swig_this_usage = "-*- texinfo -*- \n\
181@deftypefn {Loadable Function} {} swig_this(@var{swigref})\n\
182Return the underlying C/C++ pointer of a SWIG-wrapped object.\n\
183@end deftypefn";
184
185DEFUN_DLD( swig_this, args, nargout, swig_this_usage ) {
186  if (args.length() != 1) {
187    error("swig_this: must be called with only a single object");
188    return octave_value_list();
189  }
190  if (args(0).is_matrix_type() && args(0).rows() == 0 && args(0).columns() == 0)
191    return octave_value(octave_uint64(0));
192  octave_swig_type *ost = Swig::swig_value_deref(args(0));
193  if (!ost) {
194    error("swig_this: object is not a swig_ref");
195    return octave_value_list();
196  }
197  return octave_value(octave_uint64((unsigned long long) ost->swig_this()));
198}
199
200static const char *const swig_octave_prereq_usage = "-*- texinfo -*- \n\
201@deftypefn {Loadable Function} {} swig_octave_prereq(@var{major}, @var{minor}, @var{patch})\n\
202Return true if the version of Octave is at least @var{major}.@var{minor}.@var{patch}.\n\
203@end deftypefn";
204
205DEFUN_DLD( swig_octave_prereq, args, nargout, swig_octave_prereq_usage ) {
206  if (args.length() != 3) {
207    error("swig_octave_prereq: must be called with 3 arguments");
208    return octave_value_list();
209  }
210  const int major = args(0).int_value();
211  const int minor = args(1).int_value();
212  const int patch = args(2).int_value();
213  const bool prereq = SWIG_OCTAVE_PREREQ(major, minor, patch);
214  return octave_value(prereq);
215}
216
217static const char *const swig_exit_usage = "-*- texinfo -*- \n\
218@deftypefn {Loadable Function} {} swig_exit([@var{exit_status}])\n\
219Exit Octave without performing any memory cleanup.\n\
220@end deftypefn";
221
222DEFUN_DLD( swig_exit, args, nargout, swig_exit_usage ) {
223  if (args.length() > 1) {
224    error("swig_exit: must be called with at most one arguments");
225    return octave_value_list();
226  }
227  int exit_status = 0;
228  if (args.length() == 1) {
229    exit_status = args(0).int_value();
230  }
231  ::_Exit(exit_status);
232  return octave_value();
233}
234
235static const char *const SWIG_name_usage = "-*- texinfo -*- \n\
236@deftypefn {Loadable Module} {} " SWIG_name_d "\n\
237Loads the SWIG-generated module `" SWIG_name_d "'.\n\
238@end deftypefn";
239
240DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
241
242  static octave_swig_type* module_ns = 0;
243
244  // workaround to prevent octave seg-faulting on exit: set Octave exit function
245  // octave_exit to _Exit, which exits immediately without trying to cleanup memory.
246  // definitely affected version 3.2.*, not sure about 3.3.*, seems to be fixed in
247  // version 3.4.*, reappeared in 4.2.*, hack not possible in 4.4.* or later due to
248  // removal of octave_exit, so turn on for all versions between 3.2.*. and 4.4.*.
249  // can be turned off with macro definition.
250#ifndef SWIG_OCTAVE_NO_SEGFAULT_HACK
251#if !SWIG_OCTAVE_PREREQ(4,4,0)
252#if SWIG_OCTAVE_PREREQ(3,2,0)
253  octave_exit = ::_Exit;
254#endif
255#endif
256#endif
257
258  // check for no input and output args
259  if (args.length() != 0 || nargout != 0) {
260    print_usage();
261    return octave_value_list();
262  }
263
264  // create module on first function call
265  if (!module_ns) {
266
267    // workaround bug in octave where installing global variable of custom type and then
268    // exiting without explicitly clearing the variable causes octave to segfault.
269#if SWIG_OCTAVE_PREREQ(3,2,0)
270    octave_value_list eval_args;
271    eval_args.append("base");
272    eval_args.append("function __swig_atexit__; "
273                     "  if mislocked() "
274                     "    clear -all; "
275                     "  else "
276                     "    mlock(); "
277                     "  endif; "
278                     "endfunction; "
279                     "__swig_atexit__; "
280                     "atexit(\"__swig_atexit__\", false); "
281                     "atexit(\"__swig_atexit__\")");
282#if SWIG_OCTAVE_PREREQ(4,4,0)
283    octave::feval("evalin", eval_args, 0);
284#else
285    feval("evalin", eval_args, 0);
286#endif
287#endif
288
289#if SWIG_OCTAVE_PREREQ(4,4,0)
290    {
291      octave::type_info& typeinfo = octave::interpreter::the_interpreter()->get_type_info();
292      string_vector types = typeinfo.installed_type_names();
293      bool register_octave_swig_ref = true;
294      bool register_octave_swig_packed = true;
295      for (int i = 0; i < types.numel(); ++i) {
296        if (types(i) == octave_swig_ref::static_type_name()) {
297          register_octave_swig_ref = false;
298        }
299        if (types(i) == octave_swig_packed::static_type_name()) {
300          register_octave_swig_packed = false;
301        }
302      }
303      if (register_octave_swig_ref) {
304        octave_swig_ref::register_type();
305      }
306      if (register_octave_swig_packed) {
307        octave_swig_packed::register_type();
308      }
309    }
310#else
311    octave_swig_ref::register_type();
312    octave_swig_packed::register_type();
313#endif
314    SWIG_InitializeModule(0);
315    SWIG_PropagateClientData();
316
317#if SWIG_OCTAVE_PREREQ(4,4,0)
318    octave::call_stack& stack = octave::interpreter::the_interpreter()->get_call_stack();
319    octave_function *me = stack.current();
320#else
321    octave_function *me = octave_call_stack::current();
322#endif
323
324    if (!SWIG_Octave_InstallFunction(me, "subclass")) {
325      return octave_value_list();
326    }
327    if (!SWIG_Octave_InstallFunction(me, "swig_type")) {
328      return octave_value_list();
329    }
330    if (!SWIG_Octave_InstallFunction(me, "swig_typequery")) {
331      return octave_value_list();
332    }
333    if (!SWIG_Octave_InstallFunction(me, "swig_this")) {
334      return octave_value_list();
335    }
336    if (!SWIG_Octave_InstallFunction(me, "swig_octave_prereq")) {
337      return octave_value_list();
338    }
339    if (!SWIG_Octave_InstallFunction(me, "swig_exit")) {
340      return octave_value_list();
341    }
342
343    octave_swig_type* cvar_ns=0;
344    if (std::string(SWIG_global_name) != ".") {
345      cvar_ns=new octave_swig_type;
346      for (int j=0;swig_globals[j].name;++j)
347        if (swig_globals[j].get_method)
348          cvar_ns->assign(swig_globals[j].name,&swig_globals[j]);
349    }
350
351    module_ns=new octave_swig_type(0, 0, 0, true);
352    if (std::string(SWIG_global_name) != ".") {
353      module_ns->assign(SWIG_global_name,Swig::swig_value_ref(cvar_ns));
354    }
355    else {
356      for (int j=0;swig_globals[j].name;++j)
357        if (swig_globals[j].get_method)
358          module_ns->assign(swig_globals[j].name,&swig_globals[j]);
359    }
360    for (int j=0;swig_globals[j].name;++j)
361      if (swig_globals[j].method)
362        module_ns->assign(swig_globals[j].name,&swig_globals[j]);
363
364    // * need better solution here; swig_type -> octave_class mapping is
365    // * really n-to-1, in some cases such as template partial spec, etc.
366    // * see failing tests.
367    for (int j=0;swig_types[j];++j)
368      if (swig_types[j]->clientdata) {
369        swig_octave_class* c=(swig_octave_class*)swig_types[j]->clientdata;
370        module_ns->assign(c->name,
371                        Swig::swig_value_ref
372                        (new octave_swig_type(0,swig_types[j])));
373      }
374
375    if (!SWIG_init_user(module_ns)) {
376      delete module_ns;
377      module_ns=0;
378      return octave_value_list();
379    }
380
381    SWIG_InstallOps(octave_swig_ref::static_type_id());
382
383    octave_swig_type::swig_member_const_iterator mb;
384    for (mb = module_ns->swig_members_begin(); mb != module_ns->swig_members_end(); ++mb) {
385      if (mb->second.first && mb->second.first->method) {
386        if (!SWIG_Octave_InstallFunction(me, mb->first)) {
387          return octave_value_list();
388        }
389      }
390    }
391
392#if SWIG_OCTAVE_PREREQ(4,4,0)
393    octave::interpreter::the_interpreter()->mlock();
394#elif SWIG_OCTAVE_PREREQ(3,2,0)
395    mlock();
396#else
397    mlock(me->name());
398#endif
399
400  }
401
402  octave_swig_type::swig_member_const_iterator mb;
403  for (mb = module_ns->swig_members_begin(); mb != module_ns->swig_members_end(); ++mb) {
404    if (mb->second.second.is_defined()) {
405      SWIG_Octave_SetGlobalValue(mb->first, mb->second.second);
406      SWIG_Octave_LinkGlobalValue(mb->first);
407    }
408  }
409
410  SWIG_Octave_SetGlobalValue(SWIG_name_d, module_ns->as_value());
411  SWIG_Octave_LinkGlobalValue(SWIG_name_d);
412
413  return octave_value_list();
414
415}
416
417%}
418