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

« back to all changes in this revision

Viewing changes to Source/Modules/ruby.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-12-06 10:27:08 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206102708-t37t62i45n595w0e
Tags: 1.3.33-2ubuntu1
* Merge with Debian; remaining changes:
  - Drop support for pike.
  - Use python2.5 instead of python2.4.
  - 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:
7
7
 * Ruby language module for SWIG.
8
8
 * ----------------------------------------------------------------------------- */
9
9
 
10
 
char cvsroot_ruby_cxx[] = "$Header: /cvsroot/swig/SWIG/Source/Modules/ruby.cxx,v 1.139 2006/11/09 22:32:28 wsfulton Exp $";
 
10
char cvsroot_ruby_cxx[] = "$Id: ruby.cxx 10115 2007-11-12 11:47:40Z gga73 $";
11
11
 
12
12
#include "swigmod.h"
13
13
#include "cparse.h"
22
22
class RClass {
23
23
private:
24
24
  String *temp;
 
25
 
25
26
public:
26
27
  String *name;                 /* class name (renamed) */
27
28
  String *cname;                /* original C class/struct name */
47
48
  String *prefix;
48
49
  String *init;
49
50
 
 
51
 
50
52
  int constructor_defined;
51
53
  int destructor_defined;
52
54
 
113
115
};
114
116
 
115
117
 
 
118
/* flags for the make_autodoc function */
 
119
enum autodoc_t {
 
120
  AUTODOC_CLASS,
 
121
  AUTODOC_CTOR,
 
122
  AUTODOC_DTOR,
 
123
  AUTODOC_STATICFUNC,
 
124
  AUTODOC_FUNC,
 
125
  AUTODOC_METHOD,
 
126
  AUTODOC_GETTER,
 
127
  AUTODOC_SETTER
 
128
};
 
129
 
116
130
static const char *usage = "\
117
131
Ruby Options (available with -ruby)\n\
118
132
     -globalmodule   - Wrap everything into the global module\n\
119
133
     -minherit       - Attempt to support multiple inheritance\n\
120
134
     -nocppcast      - Disable C++ casting operators, useful for generating bugs\n\
121
 
     -cppcast        - Enable C++ casting operators\n\
 
135
     -cppcast        - Enable C++ casting operators (default)\n\
122
136
     -autorename     - Enable renaming of classes and methods to follow Ruby coding standards\n\
123
137
     -noautorename   - Disable renaming of classes and methods (default)\n\
124
138
     -prefix <name>  - Set a prefix <name> to be prepended to all names\n\
125
 
     -feature <name> - Set feature name to <name> (used by `require')\n";
 
139
     -initname <name> - Set entry function to Init_<name> (used by `require')\n";
126
140
 
127
141
 
128
142
#define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0)
129
143
#define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0))
130
144
 
 
145
 
131
146
class RUBY:public Language {
132
147
private:
133
148
 
154
169
  bool multipleInheritance;
155
170
 
156
171
  // Wrap modes
157
 
  enum {
 
172
  enum WrapperMode {
158
173
    NO_CPP,
159
174
    MEMBER_FUNC,
160
175
    CONSTRUCTOR_ALLOCATE,
166
181
    STATIC_VAR
167
182
  };
168
183
 
 
184
  /* ------------------------------------------------------------
 
185
   * autodoc level declarations
 
186
   * ------------------------------------------------------------ */
 
187
 
 
188
  enum autodoc_l {
 
189
    NO_AUTODOC = -2,            // no autodoc
 
190
    STRING_AUTODOC = -1,        // use provided string
 
191
    NAMES_AUTODOC = 0,          // only parameter names
 
192
    TYPES_AUTODOC = 1,          // parameter names and types
 
193
    EXTEND_AUTODOC = 2,         // extended documentation and parameter names
 
194
    EXTEND_TYPES_AUTODOC = 3    // extended documentation and parameter types + names
 
195
  };
 
196
 
 
197
  autodoc_t last_mode;
 
198
  String*   last_autodoc;
 
199
 
 
200
 
 
201
 
 
202
  autodoc_l autodoc_level(String *autodoc) {
 
203
    autodoc_l dlevel = NO_AUTODOC;
 
204
    if (autodoc) {
 
205
      char *c = Char(autodoc);
 
206
      if (c && isdigit(c[0])) {
 
207
        dlevel = (autodoc_l) atoi(c);
 
208
      } else {
 
209
        if (strcmp(c, "extended") == 0) {
 
210
          dlevel = EXTEND_AUTODOC;
 
211
        } else {
 
212
          dlevel = STRING_AUTODOC;
 
213
        }
 
214
      }
 
215
    }
 
216
    return dlevel;
 
217
  }
 
218
 
 
219
 
 
220
 
 
221
  /* ------------------------------------------------------------
 
222
   * have_docstring()
 
223
   *    Check if there is a docstring directive and it has text,
 
224
   *    or there is an autodoc flag set
 
225
   * ------------------------------------------------------------ */
 
226
 
 
227
  bool have_docstring(Node *n) {
 
228
    String *str = Getattr(n, "feature:docstring");
 
229
    return (str != NULL && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
 
230
  }
 
231
 
 
232
  /* ------------------------------------------------------------
 
233
   * docstring()
 
234
   *    Get the docstring text, stripping off {} if neccessary,
 
235
   *    and enclose in triple double quotes.  If autodoc is also
 
236
   *    set then it will build a combined docstring.
 
237
   * ------------------------------------------------------------ */
 
238
 
 
239
  String *docstring(Node *n, autodoc_t ad_type) {
 
240
 
 
241
    String *str = Getattr(n, "feature:docstring");
 
242
    bool have_ds = (str != NULL && Len(str) > 0);
 
243
    bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
 
244
    String *autodoc = NULL;
 
245
    String *doc = NULL;
 
246
 
 
247
    if (have_ds) {
 
248
      char *t = Char(str);
 
249
      if (*t == '{') {
 
250
        Delitem(str, 0);
 
251
        Delitem(str, DOH_END);
 
252
      }
 
253
    }
 
254
 
 
255
    if (have_auto) {
 
256
      autodoc = make_autodoc(n, ad_type);
 
257
      have_auto = (autodoc != NULL && Len(autodoc) > 0);
 
258
    }
 
259
    // If there is more than one line then make docstrings like this:
 
260
    //
 
261
    //      This is line1
 
262
    //      And here is line2 followed by the rest of them
 
263
    //
 
264
    // otherwise, put it all on a single line
 
265
    //
 
266
    if (have_auto && have_ds) { // Both autodoc and docstring are present
 
267
      doc = NewString("");
 
268
      Printv(doc, "\n", autodoc, "\n", str, NIL);
 
269
    } else if (!have_auto && have_ds) { // only docstring
 
270
      if (Strchr(str, '\n') == NULL) {
 
271
        doc = NewString(str);
 
272
      } else {
 
273
        doc = NewString("");
 
274
        Printv(doc, str, NIL);
 
275
      }
 
276
    } else if (have_auto && !have_ds) { // only autodoc
 
277
      if (Strchr(autodoc, '\n') == NULL) {
 
278
        doc = NewStringf("%s", autodoc);
 
279
      } else {
 
280
        doc = NewString("");
 
281
        Printv(doc, "\n", autodoc, NIL);
 
282
      }
 
283
    } else
 
284
      doc = NewString("");
 
285
 
 
286
    // Save the generated strings in the parse tree in case they are used later
 
287
    // by post processing tools
 
288
    Setattr(n, "ruby:docstring", doc);
 
289
    Setattr(n, "ruby:autodoc", autodoc);
 
290
    return doc;
 
291
  }
 
292
 
 
293
  /* ------------------------------------------------------------
 
294
   * make_autodocParmList()
 
295
   *   Generate the documentation for the function parameters
 
296
   * ------------------------------------------------------------ */
 
297
 
 
298
  String *make_autodocParmList(Node *n, bool showTypes) {
 
299
    String *doc = NewString("");
 
300
    String *pdocs = Copy(Getattr(n, "feature:pdocs"));
 
301
    ParmList *plist = CopyParmList(Getattr(n, "parms"));
 
302
    Parm *p;
 
303
    Parm *pnext;
 
304
    Node *lookup;
 
305
    int lines = 0;
 
306
    const int maxwidth = 50;
 
307
 
 
308
    if (pdocs)
 
309
      Append(pdocs, ".\n");
 
310
 
 
311
 
 
312
    Swig_typemap_attach_parms("in", plist, 0);
 
313
    Swig_typemap_attach_parms("doc", plist, 0);
 
314
 
 
315
    for (p = plist; p; p = pnext) {
 
316
      String *name = 0;
 
317
      String *type = 0;
 
318
      String *value = 0;
 
319
      String *ptype = 0;
 
320
      String *pdoc = Getattr(p, "tmap:doc");
 
321
      if (pdoc) {
 
322
        name = Getattr(p, "tmap:doc:name");
 
323
        type = Getattr(p, "tmap:doc:type");
 
324
        value = Getattr(p, "tmap:doc:value");
 
325
        ptype = Getattr(p, "tmap:doc:pytype");
 
326
      }
 
327
 
 
328
      name = name ? name : Getattr(p, "name");
 
329
      type = type ? type : Getattr(p, "type");
 
330
      value = value ? value : Getattr(p, "value");
 
331
 
 
332
 
 
333
      String *tm = Getattr(p, "tmap:in");
 
334
      if (tm) {
 
335
        pnext = Getattr(p, "tmap:in:next");
 
336
      } else {
 
337
        pnext = nextSibling(p);
 
338
      }
 
339
 
 
340
      // Skip ignored input attributes
 
341
      if (checkAttribute(p, "tmap:in:numinputs", "0"))
 
342
        continue;
 
343
 
 
344
      // Skip the 'self' parameter which in ruby is implicit
 
345
      if ( Cmp(name, "self") == 0 )
 
346
        continue;
 
347
 
 
348
      // Make __p parameters just p (as used in STL)
 
349
      Replace( name, "__", "", DOH_REPLACE_FIRST );
 
350
 
 
351
      if (Len(doc)) {
 
352
        // add a comma to the previous one if any
 
353
        Append(doc, ", ");
 
354
 
 
355
        // Do we need to wrap a long line?
 
356
        if ((Len(doc) - lines * maxwidth) > maxwidth) {
 
357
          Printf(doc, "\n%s", tab4);
 
358
          lines += 1;
 
359
        }
 
360
      }
 
361
      // Do the param type too?
 
362
      if (showTypes) {
 
363
        type = SwigType_base(type);
 
364
        lookup = Swig_symbol_clookup(type, 0);
 
365
        if (lookup)
 
366
          type = Getattr(lookup, "sym:name");
 
367
        Printf(doc, "%s ", type);
 
368
      }
 
369
 
 
370
      if (name) {
 
371
        Append(doc, name);
 
372
        if (pdoc) {
 
373
          if (!pdocs)
 
374
            pdocs = NewString("Parameters:\n");
 
375
          Printf(pdocs, "   %s.\n", pdoc);
 
376
        }
 
377
      } else {
 
378
        Append(doc, "?");
 
379
      }
 
380
 
 
381
      if (value) {
 
382
        if (Strcmp(value, "NULL") == 0)
 
383
          value = NewString("nil");
 
384
        else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
 
385
          value = NewString("true");
 
386
        else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
 
387
          value = NewString("false");
 
388
        else {
 
389
          lookup = Swig_symbol_clookup(value, 0);
 
390
          if (lookup)
 
391
            value = Getattr(lookup, "sym:name");
 
392
        }
 
393
        Printf(doc, "=%s", value);
 
394
      }
 
395
    }
 
396
    if (pdocs)
 
397
      Setattr(n, "feature:pdocs", pdocs);
 
398
    Delete(plist);
 
399
    return doc;
 
400
  }
 
401
 
 
402
  /* ------------------------------------------------------------
 
403
   * make_autodoc()
 
404
   *    Build a docstring for the node, using parameter and other
 
405
   *    info in the parse tree.  If the value of the autodoc
 
406
   *    attribute is "0" then do not include parameter types, if
 
407
   *    it is "1" (the default) then do.  If it has some other
 
408
   *    value then assume it is supplied by the extension writer
 
409
   *    and use it directly.
 
410
   * ------------------------------------------------------------ */
 
411
 
 
412
  String *make_autodoc(Node *n, autodoc_t ad_type) {
 
413
    int extended = 0;
 
414
    // If the function is overloaded then this funciton is called
 
415
    // for the last one.  Rewind to the first so the docstrings are
 
416
    // in order.
 
417
    while (Getattr(n, "sym:previousSibling"))
 
418
      n = Getattr(n, "sym:previousSibling");
 
419
 
 
420
    Node *pn = Swig_methodclass(n);
 
421
    String* super_names = NewString(""); 
 
422
    String* class_name = Getattr(pn, "sym:name") ; 
 
423
 
 
424
    if ( !class_name ) class_name = NewString("");
 
425
    else
 
426
      {
 
427
        class_name = Copy(class_name);
 
428
        List *baselist = Getattr(pn, "bases");
 
429
        if (baselist && Len(baselist)) {
 
430
          Iterator base = First(baselist);
 
431
          while (base.item && GetFlag(base.item, "feature:ignore")) {
 
432
            base = Next(base);
 
433
          }
 
434
          
 
435
          int count = 0;
 
436
          for ( ;base.item; ++count) {
 
437
            if ( count ) Append(super_names, ", ");
 
438
            String *basename = Getattr(base.item, "sym:name");
 
439
 
 
440
            String* basenamestr = NewString(basename);
 
441
            Node* parent = parentNode(base.item);
 
442
            while (parent)
 
443
              {
 
444
                String *parent_name = Copy( Getattr(parent, "sym:name") );
 
445
                if ( !parent_name ) {
 
446
                  Node* mod = Getattr(parent, "module");
 
447
                  if ( mod )
 
448
                    parent_name = Copy( Getattr(mod, "name") );
 
449
                  if ( parent_name )
 
450
                    {
 
451
                      (Char(parent_name))[0] = toupper((Char(parent_name))[0]);
 
452
                    }
 
453
                }
 
454
                if ( parent_name )
 
455
                  {
 
456
                    Insert(basenamestr, 0, "::");
 
457
                    Insert(basenamestr, 0, parent_name);
 
458
                    Delete(parent_name);
 
459
                  }
 
460
                parent = parentNode(parent);
 
461
              }
 
462
 
 
463
            Append(super_names, basenamestr );
 
464
            Delete(basenamestr);
 
465
            base = Next(base);
 
466
          }
 
467
        }
 
468
      }
 
469
    String* full_name;
 
470
    if ( module ) {
 
471
      full_name = NewString(module);
 
472
      if (class_name && Len(class_name) > 0) Append(full_name, "::");
 
473
    }
 
474
    else
 
475
      full_name = NewString("");
 
476
    Append(full_name, class_name);
 
477
 
 
478
    String* symname = Getattr(n, "sym:name");
 
479
    if ( Getattr( special_methods, symname ) )
 
480
      symname = Getattr( special_methods, symname );
 
481
 
 
482
    String* methodName = NewString(full_name);
 
483
    Append(methodName, symname);
 
484
 
 
485
 
 
486
    // Each overloaded function will try to get documented,
 
487
    // so we keep the name of the last overloaded function and its type.
 
488
    // Documenting just from functionWrapper() is not possible as
 
489
    // sym:name has already been changed to include the class name
 
490
    if ( last_mode == ad_type && Cmp(methodName, last_autodoc) == 0 ) {
 
491
      Delete(full_name);
 
492
      Delete(class_name);
 
493
      Delete(super_names);
 
494
      Delete(methodName);
 
495
      return NewString("");
 
496
    }
 
497
 
 
498
 
 
499
    last_mode    = ad_type;
 
500
    last_autodoc = Copy(methodName);
 
501
 
 
502
    String *doc = NewString("/*\n");
 
503
    int counter = 0;
 
504
    bool skipAuto = false;
 
505
    Node* on = n;
 
506
    for ( ; n; ++counter ) {
 
507
      skipAuto = false;
 
508
      bool showTypes = false;
 
509
      String *autodoc = Getattr(n, "feature:autodoc");
 
510
      autodoc_l dlevel = autodoc_level(autodoc);
 
511
      switch (dlevel) {
 
512
      case NO_AUTODOC:
 
513
        break;
 
514
      case NAMES_AUTODOC:
 
515
        showTypes = false;
 
516
        break;
 
517
      case TYPES_AUTODOC:
 
518
        showTypes = true;
 
519
        break;
 
520
      case EXTEND_AUTODOC:
 
521
        extended = 1;
 
522
        showTypes = false;
 
523
        break;
 
524
      case EXTEND_TYPES_AUTODOC:
 
525
        extended = 1;
 
526
        showTypes = true;
 
527
        break;
 
528
      case STRING_AUTODOC:
 
529
        skipAuto = true;
 
530
        break;
 
531
      }
 
532
 
 
533
      SwigType *type = Getattr(n, "type");
 
534
 
 
535
      if (type) {
 
536
        if (Strcmp(type, "void") == 0)
 
537
          type = NULL;
 
538
        else {
 
539
          SwigType *qt = SwigType_typedef_resolve_all(type);
 
540
          if (SwigType_isenum(qt))
 
541
              type = NewString("int");
 
542
          else {
 
543
            type = SwigType_base(type);
 
544
            Node *lookup = Swig_symbol_clookup(type, 0);
 
545
              if (lookup)
 
546
                type = Getattr(lookup, "sym:name");
 
547
          }
 
548
        }
 
549
      }
 
550
 
 
551
      if (counter == 0) {
 
552
        switch (ad_type) {
 
553
        case AUTODOC_CLASS:
 
554
          Printf(doc, "  Document-class: %s", full_name);
 
555
          if ( Len(super_names) > 0 )
 
556
            Printf( doc, " < %s", super_names);
 
557
          Append(doc, "\n\n");
 
558
          break;
 
559
        case AUTODOC_CTOR:
 
560
          Printf(doc, "  Document-method: %s.new\n\n", full_name);
 
561
          break;
 
562
 
 
563
        case AUTODOC_DTOR:
 
564
          break;
 
565
 
 
566
        case AUTODOC_STATICFUNC:
 
567
          Printf(doc, "  Document-method: %s.%s\n\n", full_name, symname);
 
568
          break;
 
569
 
 
570
        case AUTODOC_FUNC:
 
571
        case AUTODOC_METHOD:
 
572
        case AUTODOC_GETTER:
 
573
          Printf(doc, "  Document-method: %s.%s\n\n", full_name, symname);
 
574
          break;
 
575
        case AUTODOC_SETTER:
 
576
          Printf(doc, "  Document-method: %s.%s=\n\n", full_name, symname);
 
577
          break;
 
578
        }
 
579
      }
 
580
 
 
581
 
 
582
      if (skipAuto) {
 
583
        if ( counter == 0 ) Printf(doc, "  call-seq:\n");
 
584
        switch( ad_type )
 
585
          {
 
586
          case AUTODOC_STATICFUNC:
 
587
          case AUTODOC_FUNC:
 
588
          case AUTODOC_METHOD:
 
589
          case AUTODOC_GETTER:
 
590
            {
 
591
              String *paramList = make_autodocParmList(n, showTypes);
 
592
              if (Len(paramList))
 
593
                Printf(doc, "    %s(%s)", symname, paramList);
 
594
              else
 
595
                Printf(doc, "    %s", symname);
 
596
              if (type)
 
597
                Printf(doc, " -> %s", type);
 
598
              break;
 
599
            }
 
600
          case AUTODOC_SETTER:
 
601
            {
 
602
              Printf(doc, "    %s=(x)", symname);
 
603
              if (type) Printf(doc, " -> %s", type);
 
604
              break;
 
605
            }
 
606
          default:
 
607
            break;
 
608
          }
 
609
      }
 
610
      else {
 
611
        switch (ad_type) {
 
612
        case AUTODOC_CLASS:
 
613
          {
 
614
            // Only do the autodoc if there isn't a docstring for the class
 
615
            String *str = Getattr(n, "feature:docstring");
 
616
            if (counter == 0 && (str == NULL || Len(str) == 0)) {
 
617
              if (CPlusPlus) {
 
618
                Printf(doc, "  Proxy of C++ %s class", full_name);
 
619
              } else {
 
620
                Printf(doc, "  Proxy of C %s struct", full_name);
 
621
              }
 
622
            }
 
623
          }
 
624
          break;
 
625
        case AUTODOC_CTOR:
 
626
          if (counter == 0) Printf(doc, "  call-seq:\n");
 
627
          if (Strcmp(class_name, symname) == 0) {
 
628
            String *paramList = make_autodocParmList(n, showTypes);
 
629
            if (Len(paramList))
 
630
              Printf(doc, "    %s.new(%s)", class_name, paramList);
 
631
            else
 
632
              Printf(doc, "    %s.new", class_name);
 
633
          } else
 
634
            Printf(doc, "    %s.new(%s)", class_name, 
 
635
                   make_autodocParmList(n, showTypes));
 
636
          break;
 
637
 
 
638
        case AUTODOC_DTOR:
 
639
          break;
 
640
 
 
641
        case AUTODOC_STATICFUNC:
 
642
        case AUTODOC_FUNC:
 
643
        case AUTODOC_METHOD:
 
644
        case AUTODOC_GETTER:
 
645
          {
 
646
            if (counter == 0) Printf(doc, "  call-seq:\n");
 
647
            String *paramList = make_autodocParmList(n, showTypes);
 
648
            if (Len(paramList))
 
649
              Printf(doc, "    %s(%s)", symname, paramList);
 
650
            else
 
651
              Printf(doc, "    %s", symname);
 
652
            if (type)
 
653
              Printf(doc, " -> %s", type);
 
654
            break;
 
655
          }
 
656
        case AUTODOC_SETTER:
 
657
          {
 
658
            Printf(doc, "  call-seq:\n");
 
659
            Printf(doc, "    %s=(x)", symname);
 
660
            if (type) Printf(doc, " -> %s", type);
 
661
            break;
 
662
          }
 
663
        }
 
664
      }
 
665
 
 
666
      // if it's overloaded then get the next decl and loop around again
 
667
      n = Getattr(n, "sym:nextSibling");
 
668
      if (n)
 
669
        Append(doc, "\n");
 
670
    }
 
671
 
 
672
    Printf(doc, "\n\n");
 
673
    if (!skipAuto) {
 
674
      switch (ad_type) {
 
675
      case AUTODOC_CLASS:
 
676
      case AUTODOC_DTOR:
 
677
        break;
 
678
      case AUTODOC_CTOR:
 
679
        Printf(doc, "Class constructor.\n");
 
680
        break;
 
681
      case AUTODOC_STATICFUNC:
 
682
        Printf(doc, "A class method.\n");
 
683
        break;
 
684
      case AUTODOC_FUNC:
 
685
        Printf(doc, "A module function.\n");
 
686
        break;
 
687
      case AUTODOC_METHOD:
 
688
        Printf(doc, "An instance method.\n");
 
689
        break;
 
690
      case AUTODOC_GETTER:
 
691
        Printf(doc, "Get value of attribute.\n");
 
692
        break;
 
693
      case AUTODOC_SETTER:
 
694
        Printf(doc, "Set new value for attribute.\n");
 
695
        break;
 
696
      }
 
697
    }
 
698
 
 
699
 
 
700
    n = on;
 
701
    while ( n ) {
 
702
      String *autodoc = Getattr(n, "feature:autodoc");
 
703
      autodoc_l dlevel = autodoc_level(autodoc);
 
704
 
 
705
      symname = Getattr(n, "sym:name");
 
706
      if ( Getattr( special_methods, symname ) )
 
707
        symname = Getattr( special_methods, symname );
 
708
 
 
709
      switch (dlevel) {
 
710
      case NO_AUTODOC:
 
711
      case NAMES_AUTODOC:
 
712
      case TYPES_AUTODOC:
 
713
        extended = 0;
 
714
        break;
 
715
      case STRING_AUTODOC:
 
716
        extended = 2;
 
717
        Replaceall( autodoc, "$class", class_name );
 
718
        Printv(doc, autodoc, ".", NIL);
 
719
        break;
 
720
      case EXTEND_AUTODOC:
 
721
      case EXTEND_TYPES_AUTODOC:
 
722
        extended = 1;
 
723
        break;
 
724
      }
 
725
 
 
726
 
 
727
      if (extended) {
 
728
        String *pdocs = Getattr(n, "feature:pdocs");
 
729
        if (pdocs) {
 
730
          Printv(doc, "\n\n", pdocs, NULL);
 
731
          break;
 
732
        }
 
733
        if ( extended == 2 ) break;
 
734
      }
 
735
      n = Getattr(n, "sym:nextSibling");
 
736
    }
 
737
 
 
738
    Append(doc, "\n*/\n");
 
739
    Delete(full_name);
 
740
    Delete(class_name);
 
741
    Delete(super_names);
 
742
    Delete(methodName);
 
743
 
 
744
    return doc;
 
745
  }
 
746
 
169
747
public:
170
748
 
171
749
  /* ---------------------------------------------------------------------
179
757
    modvar = 0;
180
758
    feature = 0;
181
759
    prefix = 0;
 
760
    last_autodoc = NewString("");
182
761
    current = NO_CPP;
183
762
    classes = 0;
184
763
    klass = 0;
216
795
    /* Look for certain command line options */
217
796
    for (int i = 1; i < argc; i++) {
218
797
      if (argv[i]) {
219
 
        if (strcmp(argv[i], "-feature") == 0) {
 
798
        if (strcmp(argv[i], "-initname") == 0) {
 
799
          if (argv[i + 1]) {
 
800
            char *name = argv[i + 1];
 
801
            feature = NewString(name);
 
802
            Swig_mark_arg(i);
 
803
            Swig_mark_arg(i + 1);
 
804
            i++;
 
805
          } else {
 
806
            Swig_arg_error();
 
807
          }
 
808
        }
 
809
        else if (strcmp(argv[i], "-feature") == 0) {
 
810
          fprintf( stderr, "Warning: Ruby -feature option is deprecated, "
 
811
                   "please use -initname instead.\n");
220
812
          if (argv[i + 1]) {
221
813
            char *name = argv[i + 1];
222
814
            feature = NewString(name);
310
902
 
311
903
    special_methods = NewHash();
312
904
 
313
 
    /* Python style special method name. */
 
905
    /* Python->Ruby style special method name. */
314
906
    /* Basic */
315
907
    Setattr(special_methods, "__repr__", "inspect");
316
908
    Setattr(special_methods, "__str__", "to_s");
395
987
    String *outfile = Getattr(n, "outfile");
396
988
    String *outfile_h = Getattr(n, "outfile_h");
397
989
 
 
990
    if (!outfile) {
 
991
      Printf(stderr, "Unable to determine outfile\n");
 
992
      SWIG_exit(EXIT_FAILURE);
 
993
    }
 
994
 
398
995
    f_runtime = NewFile(outfile, "w");
399
996
    if (!f_runtime) {
400
997
      FileErrorDisplay(outfile);
402
999
    }
403
1000
 
404
1001
    if (directorsEnabled()) {
 
1002
      if (!outfile_h) {
 
1003
        Printf(stderr, "Unable to determine outfile_h\n");
 
1004
        SWIG_exit(EXIT_FAILURE);
 
1005
      }
405
1006
      f_runtime_h = NewFile(outfile_h, "w");
406
1007
      if (!f_runtime_h) {
407
1008
        FileErrorDisplay(outfile_h);
482
1083
    Printf(f_header, "static VALUE %s;\n", modvar);
483
1084
 
484
1085
    /* Start generating the initialization function */
 
1086
    String* docs = docstring(n, AUTODOC_CLASS);
 
1087
    Printf(f_init, "/*\n%s\n*/", docs );
485
1088
    Printv(f_init, "\n", "#ifdef __cplusplus\n", "extern \"C\"\n", "#endif\n", "SWIGEXPORT void Init_", feature, "(void) {\n", "size_t i;\n", "\n", NIL);
486
1089
 
487
1090
    Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL);
942
1545
        Replaceall(tm, "$input", Getattr(p, "emit:input"));
943
1546
 
944
1547
        Printv(outarg, tm, "\n", NIL);
945
 
        need_result = 1;
 
1548
        need_result += 1;
946
1549
        p = Getattr(p, "tmap:argout:next");
947
1550
      } else {
948
1551
        p = nextSibling(p);
985
1588
   * --------------------------------------------------------------------- */
986
1589
 
987
1590
  virtual int functionWrapper(Node *n) {
 
1591
 
988
1592
    String *nodeType;
989
1593
    bool constructor;
990
1594
    bool destructor;
1080
1684
      }
1081
1685
      Printf(f->code, "{rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc); SWIG_fail;}\n", numreq - start);
1082
1686
    } else {
 
1687
 
 
1688
      if ( current == NO_CPP )
 
1689
        {
 
1690
          String* docs = docstring(n, AUTODOC_FUNC);
 
1691
          Printf(f_wrappers, "%s", docs);
 
1692
          Delete(docs);
 
1693
        }
 
1694
 
1083
1695
      Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
1084
1696
      if (!varargs) {
1085
1697
        Printf(f->code, "if ((argc < %d) || (argc > %d)) ", numreq - start, numarg - start);
1110
1722
    insertArgOutputCode(l, outarg, need_result);
1111
1723
 
1112
1724
    /* if the object is a director, and the method call originated from its
1113
 
     * underlying python object, resolve the call by going up the c++ 
 
1725
     * underlying Ruby object, resolve the call by going up the c++ 
1114
1726
     * inheritance chain.  otherwise try to resolve the method in python.  
1115
1727
     * without this check an infinite loop is set up between the director and 
1116
1728
     * shadow class method calls.
1239
1851
      need_result = 1;
1240
1852
      // Printf(f->code, "DATA_PTR(self) = result;\n");
1241
1853
    }
 
1854
    else
 
1855
      {
 
1856
        if ( need_result > 1 ) {
 
1857
          if ( SwigType_type(t) == T_VOID )
 
1858
            Printf(f->code, "vresult = rb_ary_new();\n");
 
1859
          else
 
1860
            {
 
1861
              Printf(f->code, "if (vresult == Qnil) vresult = rb_ary_new();\n");
 
1862
              Printf(f->code, "else vresult = SWIG_Ruby_AppendOutput( "
 
1863
                     "rb_ary_new(), vresult);\n");
 
1864
            }
 
1865
        }
 
1866
      }
1242
1867
 
1243
1868
    /* Dump argument output code; */
1244
1869
    Printv(f->code, outarg, NIL);
1369
1994
    Wrapper_add_local(f, "ii", "int ii");
1370
1995
 
1371
1996
    if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) {
 
1997
      maxargs += 1;
1372
1998
      Printf(f->code, "argc = nargs + 1;\n");
1373
1999
      Printf(f->code, "argv[0] = self;\n");
1374
 
      Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs + 1);
1375
 
      Printf(f->code, "for (ii = 1; (ii < argc); ii++) {\n");
 
2000
      Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
 
2001
      Printf(f->code, "for (ii = 1; (ii < argc); ++ii) {\n");
1376
2002
      Printf(f->code, "argv[ii] = args[ii-1];\n");
1377
2003
      Printf(f->code, "}\n");
1378
2004
    } else {
1379
2005
      Printf(f->code, "argc = nargs;\n");
1380
2006
      Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
1381
 
      Printf(f->code, "for (ii = 0; (ii < argc); ii++) {\n");
 
2007
      Printf(f->code, "for (ii = 0; (ii < argc); ++ii) {\n");
1382
2008
      Printf(f->code, "argv[ii] = args[ii];\n");
1383
2009
      Printf(f->code, "}\n");
1384
2010
    }
1385
2011
 
1386
2012
    Replaceall(dispatch, "$args", "nargs, args, self");
1387
2013
    Printv(f->code, dispatch, "\n", NIL);
1388
 
    Printf(f->code, "fail:\n");
1389
 
    Printf(f->code, "rb_raise(rb_eArgError, \"No matching function for overloaded '%s'\");\n", symname);
1390
 
    Printf(f->code, "return Qnil;\n");
 
2014
 
 
2015
 
 
2016
    
 
2017
    // Generate prototype list, go to first node
 
2018
    Node *sibl = n;
 
2019
 
 
2020
    String* type = SwigType_str(Getattr(sibl,"type"),NULL);
 
2021
 
 
2022
    while (Getattr(sibl, "sym:previousSibling"))
 
2023
      sibl = Getattr(sibl, "sym:previousSibling");      // go all the way up
 
2024
 
 
2025
    // Constructors will be treated specially
 
2026
    const bool isCtor = Cmp(Getattr(sibl,"feature:new"), "1") == 0;
 
2027
    const bool isMethod = ( Cmp(Getattr(sibl, "ismember"), "1") == 0 &&
 
2028
                            (!isCtor) );
 
2029
 
 
2030
    // Construct real method name
 
2031
    String* methodName = NewString("");
 
2032
    if ( isMethod ) 
 
2033
      Printv( methodName, Getattr(parentNode(sibl),"sym:name"), ".", NIL );
 
2034
    Append( methodName, Getattr(sibl,"sym:name" ) );
 
2035
    if ( isCtor ) Append( methodName, ".new" ); 
 
2036
 
 
2037
    // Generate prototype list
 
2038
    String *protoTypes = NewString("");
 
2039
    do {
 
2040
      Append( protoTypes, "\n\"    ");
 
2041
      if ( !isCtor )  Printv( protoTypes, type, " ", NIL );
 
2042
      Printv(protoTypes, methodName, NIL );
 
2043
      Parm* p = Getattr(sibl, "wrap:parms");
 
2044
      if (p && (current == MEMBER_FUNC || current == MEMBER_VAR || 
 
2045
                ctor_director) )
 
2046
        p = nextSibling(p); // skip self
 
2047
      Append( protoTypes, "(" );
 
2048
      while(p)
 
2049
        {
 
2050
          Append( protoTypes, SwigType_str(Getattr(p,"type"), Getattr(p,"name")) );
 
2051
          if ( ( p = nextSibling(p)) ) Append(protoTypes, ", ");
 
2052
        }
 
2053
      Append( protoTypes, ")\\n\"" );
 
2054
    } while ((sibl = Getattr(sibl, "sym:nextSibling")));
 
2055
 
 
2056
    Append(f->code, "fail:\n");
 
2057
    Printf(f->code, "Ruby_Format_OverloadedError( argc, %d, \"%s\", %s);\n", 
 
2058
           maxargs, methodName, protoTypes);
 
2059
    Append(f->code, "\nreturn Qnil;\n");
 
2060
 
 
2061
    Delete(methodName);
 
2062
    Delete(type);
 
2063
    Delete(protoTypes);
 
2064
 
1391
2065
    Printv(f->code, "}\n", NIL);
1392
2066
    Wrapper_print(f, f_wrappers);
1393
2067
    create_command(n, Char(symname));
1403
2077
   * --------------------------------------------------------------------- */
1404
2078
 
1405
2079
  virtual int variableWrapper(Node *n) {
 
2080
    String* docs = docstring(n, AUTODOC_GETTER);
 
2081
    Printf(f_wrappers, "%s", docs);
 
2082
    Delete(docs);
 
2083
 
1406
2084
 
1407
2085
    char *name = GetChar(n, "name");
1408
2086
    char *iname = GetChar(n, "sym:name");
1416
2094
 
1417
2095
    /* create getter */
1418
2096
    int addfail = 0;
1419
 
    getfname = Swig_name_get(iname);
 
2097
    String *getname = Swig_name_get(iname);
 
2098
    getfname = Swig_name_wrapper(getname);
1420
2099
    Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL);
1421
2100
    Printf(getf->def, "VALUE self");
1422
2101
    Printf(getf->def, ") {");
1445
2124
      setfname = NewString("NULL");
1446
2125
    } else {
1447
2126
      /* create setter */
1448
 
      setfname = Swig_name_set(iname);
 
2127
      String* docs = docstring(n, AUTODOC_SETTER);
 
2128
      Printf(f_wrappers, "%s", docs);
 
2129
      Delete(docs);
 
2130
 
 
2131
      String *setname = Swig_name_set(iname);
 
2132
      setfname = Swig_name_wrapper(setname);
1449
2133
      Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL);
1450
2134
      Printf(setf->def, "VALUE _val) {");
1451
2135
      tm = Swig_typemap_lookup_new("varin", n, name, 0);
1463
2147
      Printv(setf->code, tab4, "return Qnil;\n", NIL);
1464
2148
      Printf(setf->code, "}\n");
1465
2149
      Wrapper_print(setf, f_wrappers);
 
2150
      Delete(setname);
1466
2151
    }
1467
2152
 
1468
2153
    /* define accessor method */
1502
2187
      Delete(s);
1503
2188
      break;
1504
2189
    }
 
2190
    Delete(getname);
1505
2191
    Delete(getfname);
1506
2192
    Delete(setfname);
1507
2193
    DelWrapper(setf);
1734
2420
   * ---------------------------------------------------------------------- */
1735
2421
 
1736
2422
  virtual int classHandler(Node *n) {
 
2423
    String* docs = docstring(n, AUTODOC_CLASS);
 
2424
    Printf(f_wrappers, "%s", docs);
 
2425
    Delete(docs);
1737
2426
 
1738
2427
    String *name = Getattr(n, "name");
1739
2428
    String *symname = Getattr(n, "sym:name");
1749
2438
    Printv(klass->type, Getattr(n, "classtype"), NIL);
1750
2439
    Printv(f_wrappers, "swig_class c", valid_name, ";\n\n", NIL);
1751
2440
    Printv(klass->init, "\n", tab4, NIL);
 
2441
 
 
2442
    if (!useGlobalModule) {
 
2443
      Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", $super);\n", NIL);
 
2444
    } else {
 
2445
      Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name, 
 
2446
             "\", $super);\n", NIL);
 
2447
    }
 
2448
 
1752
2449
    if (multipleInheritance) {
1753
 
      if (!useGlobalModule) {
1754
 
        Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", rb_cObject);\n", NIL);
1755
 
      } else {
1756
 
        Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name, "\", rb_cObject);\n", NIL);
1757
 
      }
1758
2450
      Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\n", NIL);
1759
 
    } else {
1760
 
      if (!useGlobalModule) {
1761
 
        Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", $super);\n", NIL);
1762
 
      } else {
1763
 
        Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name, "\", $super);\n", NIL);
1764
 
      }
1765
2451
    }
1766
2452
 
1767
2453
    SwigType *tt = NewString(name);
1825
2511
 
1826
2512
  virtual int memberfunctionHandler(Node *n) {
1827
2513
    current = MEMBER_FUNC;
 
2514
 
 
2515
    String* docs = docstring(n, AUTODOC_METHOD);
 
2516
    Printf(f_wrappers, "%s", docs);
 
2517
    Delete(docs);
 
2518
 
1828
2519
    Language::memberfunctionHandler(n);
1829
2520
    current = NO_CPP;
1830
2521
    return SWIG_OK;
1891
2582
      Delete(self);
1892
2583
    }
1893
2584
 
 
2585
 
 
2586
 
1894
2587
    /* Now do the instance initialize method */
 
2588
    String* docs = docstring(n, AUTODOC_CTOR);
 
2589
    Printf(f_wrappers, "%s", docs);
 
2590
    Delete(docs);
 
2591
 
1895
2592
    current = CONSTRUCTOR_INITIALIZE;
1896
2593
    Swig_name_register((String_or_char *) "construct", (String_or_char *) "new_%c");
1897
2594
    Language::constructorHandler(n);
1926
2623
   * -------------------------------------------------------------------- */
1927
2624
 
1928
2625
  virtual int destructorHandler(Node *n) {
 
2626
 
 
2627
    /* Do no spit free function if user defined his own for this class */
 
2628
    Node *pn = Swig_methodclass(n);
 
2629
    String *freefunc = Getattr(pn, "feature:freefunc");
 
2630
    if (freefunc) return SWIG_OK;
 
2631
 
1929
2632
    current = DESTRUCTOR;
1930
2633
    Language::destructorHandler(n);
1931
2634
 
1932
 
    String *freefunc = NewString("");
 
2635
    freefunc = NewString("");
1933
2636
    String *freebody = NewString("");
1934
2637
    String *pname0 = Swig_cparm_name(0, 0);
1935
2638
 
1938
2641
 
1939
2642
    /* Check to see if object tracking is activated for the class
1940
2643
       that owns this destructor. */
1941
 
    Node *pn = Swig_methodclass(n);
1942
2644
    if (GetFlag(pn, "feature:trackobjects")) {
1943
2645
      Printf(freebody, "SWIG_RubyRemoveTracking(%s);\n", pname0);
1944
2646
      Printv(freebody, tab4, NIL);
1983
2685
   * -------------------------------------------------------------------- */
1984
2686
 
1985
2687
  virtual int membervariableHandler(Node *n) {
 
2688
    String* docs = docstring(n, AUTODOC_GETTER);
 
2689
    Printf(f_wrappers, "%s", docs);
 
2690
    Delete(docs);
 
2691
 
 
2692
    if (is_assignable(n)) {
 
2693
      String* docs = docstring(n, AUTODOC_SETTER);
 
2694
      Printf(f_wrappers, "%s", docs);
 
2695
      Delete(docs);
 
2696
    }
 
2697
 
1986
2698
    current = MEMBER_VAR;
1987
2699
    Language::membervariableHandler(n);
1988
2700
    current = NO_CPP;
1996
2708
   * ---------------------------------------------------------------------- */
1997
2709
 
1998
2710
  virtual int staticmemberfunctionHandler(Node *n) {
 
2711
    String* docs = docstring(n, AUTODOC_STATICFUNC);
 
2712
    Printf(f_wrappers, "%s", docs);
 
2713
    Delete(docs);
 
2714
 
1999
2715
    current = STATIC_FUNC;
2000
2716
    Language::staticmemberfunctionHandler(n);
2001
2717
    current = NO_CPP;
2009
2725
   * --------------------------------------------------------------------- */
2010
2726
 
2011
2727
  virtual int memberconstantHandler(Node *n) {
 
2728
    String* docs = docstring(n, AUTODOC_STATICFUNC);
 
2729
    Printf(f_wrappers, "%s", docs);
 
2730
    Delete(docs);
 
2731
 
2012
2732
    current = CLASS_CONST;
2013
2733
    Language::memberconstantHandler(n);
2014
2734
    current = NO_CPP;
2020
2740
   * --------------------------------------------------------------------- */
2021
2741
 
2022
2742
  virtual int staticmembervariableHandler(Node *n) {
 
2743
    String* docs = docstring(n, AUTODOC_GETTER);
 
2744
    Printf(f_wrappers, "%s", docs);
 
2745
    Delete(docs);
 
2746
 
 
2747
    if (is_assignable(n)) {
 
2748
      String* docs = docstring(n, AUTODOC_SETTER);
 
2749
      Printf(f_wrappers, "%s", docs);
 
2750
      Delete(docs);
 
2751
    }
 
2752
 
2023
2753
    current = STATIC_VAR;
2024
2754
    Language::staticmembervariableHandler(n);
2025
2755
    current = NO_CPP;
2122
2852
   *
2123
2853
   * --------------------------------------------------------------- */
2124
2854
 
2125
 
  void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args) {
 
2855
  void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args, bool initstack) {
2126
2856
    Wrapper *body = NewWrapper();
2127
2857
    Wrapper *rescue = NewWrapper();
2128
2858
 
2147
2877
        Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName);
2148
2878
        Wrapper_add_localv(body, "args", "Swig::body_args *", "args", "= reinterpret_cast<Swig::body_args *>(data)", NIL);
2149
2879
        Wrapper_add_localv(body, "result", "VALUE", "result", "= Qnil", NIL);
2150
 
        Printf(body->code, "%s++;\n", depthCountName, NIL);
 
2880
        Printf(body->code, "%s++;\n", depthCountName);
2151
2881
        Printv(body->code, "result = rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL);
2152
 
        Printf(body->code, "%s--;\n", depthCountName, NIL);
 
2882
        Printf(body->code, "%s--;\n", depthCountName);
2153
2883
        Printv(body->code, "return result;\n", NIL);
2154
2884
        Printv(body->code, "}", NIL);
2155
2885
 
2156
2886
        // Exception handler
2157
2887
        Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName);
2158
2888
        Replaceall(tm, "$error", "error");
2159
 
        Printf(rescue->code, "if (%s == 1) ", depthCountName);
 
2889
        Printf(rescue->code, "%s--;\n", depthCountName);
 
2890
        Printf(rescue->code, "if (%s == 0) ", depthCountName);
2160
2891
        Printv(rescue->code, Str(tm), "\n", NIL);
2161
 
        Printf(rescue->code, "%s--;\n", depthCountName);
2162
2892
        Printv(rescue->code, "rb_exc_raise(error);\n", NIL);
2163
2893
        Printv(rescue->code, "}", NIL);
2164
2894
      }
2177
2907
      } else {
2178
2908
        Printv(w->code, "args.argv = 0;\n", NIL);
2179
2909
      }
2180
 
      Printf(w->code, "result = rb_protect(PROTECTFUNC(%s), reinterpret_cast<VALUE>(&args), &status);\n", bodyName, rescueName);
 
2910
      Printf(w->code, "result = rb_protect(PROTECTFUNC(%s), reinterpret_cast<VALUE>(&args), &status);\n", bodyName);
 
2911
      if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
2181
2912
      Printf(w->code, "if (status) {\n");
2182
2913
      Printf(w->code, "VALUE lastErr = rb_gv_get(\"$!\");\n");
2183
2914
      Printf(w->code, "%s(reinterpret_cast<VALUE>(&args), lastErr);\n", rescueName);
2194
2925
      } else {
2195
2926
        Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", methodName);
2196
2927
      }
 
2928
      if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
2197
2929
    }
2198
2930
 
2199
2931
    // Clean up
2225
2957
    int status = SWIG_OK;
2226
2958
    int idx;
2227
2959
    bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
 
2960
    bool asvoid = checkAttribute( n, "feature:numoutputs", "0") ? true : false;
 
2961
    bool initstack = checkAttribute( n, "feature:initstack", "1") ? true : false;
2228
2962
 
2229
2963
    if (Cmp(storage, "virtual") == 0) {
2230
2964
      if (Cmp(value, "0") == 0) {
2305
3039
    Append(w->def, " {");
2306
3040
    Append(declaration, ";\n");
2307
3041
 
 
3042
    if (initstack && !(ignored_method && !pure_virtual)) {
 
3043
      Append(w->def, "\nSWIG_INIT_STACK;\n");
 
3044
    }
 
3045
 
2308
3046
    /* declare method return value 
2309
3047
     * if the return value is a reference or const reference, a specialized typemap must
2310
3048
     * handle it, including declaration of c_result ($result).
2342
3080
      Swig_typemap_attach_parms("directorin", l, 0);
2343
3081
      Swig_typemap_attach_parms("directorargout", l, w);
2344
3082
 
2345
 
      int num_arguments = emit_num_arguments(l);
2346
 
      int i;
2347
3083
      char source[256];
2348
3084
 
2349
3085
      int outputs = 0;
2350
 
      if (!is_void)
 
3086
      if (!is_void && !asvoid)
2351
3087
        outputs++;
2352
3088
 
2353
3089
      /* build argument list and type conversion string */
2354
 
      for (i = 0, idx = 0, p = l; i < num_arguments; i++) {
 
3090
      idx = 0; p = l;
 
3091
      while ( p ) {
2355
3092
 
2356
 
        while (Getattr(p, "tmap:ignore")) {
 
3093
        if (Getattr(p, "tmap:ignore")) {
2357
3094
          p = Getattr(p, "tmap:ignore:next");
 
3095
          continue;
2358
3096
        }
2359
3097
 
2360
3098
        if (Getattr(p, "tmap:directorargout") != 0)
2361
3099
          outputs++;
2362
3100
 
 
3101
        if ( checkAttribute( p, "tmap:in:numinputs", "0") )
 
3102
          {
 
3103
            p = Getattr(p, "tmap:in:next");
 
3104
            continue;
 
3105
          }
 
3106
 
2363
3107
        String *parameterName = Getattr(p, "name");
2364
3108
        String *parameterType = Getattr(p, "type");
2365
3109
 
2450
3194
      Printv(w->code, wrap_args, NIL);
2451
3195
 
2452
3196
      /* pass the method call on to the Ruby object */
2453
 
      exceptionSafeMethodCall(classname, n, w, idx, arglist);
 
3197
      exceptionSafeMethodCall(classname, n, w, idx, arglist, initstack);
2454
3198
 
2455
3199
      /*
2456
3200
       * Ruby method may return a simple object, or an Array of objects.
2466
3210
      if (outputs > 1) {
2467
3211
        Wrapper_add_local(w, "output", "VALUE output");
2468
3212
        Printf(w->code, "if (TYPE(result) != T_ARRAY) {\n");
2469
 
        Printf(w->code, "throw Swig::DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n");
 
3213
        Printf(w->code, "Ruby_DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n");
2470
3214
        Printf(w->code, "}\n");
2471
3215
      }
2472
3216
 
2488
3232
          Delete(name);
2489
3233
        }
2490
3234
        if (tm != 0) {
2491
 
          if (outputs > 1) {
 
3235
          if (outputs > 1 && !asvoid ) {
2492
3236
            Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
2493
3237
            Replaceall(tm, "$input", "output");
2494
3238
          } else {