/branches/swig-2.0/Source/Modules/octave.cxx

# · C++ · 1410 lines · 1172 code · 196 blank · 42 comment · 228 complexity · 18f13a1b08b943ba7426d6a68613414b MD5 · raw file

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