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