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.
7 * Octave language module for SWIG.
8 * ----------------------------------------------------------------------------- */
10 char cvsroot_octave_cxx[] = "$Id$";
14 static const char *usage = (char *) "\
15 Octave Options (available with -octave)\n\
16 -api <N> - Generate code that assumes Octave API N [default: 37]\n\
20 class OCTAVE:public Language {
28 File *f_initbeforefunc;
32 String *s_members_tab;
37 String *constructor_name;
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",
52 "} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
54 enable_cplus_runtime_mode();
56 director_multiple_inheritance = 1;
57 director_language = 1;
62 virtual void main(int argc, char *argv[]) {
63 for (int i = 1; i < argc; i++) {
65 if (strcmp(argv[i], "-help") == 0) {
67 } else if (strcmp(argv[i], "-api") == 0) {
69 api_version = atoi(argv[i + 1]);
80 SWIG_library_directory("octave");
81 Preprocessor_define("SWIGOCTAVE 1", 0);
82 SWIG_config_file("octave.swg");
83 SWIG_typemap_lang("octave");
87 virtual int top(Node *n) {
89 Node *mod = Getattr(n, "module");
91 Node *options = Getattr(mod, "options");
94 if (Getattr(options, "dirprot")) {
97 if (Getattr(options, "nodirprot")) {
100 if (Getattr(options, "directors")) {
109 String *module = Getattr(n, "name");
110 String *outfile = Getattr(n, "outfile");
111 f_begin = NewFile(outfile, "w", SWIG_output_files());
113 FileErrorDisplay(outfile);
114 SWIG_exit(EXIT_FAILURE);
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);
135 Swig_banner(f_begin);
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);
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");
152 Printf(f_runtime, "\n");
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");
158 Printf(f_header,"extern \"C\" {\n");
163 Printf(f_header,"}\n");
168 if (directorsEnabled())
169 Swig_insert_file("director.swg", f_runtime);
171 Printf(f_init, "}\n");
172 Printf(s_global_tab, "{0,0,0,0,0}\n};\n");
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);
183 Dump(f_wrappers, f_begin);
184 Dump(f_initbeforefunc, f_begin);
185 Wrapper_pretty_print(f_init, f_begin);
187 Delete(s_global_tab);
188 Delete(f_initbeforefunc);
194 Delete(f_directors_h);
202 String *texinfo_escape(String *_s) {
203 const char* s=(const char*)Data(_s);
204 while (*s&&(*s=='\t'||*s=='\r'||*s=='\n'||*s==' '))
206 String *r = NewString("");
207 for (int j=0;s[j];++j) {
209 Append(r, "\\n\\\n");
210 } else if (s[j] == '\r') {
212 } else if (s[j] == '\t') {
214 } else if (s[j] == '\\') {
216 } else if (s[j] == '\'') {
218 } else if (s[j] == '\"') {
225 void emit_doc_texinfo() {
226 for (Iterator it = First(docs); it.key; it = Next(it)) {
227 String *wrap_name = it.key;
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");
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);
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);
242 Printf(f_doc,"\\n\\\n@end deftypefn");
243 Printf(f_doc,"\";\n");
246 Delete(escaped_doc_str);
252 bool is_empty_doc_node(Node* n) {
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);
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);
268 if (is_empty_doc_node(d))
271 Printf(tname, "%s_texinfo", wname);
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);
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);
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");
296 // * couldn't we just emit the docs here?
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} ");
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);
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);
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);
326 if (str && Len(str) > 0) {
327 // strip off {} if necessary
331 Delitem(str, DOH_END);
334 // emit into synopsis section
335 Append(synopsis, str);
339 virtual int importDirective(Node *n) {
340 String *modname = Getattr(n, "module");
342 Printf(f_init, "feval(\"%s\",octave_value_list(),0);\n", modname);
343 return Language::importDirective(n);
346 const char *get_implicitconv_flag(Node *n) {
348 if (n && GetFlag(n, "feature:implicitconv")) {
351 return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0";
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"));
364 Swig_typemap_attach_parms("in", plist, 0);
365 Swig_typemap_attach_parms("doc", plist, 0);
367 for (p = plist; p; p = pnext) {
372 String *pdoc = Getattr(p, "tmap:doc");
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");
380 name = name ? name : Getattr(p, "name");
381 type = type ? type : Getattr(p, "type");
382 value = value ? value : Getattr(p, "value");
384 String *tex_name = NewString("");
386 Printf(tex_name, "@var{%s}", name);
388 Printf(tex_name, "@var{?}");
390 String *tm = Getattr(p, "tmap:in");
392 pnext = Getattr(p, "tmap:in:next");
394 pnext = nextSibling(p);
398 Append(decl_str, ", ");
399 Append(decl_str, tex_name);
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");
409 lookup = Swig_symbol_clookup(value, 0);
411 value = Getattr(lookup, "sym:name");
413 Printf(decl_str, " = %s", value);
417 String *type_str = NewString("");
418 type = SwigType_base(type);
419 lookup = Swig_symbol_clookup(type, 0);
421 type = Getattr(lookup, "sym:name");
422 Printf(type_str, "%s is of type %s. ", tex_name, type);
423 Append(args_str, type_str);
430 Setattr(n, "feature:pdocs", pdocs);
434 virtual int functionWrapper(Node *n) {
435 Wrapper *f = NewWrapper();
440 String *nodeType = Getattr(n, "nodeType");
441 int constructor = (!Cmp(nodeType, "constructor"));
442 int destructor = (!Cmp(nodeType, "destructor"));
443 String *storage = Getattr(n, "storage");
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");
453 if (!overloaded && !addSymbol(iname, n))
457 Append(overname, Getattr(n, "sym:overname"));
459 Printv(f->def, "static octave_value_list ", overname, " (const octave_value_list& args, int nargout) {", NIL);
461 emit_parameter_variables(l, f);
462 emit_attach_parmmaps(l, f);
463 Setattr(n, "wrap:parms", l);
465 int num_arguments = emit_num_arguments(l);
466 int num_required = emit_num_required(l);
467 int varargs = emit_isvarargs(l);
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);
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);
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");
489 SwigType *pt = Getattr(p, "type");
491 String *tm = Getattr(p, "tmap:in");
493 if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) {
498 sprintf(source, "args(%d)", j);
499 Setattr(p, "emit:input", source);
501 Replaceall(tm, "$source", Getattr(p, "emit:input"));
502 Replaceall(tm, "$input", Getattr(p, "emit:input"));
503 Replaceall(tm, "$target", Getattr(p, "lname"));
505 if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
506 Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
508 Replaceall(tm, "$disown", "0");
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));
517 Replaceall(tm, "$implicitconv", convflag);
518 Setattr(p, "implicitconv", convflag);
521 String *getargs = NewString("");
522 if (j >= num_required)
523 Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm);
525 Printv(getargs, tm, NIL);
526 Printv(f->code, getargs, "\n", NIL);
529 p = Getattr(p, "tmap:in:next");
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));
537 // Check for trailing varargs
539 if (p && (tm = Getattr(p, "tmap:in"))) {
540 Replaceall(tm, "$input", "varargs");
541 Printv(f->code, tm, "\n", NIL);
545 // Insert constraint checking code
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");
556 // Insert cleanup code
557 String *cleanup = NewString("");
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));
566 if (strcmp(convflag, "0") == 0) {
570 if (tm && (Len(tm) != 0)) {
571 Replaceall(tm, "$source", Getattr(p, "lname"));
572 Printv(cleanup, tm, "\n", NIL);
574 p = Getattr(p, "tmap:freearg:next");
580 // Insert argument output code
581 String *outarg = NewString("");
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");
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");
602 Setattr(n, "wrap:name", overname);
604 Swig_director_emit_dynamic_cast(n, f);
605 String *actioncode = emit_action(n);
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");
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");
617 if (GetFlag(n, "feature:new"))
618 Replaceall(tm, "$owner", "1");
620 Replaceall(tm, "$owner", "0");
622 Printf(f->code, "%s\n", tm);
623 Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n");
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);
628 emit_return_variable(n, d, f);
630 Printv(f->code, outarg, NIL);
631 Printv(f->code, cleanup, NIL);
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);
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);
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");
651 Replaceall(f->code, "$symname", iname);
652 Wrapper_print(f, f_wrappers);
658 if (!overloaded || last_overload) {
660 String *tname = texinfo_name(n);
661 Printf(s_global_tab, "{\"%s\",%s,0,0,2,%s},\n", iname, wname, tname);
673 void dispatchFunction(Node *n) {
674 Wrapper *f = NewWrapper();
676 String *iname = Getattr(n, "sym:name");
677 String *wname = Swig_name_wrapper(iname);
679 String *dispatch = Swig_overload_dispatch(n, "return %s(args, nargout);", &maxargs);
680 String *tmp = NewString("");
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);
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);
694 Wrapper_print(f, f_wrappers);
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");
706 if (!addSymbol(iname, n))
710 Wrapper *getf = NewWrapper();
711 Wrapper *setf = NewWrapper();
713 String *getname = Swig_name_get(iname);
714 String *setname = Swig_name_set(iname);
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));
727 emit_action_code(n, setf->code, tm);
730 Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
732 Append(setf->code, "fail:\n");
733 Printf(setf->code, "return octave_value_list();\n");
735 Printf(setf->code, "return octave_set_immutable(args,nargout);");
737 Append(setf->code, "}\n");
738 Wrapper_print(setf, f_wrappers);
740 Setattr(n, "wrap:name", getname);
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);
751 Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
753 Append(getf->code, " return obj;\n");
755 Append(getf->code, "fail:\n");
756 Append(getf->code, " return octave_value_list();\n");
758 Append(getf->code, "}\n");
759 Wrapper_print(getf, f_wrappers);
761 Printf(s_global_tab, "{\"%s\",0,_wrap_%s,_wrap_%s,2,0},\n", iname, getname, setname);
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");
774 if (!addSymbol(iname, n))
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);
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);
791 Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
798 virtual int nativeWrapper(Node *n) {
799 return Language::nativeWrapper(n);
802 virtual int enumDeclaration(Node *n) {
803 return Language::enumDeclaration(n);
806 virtual int enumvalueDeclaration(Node *n) {
807 return Language::enumvalueDeclaration(n);
810 virtual int classDeclaration(Node *n) {
811 return Language::classDeclaration(n);
814 virtual int classHandler(Node *n) {
815 have_constructor = 0;
817 constructor_name = 0;
819 class_name = Getattr(n, "sym:name");
821 if (!addSymbol(class_name, n))
824 // This is a bug, due to the fact that swig_type -> octave_class mapping
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);
832 Setattr(emitted, mangled_classname, "1");
833 Delete(mangled_classname);
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);
839 Language::classHandler(n);
841 SwigType *t = Copy(Getattr(n, "name"));
842 SwigType_add_pointer(t);
844 String *wrap_class = NewStringf("&_wrap_class_%s", class_name);
845 SwigType_remember_clientdata(t, wrap_class);
847 int use_director = Swig_directorclass(n);
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);
863 Printf(s_members_tab, "{0,0,0,0}\n};\n");
864 Printv(f_wrappers, s_members_tab, NIL);
866 String *base_class_names = NewString("");
867 String *base_class = NewString("");
868 List *baselist = Getattr(n, "bases");
869 if (baselist && Len(baselist)) {
874 String *bname = Getattr(b.item, "name");
875 if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
880 String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname)));
881 Printf(base_class_names, "\"%s\",", bname_mangled);
882 Printf(base_class, "0,");
885 Delete(bname_mangled);
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);
902 Printv(f_wrappers, "0,0,", NIL);
904 Printv(f_wrappers, "_wrap_delete_", class_name, ",", NIL);
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);
910 Delete(base_class_names);
912 Delete(s_members_tab);
919 virtual int memberfunctionHandler(Node *n) {
920 Language::memberfunctionHandler(n);
922 assert(s_members_tab);
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));
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);
940 virtual int membervariableHandler(Node *n) {
941 Setattr(n, "feature:autodoc", "0");
943 Language::membervariableHandler(n);
945 assert(s_members_tab);
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);
953 Printf(s_members_tab, "{\"%s\",0,%s,%s,0,0},\n", symname, getname, setname);
960 virtual int constructorHandler(Node *n) {
961 have_constructor = 1;
962 if (!constructor_name)
963 constructor_name = NewString(Getattr(n, "sym:name"));
965 int use_director = Swig_directorclass(n);
967 Parm *parms = Getattr(n, "parms");
969 String *name = NewString("self");
970 String *type = NewString("void");
971 SwigType_add_pointer(type);
972 self = NewParm(type, name);
975 Setattr(self, "lname", "self_obj");
977 set_nextSibling(self, parms);
978 Setattr(n, "parms", self);
979 Setattr(n, "wrap:self", "1");
980 Setattr(n, "hidden", "1");
984 return Language::constructorHandler(n);;
987 virtual int destructorHandler(Node *n) {
989 return Language::destructorHandler(n);;
992 virtual int staticmemberfunctionHandler(Node *n) {
993 Language::staticmemberfunctionHandler(n);
995 assert(s_members_tab);
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));
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);
1013 virtual int memberconstantHandler(Node *n) {
1014 return Language::memberconstantHandler(n);
1017 virtual int staticmembervariableHandler(Node *n) {
1018 Setattr(n, "feature:autodoc", "0");
1020 Language::staticmembervariableHandler(n);
1022 if (!GetFlag(n, "wrappedasconstant")) {
1023 assert(s_members_tab);
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);
1031 Printf(s_members_tab, "{\"%s\",0,%s,%s,1,0},\n", symname, getname, setname);
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);
1048 int classDirectorEnd(Node *n) {
1049 Printf(f_directors_h, "};\n\n");
1050 return Language::classDirectorEnd(n);
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);
1061 // insert self parameter
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);
1071 if (!Getattr(n, "defaultargs")) {
1074 Wrapper *w = NewWrapper();
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");
1082 Wrapper_print(w, f_directors);
1087 // constructor header
1089 String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
1090 Printf(f_directors_h, " %s;\n", target);
1099 return Language::classDirectorConstructor(n);
1102 int classDirectorDefaultConstructor(Node *n) {
1103 String *classname = Swig_class_name(n);
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);
1112 Printf(f_directors_h, " SwigDirector_%s(octave_swig_type* self);\n", classname);
1114 return Language::classDirectorDefaultConstructor(n);
1117 int classDirectorMethod(Node *n, Node *parent, String *super) {
1124 String *c_classname = Getattr(parent, "name");
1125 String *declaration;
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;
1136 bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
1138 if (Cmp(storage, "virtual") == 0) {
1139 if (Cmp(value, "0") == 0) {
1140 pure_virtual = true;
1144 classname = Getattr(parent, "sym:name");
1145 type = Getattr(n, "type");
1146 name = Getattr(n, "name");
1149 declaration = NewString("");
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);
1156 // form complete return type
1157 return_type = Copy(type);
1159 SwigType *t = Copy(decl);
1161 f = SwigType_pop_function(t);
1162 SwigType_push(return_type, t);
1167 // virtual method definition
1168 l = Getattr(n, "parms");
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);
1178 // header declaration
1179 target = Swig_method_decl(rtype, decl, name, l, 0, 1);
1180 Printf(declaration, " virtual %s", target);
1183 // Get any exception classes in the throws typemap
1184 ParmList *throw_parm_list = 0;
1186 if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
1190 Append(w->def, " throw(");
1191 Append(declaration, " throw(");
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"))) {
1198 Append(w->def, ", ");
1199 Append(declaration, ", ");
1201 String *str = SwigType_str(Getattr(p, "type"), 0);
1202 Append(w->def, str);
1203 Append(declaration, str);
1208 Append(w->def, ")");
1209 Append(declaration, ")");
1212 Append(w->def, " {");
1213 Append(declaration, ";\n");
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).
1219 if (!(ignored_method && !pure_virtual)) {
1220 String *cres = SwigType_lstr(return_type, "c_result");
1221 Printf(w->code, "%s;\n", cres);
1226 if (ignored_method) {
1227 if (!pure_virtual) {
1229 Printf(w->code, "return ");
1230 String *super_call = Swig_method_call(super, l);
1231 Printf(w->code, "%s;\n", super_call);
1234 Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
1235 SwigType_namestr(name));
1238 // attach typemaps to arguments (C/C++ -> Python)
1239 String *parse_args = NewString("");
1241 Swig_typemap_attach_parms("in", l, 0);
1242 Swig_typemap_attach_parms("directorin", l, 0);
1243 Swig_typemap_attach_parms("directorargout", l, w);
1251 // build argument list and type conversion string
1256 if (checkAttribute(p, "tmap:in:numinputs", "0")) {
1257 p = Getattr(p, "tmap:in:next");
1261 if (Getattr(p, "tmap:directorargout") != 0)
1264 String *pname = Getattr(p, "name");
1265 String *ptype = Getattr(p, "type");
1266 Wrapper_add_local(w, "tmpv", "octave_value tmpv");
1268 if ((tm = Getattr(p, "tmap:directorin")) != 0) {
1269 String *parse = Getattr(p, "tmap:directorin: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);
1278 Append(parse_args, parse);
1279 Replaceall(tm, "$input", pname);
1280 Replaceall(tm, "$owner", "0");
1284 p = Getattr(p, "tmap:directorin:next");
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;
1296 String *method_name = Getattr(n, "sym:name");
1298 Printv(w->code, wrap_args, NIL);
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);
1308 String *cleanup = NewString("");
1309 String *outarg = NewString("");
1312 // marshal return value
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");
1319 Setattr(n, "type", return_type);
1320 tm = Swig_typemap_lookup("directorout", n, "result", w);
1321 Setattr(n, "type", type);
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));
1331 Replaceall(tm, "$result", "c_result");
1332 Printv(w->code, tm, "\n", NIL);
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;
1345 if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
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");
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);
1368 Printf(w->code, "return (%s) *c_result;\n", rettype);
1374 Append(w->code, "}\n");
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 ");
1384 Printf(inline_extra_method, "return ");
1385 String *methodcall = Swig_method_call(super, l);
1386 Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
1388 Delete(extra_method_name);
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);
1400 Delete(return_type);
1406 String *runtimeCode() {
1407 String *s = NewString("");
1408 String *srun = Swig_include_sys("octrun.swg");
1410 Printf(stderr, "*** Unable to open 'octrun.swg'\n");
1418 String *defaultExternalRuntimeFilename() {
1419 return NewString("swigoctaverun.h");
1423 extern "C" Language *swig_octave(void) {
1424 return new OCTAVE();