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