/trunk/Source/Modules/octave.cxx

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