import source from 1.3.40
[external/swig.git] / Source / Modules / octave.cxx
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
10 char cvsroot_octave_cxx[] = "$Id$";
11
12 #include "swigmod.h"
13
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\
17      \n";
18
19
20 class OCTAVE:public Language {
21 private:
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
43 public:
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
1423 extern "C" Language *swig_octave(void) {
1424   return new OCTAVE();
1425 }