~ubuntu-branches/ubuntu/oneiric/swig1.3/oneiric

« back to all changes in this revision

Viewing changes to Source/Modules/octave.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2008-06-20 18:33:37 UTC
  • mfrom: (1.2.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080620183337-hockvwcewu29409c
Tags: 1.3.35-4ubuntu1
* Merge from debian unstable, remaining changes:
  - Drop support for pike.
  - Use python2.5 instead of python2.4.
  - use php5
  - Clean Runtime/ as well.
  - Force a few environment variables.
  - debian/Rules (clean): Remove Lib/ocaml/swigp4.ml.

Show diffs side-by-side

added added

removed removed

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