/tags/rel-2.0.0/trunk/Source/Modules/octave.cxx

# · C++ · 1417 lines · 1175 code · 196 blank · 46 comment · 226 complexity · 2baeeaa1c9ca2a021a379530af8f2904 MD5 · raw file

  1. /* -----------------------------------------------------------------------------
  2. * This file is part of SWIG, which is licensed as a whole under version 3
  3. * (or any later version) of the GNU General Public License. Some additional
  4. * terms also apply to certain portions of SWIG. The full details of the SWIG
  5. * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6. * included with the SWIG source code as distributed by the SWIG developers
  7. * and at http://www.swig.org/legal.html.
  8. *
  9. * octave.cxx
  10. *
  11. * Octave language module for SWIG.
  12. * ----------------------------------------------------------------------------- */
  13. char cvsroot_octave_cxx[] = "$Id$";
  14. #include "swigmod.h"
  15. static const char *usage = (char *) "\
  16. Octave Options (available with -octave)\n\
  17. [no additional options]\n\
  18. \n";
  19. class OCTAVE:public Language {
  20. private:
  21. File *f_begin;
  22. File *f_runtime;
  23. File *f_header;
  24. File *f_doc;
  25. File *f_wrappers;
  26. File *f_init;
  27. File *f_initbeforefunc;
  28. File *f_directors;
  29. File *f_directors_h;
  30. String *s_global_tab;
  31. String *s_members_tab;
  32. String *class_name;
  33. int have_constructor;
  34. int have_destructor;
  35. String *constructor_name;
  36. Hash *docs;
  37. public:
  38. OCTAVE():f_begin(0), f_runtime(0), f_header(0), f_doc(0), f_wrappers(0),
  39. f_init(0), f_initbeforefunc(0), f_directors(0), f_directors_h(0),
  40. s_global_tab(0), s_members_tab(0), class_name(0) {
  41. /* Add code to manage protected constructors and directors */
  42. director_prot_ctor_code = NewString("");
  43. Printv(director_prot_ctor_code,
  44. "if ( $comparison ) { /* subclassed */\n",
  45. " $director_new \n",
  46. "} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
  47. enable_cplus_runtime_mode();
  48. allow_overloading();
  49. director_multiple_inheritance = 1;
  50. director_language = 1;
  51. docs = NewHash();
  52. }
  53. virtual void main(int argc, char *argv[]) {
  54. for (int i = 1; i < argc; i++) {
  55. if (argv[i]) {
  56. if (strcmp(argv[i], "-help") == 0) {
  57. fputs(usage, stderr);
  58. }
  59. }
  60. }
  61. SWIG_library_directory("octave");
  62. Preprocessor_define("SWIGOCTAVE 1", 0);
  63. SWIG_config_file("octave.swg");
  64. SWIG_typemap_lang("octave");
  65. allow_overloading();
  66. }
  67. virtual int top(Node *n) {
  68. {
  69. Node *mod = Getattr(n, "module");
  70. if (mod) {
  71. Node *options = Getattr(mod, "options");
  72. if (options) {
  73. int dirprot = 0;
  74. if (Getattr(options, "dirprot")) {
  75. dirprot = 1;
  76. }
  77. if (Getattr(options, "nodirprot")) {
  78. dirprot = 0;
  79. }
  80. if (Getattr(options, "directors")) {
  81. allow_directors();
  82. if (dirprot)
  83. allow_dirprot();
  84. }
  85. }
  86. }
  87. }
  88. String *module = Getattr(n, "name");
  89. String *outfile = Getattr(n, "outfile");
  90. f_begin = NewFile(outfile, "w", SWIG_output_files());
  91. if (!f_begin) {
  92. FileErrorDisplay(outfile);
  93. SWIG_exit(EXIT_FAILURE);
  94. }
  95. f_runtime = NewString("");
  96. f_header = NewString("");
  97. f_doc = NewString("");
  98. f_wrappers = NewString("");
  99. f_init = NewString("");
  100. f_initbeforefunc = NewString("");
  101. f_directors_h = NewString("");
  102. f_directors = NewString("");
  103. s_global_tab = NewString("");
  104. Swig_register_filebyname("begin", f_begin);
  105. Swig_register_filebyname("runtime", f_runtime);
  106. Swig_register_filebyname("header", f_header);
  107. Swig_register_filebyname("doc", f_doc);
  108. Swig_register_filebyname("wrapper", f_wrappers);
  109. Swig_register_filebyname("init", f_init);
  110. Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
  111. Swig_register_filebyname("director", f_directors);
  112. Swig_register_filebyname("director_h", f_directors_h);
  113. Swig_banner(f_begin);
  114. Printf(f_runtime, "\n");
  115. Printf(f_runtime, "#define SWIGOCTAVE\n");
  116. Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module);
  117. Printf(f_runtime, "#define SWIG_name %s\n", module);
  118. if (directorsEnabled()) {
  119. Printf(f_runtime, "#define SWIG_DIRECTORS\n");
  120. Swig_banner(f_directors_h);
  121. if (dirprot_mode()) {
  122. // Printf(f_directors_h, "#include <map>\n");
  123. // Printf(f_directors_h, "#include <string>\n\n");
  124. }
  125. }
  126. Printf(f_runtime, "\n");
  127. Printf(s_global_tab, "\nstatic const struct swig_octave_member swig_globals[] = {\n");
  128. Printf(f_init, "static void SWIG_init_user(octave_swig_type* module_ns)\n{\n");
  129. if (!CPlusPlus)
  130. Printf(f_header,"extern \"C\" {\n");
  131. Language::top(n);
  132. if (!CPlusPlus)
  133. Printf(f_header,"}\n");
  134. if (Len(docs))
  135. emit_doc_texinfo();
  136. if (directorsEnabled())
  137. Swig_insert_file("director.swg", f_runtime);
  138. Printf(f_init, "}\n");
  139. Printf(s_global_tab, "{0,0,0,0,0}\n};\n");
  140. Printv(f_wrappers, s_global_tab, NIL);
  141. SwigType_emit_type_table(f_runtime, f_wrappers);
  142. Dump(f_runtime, f_begin);
  143. Dump(f_header, f_begin);
  144. Dump(f_doc, f_begin);
  145. if (directorsEnabled()) {
  146. Dump(f_directors_h, f_begin);
  147. Dump(f_directors, f_begin);
  148. }
  149. Dump(f_wrappers, f_begin);
  150. Dump(f_initbeforefunc, f_begin);
  151. Wrapper_pretty_print(f_init, f_begin);
  152. Delete(s_global_tab);
  153. Delete(f_initbeforefunc);
  154. Delete(f_init);
  155. Delete(f_wrappers);
  156. Delete(f_doc);
  157. Delete(f_header);
  158. Delete(f_directors);
  159. Delete(f_directors_h);
  160. Close(f_begin);
  161. Delete(f_runtime);
  162. Delete(f_begin);
  163. return SWIG_OK;
  164. }
  165. String *texinfo_escape(String *_s) {
  166. const char* s=(const char*)Data(_s);
  167. while (*s&&(*s=='\t'||*s=='\r'||*s=='\n'||*s==' '))
  168. ++s;
  169. String *r = NewString("");
  170. for (int j=0;s[j];++j) {
  171. if (s[j] == '\n') {
  172. Append(r, "\\n\\\n");
  173. } else if (s[j] == '\r') {
  174. Append(r, "\\r");
  175. } else if (s[j] == '\t') {
  176. Append(r, "\\t");
  177. } else if (s[j] == '\\') {
  178. Append(r, "\\\\");
  179. } else if (s[j] == '\'') {
  180. Append(r, "\\\'");
  181. } else if (s[j] == '\"') {
  182. Append(r, "\\\"");
  183. } else
  184. Putc(s[j], r);
  185. }
  186. return r;
  187. }
  188. void emit_doc_texinfo() {
  189. for (Iterator it = First(docs); it.key; it = Next(it)) {
  190. String *wrap_name = it.key;
  191. String *synopsis = Getattr(it.item, "synopsis");
  192. String *decl_info = Getattr(it.item, "decl_info");
  193. String *cdecl_info = Getattr(it.item, "cdecl_info");
  194. String *args_info = Getattr(it.item, "args_info");
  195. String *doc_str = NewString("");
  196. Printv(doc_str, synopsis, decl_info, cdecl_info, args_info, NIL);
  197. String *escaped_doc_str = texinfo_escape(doc_str);
  198. if (Len(doc_str)>0) {
  199. Printf(f_doc,"const char* %s_texinfo = ",wrap_name);
  200. Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str);
  201. if (Len(decl_info))
  202. Printf(f_doc,"\\n\\\n@end deftypefn");
  203. Printf(f_doc,"\";\n");
  204. }
  205. Delete(escaped_doc_str);
  206. Delete(doc_str);
  207. Delete(wrap_name);
  208. }
  209. Printf(f_doc,"\n");
  210. }
  211. bool is_empty_doc_node(Node* n) {
  212. if (!n)
  213. return true;
  214. String *synopsis = Getattr(n, "synopsis");
  215. String *decl_info = Getattr(n, "decl_info");
  216. String *cdecl_info = Getattr(n, "cdecl_info");
  217. String *args_info = Getattr(n, "args_info");
  218. return !Len(synopsis) && !Len(decl_info) &&
  219. !Len(cdecl_info) && !Len(args_info);
  220. }
  221. String *texinfo_name(Node* n) {
  222. String *tname = NewString("");
  223. String *iname = Getattr(n, "sym:name");
  224. String *wname = Swig_name_wrapper(iname);
  225. Node* d = Getattr(docs, wname);
  226. if (is_empty_doc_node(d))
  227. Printf(tname, "0");
  228. else
  229. Printf(tname, "%s_texinfo", wname);
  230. return tname;
  231. }
  232. void process_autodoc(Node *n) {
  233. String *iname = Getattr(n, "sym:name");
  234. String *name = Getattr(n, "name");
  235. String *wname = Swig_name_wrapper(iname);
  236. String *str = Getattr(n, "feature:docstring");
  237. bool autodoc_enabled = !Cmp(Getattr(n, "feature:autodoc"), "1");
  238. Node* d = Getattr(docs, wname);
  239. if (!d) {
  240. d = NewHash();
  241. Setattr(d, "synopsis", NewString(""));
  242. Setattr(d, "decl_info", NewString(""));
  243. Setattr(d, "cdecl_info", NewString(""));
  244. Setattr(d, "args_info", NewString(""));
  245. Setattr(docs, wname, d);
  246. }
  247. String *synopsis = Getattr(d, "synopsis");
  248. String *decl_info = Getattr(d, "decl_info");
  249. // String *cdecl_info = Getattr(d, "cdecl_info");
  250. String *args_info = Getattr(d, "args_info");
  251. // * couldn't we just emit the docs here?
  252. if (autodoc_enabled) {
  253. String *decl_str = NewString("");
  254. String *args_str = NewString("");
  255. make_autodocParmList(n, decl_str, args_str);
  256. Append(decl_info, "@deftypefn {Loadable Function} ");
  257. SwigType *type = Getattr(n, "type");
  258. if (type && Strcmp(type, "void")) {
  259. type = SwigType_base(type);
  260. Node *lookup = Swig_symbol_clookup(type, 0);
  261. if (lookup)
  262. type = Getattr(lookup, "sym:name");
  263. Append(decl_info, "@var{retval} = ");
  264. String *type_str = NewString("");
  265. Printf(type_str, "@var{retval} is of type %s. ", type);
  266. Append(args_str, type_str);
  267. Delete(type_str);
  268. }
  269. Append(decl_info, name);
  270. Append(decl_info, " (");
  271. Append(decl_info, decl_str);
  272. Append(decl_info, ")\n");
  273. Append(args_info, args_str);
  274. Delete(decl_str);
  275. Delete(args_str);
  276. }
  277. if (str && Len(str) > 0) {
  278. // strip off {} if necessary
  279. char *t = Char(str);
  280. if (*t == '{') {
  281. Delitem(str, 0);
  282. Delitem(str, DOH_END);
  283. }
  284. // emit into synopsis section
  285. Append(synopsis, str);
  286. }
  287. }
  288. virtual int importDirective(Node *n) {
  289. String *modname = Getattr(n, "module");
  290. if (modname)
  291. Printf(f_init, "feval(\"%s\",octave_value_list(),0);\n", modname);
  292. return Language::importDirective(n);
  293. }
  294. const char *get_implicitconv_flag(Node *n) {
  295. int conv = 0;
  296. if (n && GetFlag(n, "feature:implicitconv")) {
  297. conv = 1;
  298. }
  299. return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0";
  300. }
  301. void make_autodocParmList(Node *n, String *decl_str, String *args_str) {
  302. String *pdocs = Copy(Getattr(n, "feature:pdocs"));
  303. ParmList *plist = CopyParmList(Getattr(n, "parms"));
  304. Parm *p;
  305. Parm *pnext;
  306. Node *lookup;
  307. if (pdocs)
  308. Append(pdocs, "\n");
  309. Swig_typemap_attach_parms("in", plist, 0);
  310. Swig_typemap_attach_parms("doc", plist, 0);
  311. for (p = plist; p; p = pnext) {
  312. String *name = 0;
  313. String *type = 0;
  314. String *value = 0;
  315. String *ptype = 0;
  316. String *pdoc = Getattr(p, "tmap:doc");
  317. if (pdoc) {
  318. name = Getattr(p, "tmap:doc:name");
  319. type = Getattr(p, "tmap:doc:type");
  320. value = Getattr(p, "tmap:doc:value");
  321. ptype = Getattr(p, "tmap:doc:pytype");
  322. }
  323. name = name ? name : Getattr(p, "name");
  324. type = type ? type : Getattr(p, "type");
  325. value = value ? value : Getattr(p, "value");
  326. String *tex_name = NewString("");
  327. if (name)
  328. Printf(tex_name, "@var{%s}", name);
  329. else
  330. Printf(tex_name, "@var{?}");
  331. String *tm = Getattr(p, "tmap:in");
  332. if (tm) {
  333. pnext = Getattr(p, "tmap:in:next");
  334. } else {
  335. pnext = nextSibling(p);
  336. }
  337. if (Len(decl_str))
  338. Append(decl_str, ", ");
  339. Append(decl_str, tex_name);
  340. if (value) {
  341. if (Strcmp(value, "NULL") == 0)
  342. value = NewString("nil");
  343. else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
  344. value = NewString("true");
  345. else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
  346. value = NewString("false");
  347. else {
  348. lookup = Swig_symbol_clookup(value, 0);
  349. if (lookup)
  350. value = Getattr(lookup, "sym:name");
  351. }
  352. Printf(decl_str, " = %s", value);
  353. }
  354. if (type) {
  355. String *type_str = NewString("");
  356. type = SwigType_base(type);
  357. lookup = Swig_symbol_clookup(type, 0);
  358. if (lookup)
  359. type = Getattr(lookup, "sym:name");
  360. Printf(type_str, "%s is of type %s. ", tex_name, type);
  361. Append(args_str, type_str);
  362. Delete(type_str);
  363. }
  364. Delete(tex_name);
  365. }
  366. if (pdocs)
  367. Setattr(n, "feature:pdocs", pdocs);
  368. Delete(plist);
  369. }
  370. virtual int functionWrapper(Node *n) {
  371. Wrapper *f = NewWrapper();
  372. Parm *p;
  373. String *tm;
  374. int j;
  375. String *nodeType = Getattr(n, "nodeType");
  376. int constructor = (!Cmp(nodeType, "constructor"));
  377. int destructor = (!Cmp(nodeType, "destructor"));
  378. String *storage = Getattr(n, "storage");
  379. bool overloaded = !!Getattr(n, "sym:overloaded");
  380. bool last_overload = overloaded && !Getattr(n, "sym:nextSibling");
  381. String *iname = Getattr(n, "sym:name");
  382. String *wname = Swig_name_wrapper(iname);
  383. String *overname = Copy(wname);
  384. SwigType *d = Getattr(n, "type");
  385. ParmList *l = Getattr(n, "parms");
  386. if (!overloaded && !addSymbol(iname, n))
  387. return SWIG_ERROR;
  388. if (overloaded)
  389. Append(overname, Getattr(n, "sym:overname"));
  390. Printv(f->def, "static octave_value_list ", overname, " (const octave_value_list& args, int nargout) {", NIL);
  391. emit_parameter_variables(l, f);
  392. emit_attach_parmmaps(l, f);
  393. Setattr(n, "wrap:parms", l);
  394. int num_arguments = emit_num_arguments(l);
  395. int num_required = emit_num_required(l);
  396. int varargs = emit_isvarargs(l);
  397. char source[64];
  398. Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) "
  399. "{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs);
  400. if (constructor && num_arguments == 1 && num_required == 1) {
  401. if (Cmp(storage, "explicit") == 0) {
  402. Node *parent = Swig_methodclass(n);
  403. if (GetFlag(parent, "feature:implicitconv")) {
  404. String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
  405. Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
  406. Delete(desc);
  407. }
  408. }
  409. }
  410. for (j = 0, p = l; j < num_arguments; ++j) {
  411. while (checkAttribute(p, "tmap:in:numinputs", "0")) {
  412. p = Getattr(p, "tmap:in:next");
  413. }
  414. SwigType *pt = Getattr(p, "type");
  415. String *tm = Getattr(p, "tmap:in");
  416. if (tm) {
  417. if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) {
  418. p = nextSibling(p);
  419. continue;
  420. }
  421. sprintf(source, "args(%d)", j);
  422. Setattr(p, "emit:input", source);
  423. Replaceall(tm, "$source", Getattr(p, "emit:input"));
  424. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  425. Replaceall(tm, "$target", Getattr(p, "lname"));
  426. if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
  427. Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
  428. } else {
  429. Replaceall(tm, "$disown", "0");
  430. }
  431. if (Getattr(p, "tmap:in:implicitconv")) {
  432. const char *convflag = "0";
  433. if (!Getattr(p, "hidden")) {
  434. SwigType *ptype = Getattr(p, "type");
  435. convflag = get_implicitconv_flag(classLookup(ptype));
  436. }
  437. Replaceall(tm, "$implicitconv", convflag);
  438. Setattr(p, "implicitconv", convflag);
  439. }
  440. String *getargs = NewString("");
  441. if (j >= num_required)
  442. Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm);
  443. else
  444. Printv(getargs, tm, NIL);
  445. Printv(f->code, getargs, "\n", NIL);
  446. Delete(getargs);
  447. p = Getattr(p, "tmap:in:next");
  448. continue;
  449. } else {
  450. Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
  451. break;
  452. }
  453. }
  454. // Check for trailing varargs
  455. if (varargs) {
  456. if (p && (tm = Getattr(p, "tmap:in"))) {
  457. Replaceall(tm, "$input", "varargs");
  458. Printv(f->code, tm, "\n", NIL);
  459. }
  460. }
  461. // Insert constraint checking code
  462. for (p = l; p;) {
  463. if ((tm = Getattr(p, "tmap:check"))) {
  464. Replaceall(tm, "$target", Getattr(p, "lname"));
  465. Printv(f->code, tm, "\n", NIL);
  466. p = Getattr(p, "tmap:check:next");
  467. } else {
  468. p = nextSibling(p);
  469. }
  470. }
  471. // Insert cleanup code
  472. String *cleanup = NewString("");
  473. for (p = l; p;) {
  474. if ((tm = Getattr(p, "tmap:freearg"))) {
  475. if (Getattr(p, "tmap:freearg:implicitconv")) {
  476. const char *convflag = "0";
  477. if (!Getattr(p, "hidden")) {
  478. SwigType *ptype = Getattr(p, "type");
  479. convflag = get_implicitconv_flag(classLookup(ptype));
  480. }
  481. if (strcmp(convflag, "0") == 0) {
  482. tm = 0;
  483. }
  484. }
  485. if (tm && (Len(tm) != 0)) {
  486. Replaceall(tm, "$source", Getattr(p, "lname"));
  487. Printv(cleanup, tm, "\n", NIL);
  488. }
  489. p = Getattr(p, "tmap:freearg:next");
  490. } else {
  491. p = nextSibling(p);
  492. }
  493. }
  494. // Insert argument output code
  495. String *outarg = NewString("");
  496. for (p = l; p;) {
  497. if ((tm = Getattr(p, "tmap:argout"))) {
  498. Replaceall(tm, "$source", Getattr(p, "lname"));
  499. Replaceall(tm, "$target", "_outp");
  500. Replaceall(tm, "$result", "_outp");
  501. Replaceall(tm, "$arg", Getattr(p, "emit:input"));
  502. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  503. Printv(outarg, tm, "\n", NIL);
  504. p = Getattr(p, "tmap:argout:next");
  505. } else {
  506. p = nextSibling(p);
  507. }
  508. }
  509. int director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
  510. if (director_method) {
  511. Wrapper_add_local(f, "upcall", "bool upcall = false");
  512. Append(f->code, "upcall = !!dynamic_cast<Swig::Director*>(arg1);\n");
  513. }
  514. Setattr(n, "wrap:name", overname);
  515. Swig_director_emit_dynamic_cast(n, f);
  516. String *actioncode = emit_action(n);
  517. Wrapper_add_local(f, "_out", "octave_value_list _out");
  518. Wrapper_add_local(f, "_outp", "octave_value_list *_outp=&_out");
  519. Wrapper_add_local(f, "_outv", "octave_value _outv");
  520. // Return the function value
  521. if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
  522. Replaceall(tm, "$source", "result");
  523. Replaceall(tm, "$target", "_outv");
  524. Replaceall(tm, "$result", "_outv");
  525. if (GetFlag(n, "feature:new"))
  526. Replaceall(tm, "$owner", "1");
  527. else
  528. Replaceall(tm, "$owner", "0");
  529. Printf(f->code, "%s\n", tm);
  530. Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n");
  531. Delete(tm);
  532. } else {
  533. Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), iname);
  534. }
  535. emit_return_variable(n, d, f);
  536. Printv(f->code, outarg, NIL);
  537. Printv(f->code, cleanup, NIL);
  538. if (GetFlag(n, "feature:new")) {
  539. if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
  540. Replaceall(tm, "$source", "result");
  541. Printf(f->code, "%s\n", tm);
  542. }
  543. }
  544. if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
  545. Replaceall(tm, "$source", "result");
  546. Replaceall(tm, "$result", "_outv");
  547. Printf(f->code, "%s\n", tm);
  548. Delete(tm);
  549. }
  550. Printf(f->code, "fail:\n"); // we should free locals etc if this happens
  551. Printf(f->code, "return _out;\n");
  552. Printf(f->code, "}\n");
  553. Replaceall(f->code, "$symname", iname);
  554. Wrapper_print(f, f_wrappers);
  555. DelWrapper(f);
  556. if (last_overload)
  557. dispatchFunction(n);
  558. if (!overloaded || last_overload) {
  559. process_autodoc(n);
  560. String *tname = texinfo_name(n);
  561. Printf(s_global_tab, "{\"%s\",%s,0,0,2,%s},\n", iname, wname, tname);
  562. Delete(tname);
  563. }
  564. Delete(overname);
  565. Delete(wname);
  566. Delete(cleanup);
  567. Delete(outarg);
  568. return SWIG_OK;
  569. }
  570. void dispatchFunction(Node *n) {
  571. Wrapper *f = NewWrapper();
  572. String *iname = Getattr(n, "sym:name");
  573. String *wname = Swig_name_wrapper(iname);
  574. int maxargs;
  575. String *dispatch = Swig_overload_dispatch(n, "return %s(args, nargout);", &maxargs);
  576. String *tmp = NewString("");
  577. Printv(f->def, "static octave_value_list ", wname, " (const octave_value_list& args, int nargout) {", NIL);
  578. Wrapper_add_local(f, "argc", "int argc = args.length()");
  579. Printf(tmp, "octave_value_ref argv[%d]={", maxargs);
  580. for (int j = 0; j < maxargs; ++j)
  581. Printf(tmp, "%soctave_value_ref(args,%d)", j ? "," : " ", j);
  582. Printf(tmp, "}");
  583. Wrapper_add_local(f, "argv", tmp);
  584. Printv(f->code, dispatch, "\n", NIL);
  585. Printf(f->code, "error(\"No matching function for overload\");\n", iname);
  586. Printf(f->code, "return octave_value_list();\n");
  587. Printv(f->code, "}\n", NIL);
  588. Wrapper_print(f, f_wrappers);
  589. Delete(tmp);
  590. DelWrapper(f);
  591. Delete(dispatch);
  592. Delete(wname);
  593. }
  594. virtual int variableWrapper(Node *n) {
  595. String *name = Getattr(n, "name");
  596. String *iname = Getattr(n, "sym:name");
  597. SwigType *t = Getattr(n, "type");
  598. if (!addSymbol(iname, n))
  599. return SWIG_ERROR;
  600. String *tm;
  601. Wrapper *getf = NewWrapper();
  602. Wrapper *setf = NewWrapper();
  603. String *getname = Swig_name_get(NSPACE_TODO, iname);
  604. String *setname = Swig_name_set(NSPACE_TODO, iname);
  605. Printf(setf->def, "static octave_value_list _wrap_%s(const octave_value_list& args,int nargout) {", setname);
  606. Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
  607. if (is_assignable(n)) {
  608. Setattr(n, "wrap:name", setname);
  609. if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
  610. Replaceall(tm, "$source", "args(0)");
  611. Replaceall(tm, "$target", name);
  612. Replaceall(tm, "$input", "args(0)");
  613. if (Getattr(n, "tmap:varin:implicitconv")) {
  614. Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
  615. }
  616. emit_action_code(n, setf->code, tm);
  617. Delete(tm);
  618. } else {
  619. Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
  620. }
  621. Append(setf->code, "fail:\n");
  622. Printf(setf->code, "return octave_value_list();\n");
  623. } else {
  624. Printf(setf->code, "return octave_set_immutable(args,nargout);");
  625. }
  626. Append(setf->code, "}\n");
  627. Wrapper_print(setf, f_wrappers);
  628. Setattr(n, "wrap:name", getname);
  629. int addfail = 0;
  630. Printf(getf->def, "static octave_value_list _wrap_%s(const octave_value_list& args,int nargout) {", getname);
  631. Wrapper_add_local(getf, "obj", "octave_value obj");
  632. if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
  633. Replaceall(tm, "$source", name);
  634. Replaceall(tm, "$target", "obj");
  635. Replaceall(tm, "$result", "obj");
  636. addfail = emit_action_code(n, getf->code, tm);
  637. Delete(tm);
  638. } else {
  639. Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
  640. }
  641. Append(getf->code, " return obj;\n");
  642. if (addfail) {
  643. Append(getf->code, "fail:\n");
  644. Append(getf->code, " return octave_value_list();\n");
  645. }
  646. Append(getf->code, "}\n");
  647. Wrapper_print(getf, f_wrappers);
  648. Printf(s_global_tab, "{\"%s\",0,_wrap_%s,_wrap_%s,2,0},\n", iname, getname, setname);
  649. return SWIG_OK;
  650. }
  651. virtual int constantWrapper(Node *n) {
  652. String *name = Getattr(n, "name");
  653. String *iname = Getattr(n, "sym:name");
  654. SwigType *type = Getattr(n, "type");
  655. String *rawval = Getattr(n, "rawval");
  656. String *value = rawval ? rawval : Getattr(n, "value");
  657. String *cppvalue = Getattr(n, "cppvalue");
  658. String *tm;
  659. if (!addSymbol(iname, n))
  660. return SWIG_ERROR;
  661. if (SwigType_type(type) == T_MPOINTER) {
  662. String *wname = Swig_name_wrapper(iname);
  663. String *str = SwigType_str(type, wname);
  664. Printf(f_header, "static %s = %s;\n", str, value);
  665. Delete(str);
  666. value = wname;
  667. }
  668. if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
  669. Replaceall(tm, "$source", value);
  670. Replaceall(tm, "$target", name);
  671. Replaceall(tm, "$value", cppvalue ? cppvalue : value);
  672. Replaceall(tm, "$nsname", iname);
  673. Printf(f_init, "%s\n", tm);
  674. } else {
  675. Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
  676. return SWIG_NOWRAP;
  677. }
  678. return SWIG_OK;
  679. }
  680. virtual int nativeWrapper(Node *n) {
  681. return Language::nativeWrapper(n);
  682. }
  683. virtual int enumDeclaration(Node *n) {
  684. return Language::enumDeclaration(n);
  685. }
  686. virtual int enumvalueDeclaration(Node *n) {
  687. return Language::enumvalueDeclaration(n);
  688. }
  689. virtual int classDeclaration(Node *n) {
  690. return Language::classDeclaration(n);
  691. }
  692. virtual int classHandler(Node *n) {
  693. have_constructor = 0;
  694. have_destructor = 0;
  695. constructor_name = 0;
  696. class_name = Getattr(n, "sym:name");
  697. if (!addSymbol(class_name, n))
  698. return SWIG_ERROR;
  699. // This is a bug, due to the fact that swig_type -> octave_class mapping
  700. // is 1-to-n.
  701. static Hash *emitted = NewHash();
  702. String *mangled_classname = Swig_name_mangle(Getattr(n, "name"));
  703. if (Getattr(emitted, mangled_classname)) {
  704. Delete(mangled_classname);
  705. return SWIG_NOWRAP;
  706. }
  707. Setattr(emitted, mangled_classname, "1");
  708. Delete(mangled_classname);
  709. assert(!s_members_tab);
  710. s_members_tab = NewString("");
  711. Printv(s_members_tab, "static swig_octave_member swig_", class_name, "_members[] = {\n", NIL);
  712. Language::classHandler(n);
  713. SwigType *t = Copy(Getattr(n, "name"));
  714. SwigType_add_pointer(t);
  715. String *wrap_class = NewStringf("&_wrap_class_%s", class_name);
  716. SwigType_remember_clientdata(t, wrap_class);
  717. int use_director = Swig_directorclass(n);
  718. if (use_director) {
  719. String *disown_shadow = NewString("");
  720. Printf(disown_shadow, "static octave_value_list _wrap_disown_%s_shadow " "(const octave_value_list& args, int nargout) {\n", class_name);
  721. Printf(disown_shadow, " if (args.length()!=1) {\n");
  722. Printf(disown_shadow, " error(\"disown takes no arguments\");\n");
  723. Printf(disown_shadow, " return octave_value_list();\n");
  724. Printf(disown_shadow, " }\n");
  725. Printf(disown_shadow, " _wrap_disown_%s (args, nargout);\n", class_name);
  726. Printf(disown_shadow, " return args;\n");
  727. Printf(disown_shadow, "}\n");
  728. Printv(f_wrappers, disown_shadow, NIL);
  729. Delete(disown_shadow);
  730. Printf(s_members_tab, "{\"__disown\",_wrap_disown_%s_shadow,0,0,0,0},\n", class_name);
  731. }
  732. Printf(s_members_tab, "{0,0,0,0}\n};\n");
  733. Printv(f_wrappers, s_members_tab, NIL);
  734. String *base_class_names = NewString("");
  735. String *base_class = NewString("");
  736. List *baselist = Getattr(n, "bases");
  737. if (baselist && Len(baselist)) {
  738. Iterator b;
  739. int index = 0;
  740. b = First(baselist);
  741. while (b.item) {
  742. String *bname = Getattr(b.item, "name");
  743. if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
  744. b = Next(b);
  745. continue;
  746. }
  747. String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname)));
  748. Printf(base_class_names, "\"%s\",", bname_mangled);
  749. Printf(base_class, "0,");
  750. b = Next(b);
  751. index++;
  752. Delete(bname_mangled);
  753. }
  754. }
  755. Printv(f_wrappers, "static const char *swig_", class_name, "_base_names[] = {", base_class_names, "0};\n", NIL);
  756. Printv(f_wrappers, "static const swig_type_info *swig_", class_name, "_base[] = {", base_class, "0};\n", NIL);
  757. Printv(f_wrappers, "static swig_octave_class _wrap_class_", class_name, " = {\"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
  758. Printv(f_wrappers, Swig_directorclass(n) ? "1," : "0,", NIL);
  759. if (have_constructor) {
  760. String *cname = Swig_name_construct(NSPACE_TODO, constructor_name);
  761. String *wcname = Swig_name_wrapper(cname);
  762. String *tname = texinfo_name(n);
  763. Printf(f_wrappers, "%s,%s,", wcname, tname);
  764. Delete(tname);
  765. Delete(wcname);
  766. Delete(cname);
  767. } else
  768. Printv(f_wrappers, "0,0,", NIL);
  769. if (have_destructor)
  770. Printv(f_wrappers, "_wrap_delete_", class_name, ",", NIL);
  771. else
  772. Printv(f_wrappers, "0", ",", NIL);
  773. Printf(f_wrappers, "swig_%s_members,swig_%s_base_names,swig_%s_base };\n\n", class_name, class_name, class_name);
  774. Delete(base_class);
  775. Delete(base_class_names);
  776. Delete(t);
  777. Delete(s_members_tab);
  778. s_members_tab = 0;
  779. class_name = 0;
  780. return SWIG_OK;
  781. }
  782. virtual int memberfunctionHandler(Node *n) {
  783. Language::memberfunctionHandler(n);
  784. assert(s_members_tab);
  785. assert(class_name);
  786. String *name = Getattr(n, "name");
  787. String *iname = GetChar(n, "sym:name");
  788. String *realname = iname ? iname : name;
  789. String *rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname));
  790. if (!Getattr(n, "sym:nextSibling")) {
  791. String *tname = texinfo_name(n);
  792. Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n",
  793. realname, rname, tname);
  794. Delete(tname);
  795. }
  796. Delete(rname);
  797. return SWIG_OK;
  798. }
  799. virtual int membervariableHandler(Node *n) {
  800. Setattr(n, "feature:autodoc", "0");
  801. Language::membervariableHandler(n);
  802. assert(s_members_tab);
  803. assert(class_name);
  804. String *symname = Getattr(n, "sym:name");
  805. String *getname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
  806. String *setname = GetFlag(n, "feature:immutable") ?
  807. NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
  808. assert(s_members_tab);
  809. Printf(s_members_tab, "{\"%s\",0,%s,%s,0,0},\n", symname, getname, setname);
  810. Delete(getname);
  811. Delete(setname);
  812. return SWIG_OK;
  813. }
  814. virtual int constructorHandler(Node *n) {
  815. have_constructor = 1;
  816. if (!constructor_name)
  817. constructor_name = NewString(Getattr(n, "sym:name"));
  818. int use_director = Swig_directorclass(n);
  819. if (use_director) {
  820. Parm *parms = Getattr(n, "parms");
  821. Parm *self;
  822. String *name = NewString("self");
  823. String *type = NewString("void");
  824. SwigType_add_pointer(type);
  825. self = NewParm(type, name, n);
  826. Delete(type);
  827. Delete(name);
  828. Setattr(self, "lname", "self_obj");
  829. if (parms)
  830. set_nextSibling(self, parms);
  831. Setattr(n, "parms", self);
  832. Setattr(n, "wrap:self", "1");
  833. Setattr(n, "hidden", "1");
  834. Delete(self);
  835. }
  836. return Language::constructorHandler(n);
  837. }
  838. virtual int destructorHandler(Node *n) {
  839. have_destructor = 1;
  840. return Language::destructorHandler(n);
  841. }
  842. virtual int staticmemberfunctionHandler(Node *n) {
  843. Language::staticmemberfunctionHandler(n);
  844. assert(s_members_tab);
  845. assert(class_name);
  846. String *name = Getattr(n, "name");
  847. String *iname = GetChar(n, "sym:name");
  848. String *realname = iname ? iname : name;
  849. String *rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname));
  850. if (!Getattr(n, "sym:nextSibling")) {
  851. String *tname = texinfo_name(n);
  852. Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n",
  853. realname, rname, tname);
  854. Delete(tname);
  855. }
  856. Delete(rname);
  857. return SWIG_OK;
  858. }
  859. virtual int memberconstantHandler(Node *n) {
  860. return Language::memberconstantHandler(n);
  861. }
  862. virtual int staticmembervariableHandler(Node *n) {
  863. Setattr(n, "feature:autodoc", "0");
  864. Language::staticmembervariableHandler(n);
  865. if (!GetFlag(n, "wrappedasconstant")) {
  866. assert(s_members_tab);
  867. assert(class_name);
  868. String *symname = Getattr(n, "sym:name");
  869. String *getname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
  870. String *setname = GetFlag(n, "feature:immutable") ?
  871. NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
  872. assert(s_members_tab);
  873. Printf(s_members_tab, "{\"%s\",0,%s,%s,1,0},\n", symname, getname, setname);
  874. Delete(getname);
  875. Delete(setname);
  876. }
  877. return SWIG_OK;
  878. }
  879. int classDirectorInit(Node *n) {
  880. String *declaration = Swig_director_declaration(n);
  881. Printf(f_directors_h, "\n");
  882. Printf(f_directors_h, "%s\n", declaration);
  883. Printf(f_directors_h, "public:\n");
  884. Delete(declaration);
  885. return Language::classDirectorInit(n);
  886. }
  887. int classDirectorEnd(Node *n) {
  888. Printf(f_directors_h, "};\n\n");
  889. return Language::classDirectorEnd(n);
  890. }
  891. int classDirectorConstructor(Node *n) {
  892. Node *parent = Getattr(n, "parentNode");
  893. String *sub = NewString("");
  894. String *decl = Getattr(n, "decl");
  895. String *supername = Swig_class_name(parent);
  896. String *classname = NewString("");
  897. Printf(classname, "SwigDirector_%s", supername);
  898. // insert self parameter
  899. Parm *p;
  900. ParmList *superparms = Getattr(n, "parms");
  901. ParmList *parms = CopyParmList(superparms);
  902. String *type = NewString("void");
  903. SwigType_add_pointer(type);
  904. p = NewParm(type, NewString("self"), n);
  905. set_nextSibling(p, parms);
  906. parms = p;
  907. if (!Getattr(n, "defaultargs")) {
  908. // constructor
  909. {
  910. Wrapper *w = NewWrapper();
  911. String *call;
  912. String *basetype = Getattr(parent, "classtype");
  913. String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
  914. call = Swig_csuperclass_call(0, basetype, superparms);
  915. Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
  916. Append(w->def, "}\n");
  917. Delete(target);
  918. Wrapper_print(w, f_directors);
  919. Delete(call);
  920. DelWrapper(w);
  921. }
  922. // constructor header
  923. {
  924. String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
  925. Printf(f_directors_h, " %s;\n", target);
  926. Delete(target);
  927. }
  928. }
  929. Delete(sub);
  930. Delete(classname);
  931. Delete(supername);
  932. Delete(parms);
  933. return Language::classDirectorConstructor(n);
  934. }
  935. int classDirectorDefaultConstructor(Node *n) {
  936. String *classname = Swig_class_name(n);
  937. {
  938. Wrapper *w = NewWrapper();
  939. Printf(w->def, "SwigDirector_%s::SwigDirector_%s(void* self) :"
  940. "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname);
  941. Append(w->def, "}\n");
  942. Wrapper_print(w, f_directors);
  943. DelWrapper(w);
  944. }
  945. Printf(f_directors_h, " SwigDirector_%s(octave_swig_type* self);\n", classname);
  946. Delete(classname);
  947. return Language::classDirectorDefaultConstructor(n);
  948. }
  949. int classDirectorMethod(Node *n, Node *parent, String *super) {
  950. int is_void = 0;
  951. int is_pointer = 0;
  952. String *decl;
  953. String *type;
  954. String *name;
  955. String *classname;
  956. String *c_classname = Getattr(parent, "name");
  957. String *declaration;
  958. ParmList *l;
  959. Wrapper *w;
  960. String *tm;
  961. String *wrap_args = NewString("");
  962. String *return_type;
  963. String *value = Getattr(n, "value");
  964. String *storage = Getattr(n, "storage");
  965. bool pure_virtual = false;
  966. int status = SWIG_OK;
  967. int idx;
  968. bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
  969. if (Cmp(storage, "virtual") == 0) {
  970. if (Cmp(value, "0") == 0) {
  971. pure_virtual = true;
  972. }
  973. }
  974. classname = Getattr(parent, "sym:name");
  975. type = Getattr(n, "type");
  976. name = Getattr(n, "name");
  977. w = NewWrapper();
  978. declaration = NewString("");
  979. // determine if the method returns a pointer
  980. decl = Getattr(n, "decl");
  981. is_pointer = SwigType_ispointer_return(decl);
  982. is_void = (!Cmp(type, "void") && !is_pointer);
  983. // form complete return type
  984. return_type = Copy(type);
  985. {
  986. SwigType *t = Copy(decl);
  987. SwigType *f = 0;
  988. f = SwigType_pop_function(t);
  989. SwigType_push(return_type, t);
  990. Delete(f);
  991. Delete(t);
  992. }
  993. // virtual method definition
  994. l = Getattr(n, "parms");
  995. String *target;
  996. String *pclassname = NewStringf("SwigDirector_%s", classname);
  997. String *qualified_name = NewStringf("%s::%s", pclassname, name);
  998. SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
  999. target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
  1000. Printf(w->def, "%s", target);
  1001. Delete(qualified_name);
  1002. Delete(target);
  1003. // header declaration
  1004. target = Swig_method_decl(rtype, decl, name, l, 0, 1);
  1005. Printf(declaration, " virtual %s", target);
  1006. Delete(target);
  1007. // Get any exception classes in the throws typemap
  1008. ParmList *throw_parm_list = 0;
  1009. if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
  1010. Parm *p;
  1011. int gencomma = 0;
  1012. Append(w->def, " throw(");
  1013. Append(declaration, " throw(");
  1014. if (throw_parm_list)
  1015. Swig_typemap_attach_parms("throws", throw_parm_list, 0);
  1016. for (p = throw_parm_list; p; p = nextSibling(p)) {
  1017. if ((tm = Getattr(p, "tmap:throws"))) {
  1018. if (gencomma++) {
  1019. Append(w->def, ", ");
  1020. Append(declaration, ", ");
  1021. }
  1022. String *str = SwigType_str(Getattr(p, "type"), 0);
  1023. Append(w->def, str);
  1024. Append(declaration, str);
  1025. Delete(str);
  1026. }
  1027. }
  1028. Append(w->def, ")");
  1029. Append(declaration, ")");
  1030. }
  1031. Append(w->def, " {");
  1032. Append(declaration, ";\n");
  1033. // declare method return value
  1034. // if the return value is a reference or const reference, a specialized typemap must
  1035. // handle it, including declaration of c_result ($result).
  1036. if (!is_void) {
  1037. if (!(ignored_method && !pure_virtual)) {
  1038. String *cres = SwigType_lstr(return_type, "c_result");
  1039. Printf(w->code, "%s;\n", cres);
  1040. Delete(cres);
  1041. }
  1042. }
  1043. if (ignored_method) {
  1044. if (!pure_virtual) {
  1045. if (!is_void)
  1046. Printf(w->code, "return ");
  1047. String *super_call = Swig_method_call(super, l);
  1048. Printf(w->code, "%s;\n", super_call);
  1049. Delete(super_call);
  1050. } else {
  1051. Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
  1052. SwigType_namestr(name));
  1053. }
  1054. } else {
  1055. // attach typemaps to arguments (C/C++ -> Python)
  1056. String *parse_args = NewString("");
  1057. Swig_typemap_attach_parms("in", l, 0);
  1058. Swig_typemap_attach_parms("directorin", l, 0);
  1059. Swig_typemap_attach_parms("directorargout", l, w);
  1060. Parm *p;
  1061. int outputs = 0;
  1062. if (!is_void)
  1063. outputs++;
  1064. // build argument list and type conversion string
  1065. idx = 0;
  1066. p = l;
  1067. int use_parse = 0;
  1068. while (p != NULL) {
  1069. if (checkAttribute(p, "tmap:in:numinputs", "0")) {
  1070. p = Getattr(p, "tmap:in:next");
  1071. continue;
  1072. }
  1073. if (Getattr(p, "tmap:directorargout") != 0)
  1074. outputs++;
  1075. String *pname = Getattr(p, "name");
  1076. String *ptype = Getattr(p, "type");
  1077. Wrapper_add_local(w, "tmpv", "octave_value tmpv");
  1078. if ((tm = Getattr(p, "tmap:directorin")) != 0) {
  1079. String *parse = Getattr(p, "tmap:directorin:parse");
  1080. if (!parse) {
  1081. Replaceall(tm, "$input", "tmpv");
  1082. Replaceall(tm, "$owner", "0");
  1083. Printv(wrap_args, tm, "\n", NIL);
  1084. Printf(wrap_args, "args.append(tmpv);\n");
  1085. Putc('O', parse_args);
  1086. } else {
  1087. use_parse = 1;
  1088. Append(parse_args, parse);
  1089. Replaceall(tm, "$input", pname);
  1090. Replaceall(tm, "$owner", "0");
  1091. if (Len(tm) == 0)
  1092. Append(tm, pname);
  1093. }
  1094. p = Getattr(p, "tmap:directorin:next");
  1095. continue;
  1096. } else if (Cmp(ptype, "void")) {
  1097. Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
  1098. "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
  1099. SwigType_namestr(c_classname), SwigType_namestr(name));
  1100. status = SWIG_NOWRAP;
  1101. break;
  1102. }
  1103. p = nextSibling(p);
  1104. }
  1105. String *method_name = Getattr(n, "sym:name");
  1106. Printv(w->code, wrap_args, NIL);
  1107. // emit method invocation
  1108. Wrapper_add_local(w, "args", "octave_value_list args");
  1109. Wrapper_add_local(w, "out", "octave_value_list out");
  1110. Wrapper_add_local(w, "idx", "std::list<octave_value_list> idx");
  1111. Printf(w->code, "idx.push_back(octave_value_list(\"%s\"));\n", method_name);
  1112. Printf(w->code, "idx.push_back(args);\n");
  1113. Printf(w->code, "out=swig_get_self()->subsref(\".(\",idx,%d);\n", outputs);
  1114. String *cleanup = NewString("");
  1115. String *outarg = NewString("");
  1116. idx = 0;
  1117. // marshal return value
  1118. if (!is_void) {
  1119. Printf(w->code, "if (out.length()<%d) {\n", outputs);
  1120. Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave "
  1121. "method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name);
  1122. Printf(w->code, "}\n");
  1123. Setattr(n, "type", return_type);
  1124. tm = Swig_typemap_lookup("directorout", n, "result", w);
  1125. Setattr(n, "type", type);
  1126. if (tm != 0) {
  1127. char temp[24];
  1128. sprintf(temp, "out(%d)", idx);
  1129. Replaceall(tm, "$input", temp);
  1130. // Replaceall(tm, "$argnum", temp);
  1131. Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0");
  1132. if (Getattr(n, "tmap:directorout:implicitconv")) {
  1133. Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
  1134. }
  1135. Replaceall(tm, "$result", "c_result");
  1136. Printv(w->code, tm, "\n", NIL);
  1137. Delete(tm);
  1138. } else {
  1139. Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
  1140. "Unable to use return type %s in director method %s::%s (skipping method).\n",
  1141. SwigType_str(return_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
  1142. status = SWIG_ERROR;
  1143. }
  1144. }
  1145. idx++;
  1146. // marshal outputs
  1147. for (p = l; p;) {
  1148. if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
  1149. char temp[24];
  1150. sprintf(temp, "out(%d)", idx);
  1151. Replaceall(tm, "$input", temp);
  1152. Replaceall(tm, "$result", Getattr(p, "name"));
  1153. Printv(w->code, tm, "\n", NIL);
  1154. p = Getattr(p, "tmap:directorargout:next");
  1155. } else {
  1156. p = nextSibling(p);
  1157. }
  1158. }
  1159. Delete(parse_args);
  1160. Delete(cleanup);
  1161. Delete(outarg);
  1162. }
  1163. if (!is_void) {
  1164. if (!(ignored_method && !pure_virtual)) {
  1165. String *rettype = SwigType_str(return_type, 0);
  1166. if (!SwigType_isreference(return_type)) {
  1167. Printf(w->code, "return (%s) c_result;\n", rettype);
  1168. } else {
  1169. Printf(w->code, "return (%s) *c_result;\n", rettype);
  1170. }
  1171. Delete(rettype);
  1172. }
  1173. }
  1174. Append(w->code, "}\n");
  1175. // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
  1176. String *inline_extra_method = NewString("");
  1177. if (dirprot_mode() && !is_public(n) && !pure_virtual) {
  1178. Printv(inline_extra_method, declaration, NIL);
  1179. String *extra_method_name = NewStringf("%sSwigPublic", name);
  1180. Replaceall(inline_extra_method, name, extra_method_name);
  1181. Replaceall(inline_extra_method, ";\n", " {\n ");
  1182. if (!is_void)
  1183. Printf(inline_extra_method, "return ");
  1184. String *methodcall = Swig_method_call(super, l);
  1185. Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
  1186. Delete(methodcall);
  1187. Delete(extra_method_name);
  1188. }
  1189. // emit the director method
  1190. if (status == SWIG_OK) {
  1191. if (!Getattr(n, "defaultargs")) {
  1192. Wrapper_print(w, f_directors);
  1193. Printv(f_directors_h, declaration, NIL);
  1194. Printv(f_directors_h, inline_extra_method, NIL);
  1195. }
  1196. }
  1197. // clean up
  1198. Delete(wrap_args);
  1199. Delete(return_type);
  1200. Delete(pclassname);
  1201. DelWrapper(w);
  1202. return status;
  1203. }
  1204. String *runtimeCode() {
  1205. String *s = NewString("");
  1206. String *srun = Swig_include_sys("octrun.swg");
  1207. if (!srun) {
  1208. Printf(stderr, "*** Unable to open 'octrun.swg'\n");
  1209. } else {
  1210. Append(s, srun);
  1211. Delete(srun);
  1212. }
  1213. return s;
  1214. }
  1215. String *defaultExternalRuntimeFilename() {
  1216. return NewString("swigoctaverun.h");
  1217. }
  1218. };
  1219. extern "C" Language *swig_octave(void) {
  1220. return new OCTAVE();
  1221. }