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

« back to all changes in this revision

Viewing changes to Source/Modules/ruby.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Thom May
  • Date: 2004-08-02 15:57:10 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040802155710-bm292q1d6x6tw7gc
Tags: 1.3.21-5ubuntu1
Fix linking for ruby, python, perl and tcl bindings

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
 * Ruby module for SWIG
 
3
 *
 
4
 * $Header: /cvsroot/SWIG/Source/Modules/ruby.cxx,v 1.47 2003/12/22 17:23:02 ljohnson Exp $
 
5
 *
 
6
 * Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
 
7
 * Copyright (C) 2000  Information-technology Promotion Agency, Japan
 
8
 *
 
9
 * Masaki Fukushima
 
10
 *
 
11
 ********************************************************************/
 
12
 
 
13
char cvsroot_ruby_cxx[] = "$Header: /cvsroot/SWIG/Source/Modules/ruby.cxx,v 1.47 2003/12/22 17:23:02 ljohnson Exp $";
 
14
 
 
15
#include "swigmod.h"
 
16
#define SWIG_PROTECTED_TARGET_METHODS 1
 
17
 
 
18
#ifndef MACSWIG
 
19
#include "swigconfig.h"
 
20
#endif
 
21
 
 
22
#include <ctype.h>
 
23
#include <string.h>
 
24
#include <limits.h> /* for INT_MAX */
 
25
 
 
26
 class RClass {
 
27
 private:
 
28
  String *temp;
 
29
 public:
 
30
  String *name;    /* class name (renamed) */
 
31
  String *cname;   /* original C class/struct name */
 
32
  String *mname;   /* Mangled name */
 
33
  
 
34
  /**
 
35
   * The C variable name used in the SWIG-generated wrapper code to refer to
 
36
   * this class; usually it is of the form "cClassName.klass", where cClassName
 
37
   * is a swig_class struct instance and klass is a member of that struct.
 
38
   */
 
39
  String *vname;
 
40
 
 
41
  /**
 
42
   * The C variable name used in the SWIG-generated wrapper code to refer to
 
43
   * the module that implements this class's methods (when we're trying to
 
44
   * support C++ multiple inheritance). Usually it is of the form
 
45
   * "cClassName.mImpl", where cClassName is a swig_class struct instance
 
46
   * and mImpl is a member of that struct.
 
47
   */
 
48
  String *mImpl;
 
49
 
 
50
  String *type;
 
51
  String *prefix;
 
52
  String *header;
 
53
  String *init;
 
54
 
 
55
  int constructor_defined;
 
56
  int destructor_defined;
 
57
 
 
58
  RClass() {
 
59
    temp = NewString("");
 
60
    name = NewString("");
 
61
    cname = NewString("");
 
62
    mname = NewString("");
 
63
    vname = NewString("");
 
64
    mImpl = NewString("");
 
65
    type = NewString("");
 
66
    prefix = NewString("");
 
67
    header = NewString("");
 
68
    init = NewString("");
 
69
    constructor_defined = 0;
 
70
    destructor_defined = 0;
 
71
  }
 
72
  
 
73
  ~RClass() {
 
74
    Delete(name);
 
75
    Delete(cname);
 
76
    Delete(vname);
 
77
    Delete(mImpl);
 
78
    Delete(mname);
 
79
    Delete(type);
 
80
    Delete(prefix);
 
81
    Delete(header);
 
82
    Delete(init);
 
83
    Delete(temp);
 
84
  }
 
85
 
 
86
  void set_name(const String_or_char *cn, const String_or_char *rn, const String_or_char *valn) {
 
87
    /* Original C/C++ class (or struct) name */
 
88
    Clear(cname);
 
89
    Append(cname,cn);
 
90
 
 
91
    /* Mangled name */
 
92
    Delete(mname);
 
93
    mname = Swig_name_mangle(cname);
 
94
 
 
95
    /* Renamed class name */
 
96
    Clear(name);
 
97
    Append(name,valn);
 
98
 
 
99
    /* Variable name for the VALUE that refers to the Ruby Class object */
 
100
    Clear(vname);
 
101
    Printf(vname, "c%s.klass", name);
 
102
    
 
103
    /* Variable name for the VALUE that refers to the Ruby Class object */
 
104
    Clear(mImpl);
 
105
    Printf(mImpl, "c%s.mImpl", name);
 
106
 
 
107
    /* Prefix */
 
108
    Clear(prefix);
 
109
    Printv(prefix,(rn ? rn : cn), "_", NIL);
 
110
  }
 
111
 
 
112
  char *strip(const String_or_char *s) {
 
113
    Clear(temp);
 
114
    Append(temp, s);
 
115
    if (Strncmp(s, prefix, Len(prefix)) == 0) {
 
116
      Replaceall(temp,prefix,"");
 
117
    }
 
118
    return Char(temp);
 
119
  }
 
120
};
 
121
 
 
122
 
 
123
static const char *
 
124
usage = "\
 
125
Ruby Options (available with -ruby)\n\
 
126
     -ldflags        - Print runtime libraries to link with\n\
 
127
     -globalmodule   - Wrap everything into the global module\n\
 
128
     -minherit       - Attempt to support multiple inheritance\n\
 
129
     -feature <name> - Set feature name to <name> (used by `require')\n";
 
130
 
 
131
 
 
132
#define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0)
 
133
#define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0))
 
134
 
 
135
 
 
136
class RUBY : public Language {
 
137
private:
 
138
 
 
139
  String *module;
 
140
  String *modvar;
 
141
  String *feature;
 
142
  int current;
 
143
  Hash *classes;                /* key=cname val=RClass */
 
144
  RClass *klass;                /* Currently processing class */
 
145
  Hash *special_methods;        /* Python style special method name table */
 
146
 
 
147
  File *f_directors;
 
148
  File *f_directors_h;
 
149
  File *f_runtime;
 
150
  File *f_runtime_h;
 
151
  File *f_header;
 
152
  File *f_wrappers;
 
153
  File *f_init;
 
154
 
 
155
  bool use_kw;
 
156
  bool useGlobalModule;
 
157
  bool multipleInheritance;
 
158
 
 
159
  // Wrap modes
 
160
  enum {
 
161
    NO_CPP,
 
162
    MEMBER_FUNC,
 
163
    CONSTRUCTOR_ALLOCATE,
 
164
    CONSTRUCTOR_INITIALIZE,
 
165
    DESTRUCTOR,
 
166
    MEMBER_VAR,
 
167
    CLASS_CONST,
 
168
    STATIC_FUNC,
 
169
    STATIC_VAR
 
170
  };
 
171
 
 
172
public:
 
173
 
 
174
  /* ---------------------------------------------------------------------
 
175
   * RUBY()
 
176
   *
 
177
   * Initialize member data
 
178
   * --------------------------------------------------------------------- */
 
179
 
 
180
  RUBY() {
 
181
    module = 0;
 
182
    modvar = 0;
 
183
    feature = 0;
 
184
    current = NO_CPP;
 
185
    classes = 0;
 
186
    klass = 0;
 
187
    special_methods = 0;
 
188
    f_runtime = 0;
 
189
    f_header = 0;
 
190
    f_wrappers = 0;
 
191
    f_init = 0;
 
192
    use_kw = false;
 
193
    useGlobalModule = false;
 
194
    multipleInheritance = false;
 
195
  }
 
196
  
 
197
  /* ---------------------------------------------------------------------
 
198
   * main()
 
199
   *
 
200
   * Parse command line options and initializes variables.
 
201
   * --------------------------------------------------------------------- */
 
202
 
 
203
  virtual void main(int argc, char *argv[]) {
 
204
 
 
205
    /* Set location of SWIG library */
 
206
    SWIG_library_directory("ruby");
 
207
    
 
208
    /* Look for certain command line options */
 
209
    for (int i = 1; i < argc; i++) {
 
210
      if (argv[i]) {
 
211
        if (strcmp(argv[i],"-feature") == 0) {
 
212
          if (argv[i+1]) {
 
213
            char *name = argv[i+1];
 
214
            feature = NewString(name);
 
215
            Swig_mark_arg(i);
 
216
            Swig_mark_arg(i+1);
 
217
            i++;
 
218
          } else {
 
219
            Swig_arg_error();
 
220
          }
 
221
        } else if (strcmp(argv[i],"-globalmodule") == 0) {
 
222
          useGlobalModule = true;
 
223
          Swig_mark_arg(i);
 
224
        } else if (strcmp(argv[i],"-minherit") == 0) {
 
225
          multipleInheritance = true;
 
226
          Swig_mark_arg(i);
 
227
        } else if (strcmp(argv[i],"-help") == 0) {
 
228
          Printf(stderr,"%s\n", usage);
 
229
        } else if (strcmp (argv[i],"-ldflags") == 0) {
 
230
          printf("%s\n", SWIG_RUBY_RUNTIME);
 
231
          SWIG_exit (EXIT_SUCCESS);
 
232
        }
 
233
      }
 
234
    }
 
235
 
 
236
    /* Add a symbol to the parser for conditional compilation */
 
237
    Preprocessor_define("SWIGRUBY 1", 0);
 
238
    
 
239
    /* Add typemap definitions */
 
240
    SWIG_typemap_lang("ruby");
 
241
    SWIG_config_file("ruby.swg");
 
242
    allow_overloading();
 
243
  }
 
244
 
 
245
  /**
 
246
   * Generate initialization code to define the Ruby module(s),
 
247
   * accounting for nested modules as necessary.
 
248
   */
 
249
  void defineRubyModule() {
 
250
    List *modules = Split(module,':',INT_MAX);
 
251
    if (modules != 0 && Len(modules) > 0) {
 
252
      String *mv = 0;
 
253
      Iterator m;
 
254
      m = First(modules);
 
255
      while (m.item) {
 
256
        if (Len(m.item) > 0) {
 
257
          if (mv != 0) {
 
258
            Printv(f_init, tab4, modvar,
 
259
              " = rb_define_module_under(", modvar, ", \"", m.item, "\");\n", NIL);
 
260
          } else {
 
261
            Printv(f_init, tab4, modvar,
 
262
              " = rb_define_module(\"", m.item, "\");\n", NIL);
 
263
            mv = NewString(modvar);
 
264
          }
 
265
        }
 
266
        m = Next(m);
 
267
      }
 
268
      Delete(mv);
 
269
      Delete(modules);
 
270
    }
 
271
  }
 
272
 
 
273
  void registerMagicMethods() {
 
274
 
 
275
    special_methods = NewHash();
 
276
 
 
277
    /* Python style special method name. */
 
278
    /* Basic */
 
279
    Setattr(special_methods, "__repr__", "inspect");
 
280
    Setattr(special_methods, "__str__", "to_s");
 
281
    Setattr(special_methods, "__cmp__", "<=>");
 
282
    Setattr(special_methods, "__hash__", "hash");
 
283
    Setattr(special_methods, "__nonzero__", "nonzero?");
 
284
  
 
285
    /* Callable */
 
286
    Setattr(special_methods, "__call__", "call");
 
287
  
 
288
    /* Collection */
 
289
    Setattr(special_methods, "__len__", "length");
 
290
    Setattr(special_methods, "__getitem__", "[]");
 
291
    Setattr(special_methods, "__setitem__", "[]=");
 
292
  
 
293
    /* Operators */
 
294
    Setattr(special_methods, "__add__", "+");
 
295
    Setattr(special_methods, "__pos__", "+@");
 
296
    Setattr(special_methods, "__sub__", "-");
 
297
    Setattr(special_methods, "__neg__", "-@");
 
298
    Setattr(special_methods, "__mul__", "*");
 
299
    Setattr(special_methods, "__div__", "/");
 
300
    Setattr(special_methods, "__mod__", "%");
 
301
    Setattr(special_methods, "__lshift__", "<<");
 
302
    Setattr(special_methods, "__rshift__", ">>");
 
303
    Setattr(special_methods, "__and__", "&");
 
304
    Setattr(special_methods, "__or__", "|");
 
305
    Setattr(special_methods, "__xor__", "^");
 
306
    Setattr(special_methods, "__invert__", "~");
 
307
    Setattr(special_methods, "__lt__", "<");
 
308
    Setattr(special_methods, "__le__", "<=");
 
309
    Setattr(special_methods, "__gt__", ">");
 
310
    Setattr(special_methods, "__ge__", ">=");
 
311
    Setattr(special_methods, "__eq__", "==");
 
312
 
 
313
    /* Other numeric */
 
314
    Setattr(special_methods, "__divmod__", "divmod");
 
315
    Setattr(special_methods, "__pow__", "**");
 
316
    Setattr(special_methods, "__abs__", "abs");
 
317
    Setattr(special_methods, "__int__", "to_i");
 
318
    Setattr(special_methods, "__float__", "to_f");
 
319
    Setattr(special_methods, "__coerce__", "coerce");
 
320
  }
 
321
 
 
322
  /* ---------------------------------------------------------------------
 
323
   * top()
 
324
   * --------------------------------------------------------------------- */
 
325
 
 
326
  virtual int top(Node *n) {
 
327
 
 
328
    /**
 
329
     * See if any Ruby module options have been specified as options
 
330
     * to the %module directive.
 
331
     */
 
332
    Node *swigModule = Getattr(n, "module");
 
333
    if (swigModule) {
 
334
      Node *options = Getattr(swigModule, "options");
 
335
      if (options) {
 
336
        if (Getattr(options, "directors")) {
 
337
          allow_directors();
 
338
        }
 
339
        if (Getattr(options, "dirprot")) {
 
340
          allow_dirprot();
 
341
        }
 
342
        if (Getattr(options, "ruby_globalmodule")) {
 
343
          useGlobalModule = true;
 
344
        }
 
345
        if (Getattr(options, "ruby_minherit")) {
 
346
          multipleInheritance = true;
 
347
        }
 
348
      }
 
349
    }
 
350
 
 
351
    /* Set comparison with none for ConstructorToFunction */
 
352
    setSubclassInstanceCheck(NewString("CLASS_OF(self) != Qnil")); // FIXME
 
353
    // setSubclassInstanceCheck(NewString("CLASS_OF(self) != cFoo.klass"));
 
354
 
 
355
    /* Initialize all of the output files */
 
356
    String *outfile = Getattr(n,"outfile");
 
357
    String *outfile_h = Getattr(n, "outfile_h");
 
358
 
 
359
    f_runtime = NewFile(outfile,"w");
 
360
    if (!f_runtime) {
 
361
      Printf(stderr,"*** Can't open '%s'\n", outfile);
 
362
      SWIG_exit(EXIT_FAILURE);
 
363
    }
 
364
 
 
365
    if (directorsEnabled()) {
 
366
      f_runtime_h = NewFile(outfile_h,"w");
 
367
      if (!f_runtime_h) {
 
368
        Printf(stderr,"*** Can't open '%s'\n", outfile_h);
 
369
        SWIG_exit(EXIT_FAILURE);
 
370
      }
 
371
    }
 
372
 
 
373
    f_init = NewString("");
 
374
    f_header = NewString("");
 
375
    f_wrappers = NewString("");
 
376
    f_directors_h = NewString("");
 
377
    f_directors = NewString("");
 
378
 
 
379
    /* Register file targets with the SWIG file handler */
 
380
    Swig_register_filebyname("header",f_header);
 
381
    Swig_register_filebyname("wrapper",f_wrappers);
 
382
    Swig_register_filebyname("runtime",f_runtime);
 
383
    Swig_register_filebyname("init",f_init);
 
384
    Swig_register_filebyname("director",f_directors);
 
385
    Swig_register_filebyname("director_h",f_directors_h);
 
386
 
 
387
    modvar = 0;
 
388
    current = NO_CPP;
 
389
    klass = 0;
 
390
    classes = NewHash();
 
391
    
 
392
    registerMagicMethods();
 
393
 
 
394
    Swig_banner(f_runtime);
 
395
 
 
396
    if (NoInclude) {
 
397
      Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
 
398
    }
 
399
 
 
400
    if (directorsEnabled()) {
 
401
      Printf(f_runtime,"#define SWIG_DIRECTORS\n");
 
402
    }
 
403
 
 
404
    /* typedef void *VALUE */
 
405
    SwigType *value = NewSwigType(T_VOID);
 
406
    SwigType_add_pointer(value);
 
407
    SwigType_typedef(value,(char*)"VALUE");
 
408
    Delete(value);
 
409
 
 
410
    /* Set module name */
 
411
    set_module(Char(Getattr(n,"name")));
 
412
 
 
413
    if (directorsEnabled()) {
 
414
      Swig_banner(f_directors_h);
 
415
      Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
 
416
      Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
 
417
      Printf(f_directors_h, "class Swig::Director;\n\n");
 
418
      Swig_insert_file("director.swg", f_directors);
 
419
      Printf(f_directors, "\n\n");
 
420
      Printf(f_directors, "/* ---------------------------------------------------\n");
 
421
      Printf(f_directors, " * C++ director class methods\n");
 
422
      Printf(f_directors, " * --------------------------------------------------- */\n\n");
 
423
      Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
 
424
    }
 
425
 
 
426
    Printf(f_header,"#define SWIG_init    Init_%s\n", feature);
 
427
    Printf(f_header,"#define SWIG_name    \"%s\"\n\n", module);
 
428
    Printf(f_header,"static VALUE %s;\n", modvar);
 
429
 
 
430
    /* Start generating the initialization function */
 
431
    Printv(f_init,
 
432
           "\n",
 
433
           "#ifdef __cplusplus\n",
 
434
           "extern \"C\"\n",
 
435
           "#endif\n",
 
436
           "SWIGEXPORT(void) Init_", feature, "(void) {\n",
 
437
           "int i;\n",
 
438
           "\n",
 
439
           NIL);
 
440
 
 
441
    Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL);
 
442
 
 
443
    if (!useGlobalModule)
 
444
      defineRubyModule();
 
445
 
 
446
    Printv(f_init,
 
447
           "\n",
 
448
           "for (i = 0; swig_types_initial[i]; i++) {\n",
 
449
           "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n",
 
450
           "SWIG_define_class(swig_types[i]);\n",
 
451
           "}\n",
 
452
           NIL);
 
453
    Printf(f_init,"\n");
 
454
 
 
455
    Language::top(n);
 
456
 
 
457
    /* Finish off our init function */
 
458
    Printf(f_init,"}\n");
 
459
    SwigType_emit_type_table(f_runtime,f_wrappers);
 
460
 
 
461
    /* Close all of the files */
 
462
    Dump(f_header,f_runtime);
 
463
 
 
464
    if (directorsEnabled()) {
 
465
      Dump(f_directors, f_runtime);
 
466
      Dump(f_directors_h, f_runtime_h);
 
467
      Printf(f_runtime_h, "\n");
 
468
      Printf(f_runtime_h, "#endif\n");
 
469
      Close(f_runtime_h);
 
470
    }
 
471
 
 
472
    Dump(f_wrappers,f_runtime);
 
473
    Wrapper_pretty_print(f_init,f_runtime);
 
474
 
 
475
    Delete(f_header);
 
476
    Delete(f_wrappers);
 
477
    Delete(f_init);
 
478
    Close(f_runtime);
 
479
    Delete(f_runtime);
 
480
 
 
481
    return SWIG_OK;
 
482
  }
 
483
 
 
484
  /* -----------------------------------------------------------------------------
 
485
   * importDirective()
 
486
   * ----------------------------------------------------------------------------- */
 
487
  
 
488
  virtual int importDirective(Node *n) {
 
489
    String *modname = Getattr(n,"module");
 
490
    if (modname) {
 
491
      Printf(f_init,"rb_require(\"%s\");\n", modname);
 
492
    }
 
493
    return Language::importDirective(n);
 
494
  }
 
495
 
 
496
  /* ---------------------------------------------------------------------
 
497
   * set_module(const char *mod_name)
 
498
   *
 
499
   * Sets the module name.  Does nothing if it's already set (so it can
 
500
   * be overridden as a command line option).
 
501
   *---------------------------------------------------------------------- */
 
502
 
 
503
  void set_module(const char *s) {
 
504
    String *mod_name = NewString(s);
 
505
    if (module == 0) {
 
506
      /* Start with the empty string */
 
507
      module = NewString("");
 
508
      
 
509
      /* Account for nested modules */
 
510
      List *modules = Split(mod_name,':',INT_MAX);
 
511
      if (modules != 0 && Len(modules) > 0) {
 
512
        String *last = 0;
 
513
        Iterator m = First(modules);
 
514
        while (m.item) {
 
515
          if (Len(m.item) > 0) {
 
516
            String *cap = NewString(m.item);
 
517
            (Char(cap))[0] = toupper((Char(cap))[0]);
 
518
            if (last != 0) {
 
519
              Append(module, "::");
 
520
            }
 
521
            Append(module, cap);
 
522
            last = m.item;
 
523
          }
 
524
          m = Next(m);
 
525
        }
 
526
        if (feature == 0) {
 
527
          feature = Copy(last);
 
528
        }
 
529
        (Char(last))[0] = toupper((Char(last))[0]);
 
530
        modvar = NewStringf("m%s", last);
 
531
        Delete(modules);
 
532
      }
 
533
    }
 
534
    Delete(mod_name);
 
535
  }
 
536
  
 
537
  /* --------------------------------------------------------------------------
 
538
   * nativeWrapper()
 
539
   * -------------------------------------------------------------------------- */
 
540
  virtual int nativeWrapper(Node *n) {
 
541
    String *funcname = Getattr(n,"wrap:name");
 
542
    Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, 
 
543
                 "Adding native function %s not supported (ignored).\n", funcname);
 
544
    return SWIG_NOWRAP;
 
545
  }
 
546
 
 
547
  /**
 
548
   * Process the comma-separated list of aliases (if any).
 
549
   */
 
550
  void defineAliases(Node *n, const String_or_char *iname) {
 
551
    String *aliasv = Getattr(n,"feature:alias");
 
552
    if (aliasv) {
 
553
      List *aliases = Split(aliasv,',',INT_MAX);
 
554
      if (aliases && Len(aliases) > 0) {
 
555
        Iterator alias = First(aliases);
 
556
        while (alias.item) {
 
557
          if (Len(alias.item) > 0) {
 
558
            Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
 
559
          }
 
560
          alias = Next(alias);
 
561
        }
 
562
      }
 
563
      Delete(aliases);
 
564
    }
 
565
  }
 
566
  
 
567
  /* ---------------------------------------------------------------------
 
568
   * create_command(Node *n, char *iname)
 
569
   *
 
570
   * Creates a new command from a C function.
 
571
   *              iname = Name of function in scripting language
 
572
   *
 
573
   * A note about what "protected" and "private" mean in Ruby:
 
574
   *
 
575
   * A private method is accessible only within the class or its subclasses,
 
576
   * and it is callable only in "function form", with 'self' (implicit or
 
577
   * explicit) as a receiver.
 
578
   *
 
579
   * A protected method is callable only from within its class, but unlike
 
580
   * a private method, it can be called with a receiver other than self, such
 
581
   * as another instance of the same class.
 
582
   * --------------------------------------------------------------------- */
 
583
 
 
584
  void create_command(Node *n, const String_or_char *iname) {
 
585
 
 
586
    String *alloc_func = Swig_name_wrapper(iname);
 
587
    String *wname = Swig_name_wrapper(iname);
 
588
    if (CPlusPlus) {
 
589
      Insert(wname,0,"VALUEFUNC(");
 
590
      Append(wname,")");
 
591
    }
 
592
    if (current != NO_CPP)
 
593
      iname = klass->strip(iname);
 
594
    if (Getattr(special_methods, iname)) {
 
595
      iname = GetChar(special_methods, iname);
 
596
    }
 
597
    
 
598
    String *s = NewString("");
 
599
    String *temp = NewString("");
 
600
    
 
601
    switch (current) {
 
602
    case MEMBER_FUNC: 
 
603
      {
 
604
#ifdef SWIG_PROTECTED_TARGET_METHODS
 
605
        const char* rb_define_method = is_protected(n) ?
 
606
          "rb_define_protected_method" : "rb_define_method";
 
607
#else        
 
608
        const char* rb_define_method = "rb_define_method";
 
609
#endif  
 
610
        if (multipleInheritance) {
 
611
          Printv(klass->init, tab4, rb_define_method,"(", klass->mImpl, ", \"",
 
612
                 iname, "\", ", wname, ", -1);\n", NIL);
 
613
        } else {
 
614
          Printv(klass->init, tab4, rb_define_method, "(", klass->vname, ", \"",
 
615
                 iname, "\", ", wname, ", -1);\n", NIL);
 
616
        }
 
617
      }      
 
618
      break;
 
619
    case CONSTRUCTOR_ALLOCATE:
 
620
      Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL);
 
621
      Replaceall(klass->init,"$allocator", s);
 
622
      break;
 
623
    case CONSTRUCTOR_INITIALIZE:
 
624
      Printv(s, tab4, "rb_define_method(", klass->vname,
 
625
             ", \"initialize\", ", wname, ", -1);\n", NIL);
 
626
      Replaceall(klass->init,"$initializer", s);
 
627
      break;
 
628
    case MEMBER_VAR:
 
629
      Append(temp,iname);
 
630
      Replaceall(temp,"_set", "=");
 
631
      Replaceall(temp,"_get", "");
 
632
      if (multipleInheritance) {
 
633
        Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"",
 
634
               temp, "\", ", wname, ", -1);\n", NIL);
 
635
      } else {
 
636
        Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
 
637
               temp, "\", ", wname, ", -1);\n", NIL);
 
638
      }
 
639
      break;
 
640
    case STATIC_FUNC:
 
641
      Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname,
 
642
             ", \"", iname, "\", ", wname, ", -1);\n", NIL);
 
643
      break;
 
644
    case NO_CPP:
 
645
      if (!useGlobalModule) {
 
646
        Printv(s, tab4, "rb_define_module_function(", modvar, ", \"",
 
647
               iname, "\", ", wname, ", -1);\n",NIL);
 
648
        Printv(f_init,s,NIL);
 
649
      } else {
 
650
        Printv(s, tab4, "rb_define_global_function(\"",
 
651
               iname, "\", ", wname, ", -1);\n",NIL);
 
652
        Printv(f_init,s,NIL);
 
653
      }
 
654
      break;
 
655
    case DESTRUCTOR:
 
656
    case CLASS_CONST:
 
657
    case STATIC_VAR:
 
658
      assert(false); // Should not have gotten here for these types
 
659
    default:
 
660
      assert(false);
 
661
    }
 
662
    
 
663
    defineAliases(n, iname);
 
664
 
 
665
    Delete(temp);
 
666
    Delete(s);
 
667
    Delete(wname);
 
668
    Delete(alloc_func);
 
669
  }
 
670
  
 
671
  /* ---------------------------------------------------------------------
 
672
   * applyInputTypemap()
 
673
   *
 
674
   * Look up the appropriate "in" typemap for this parameter (p),
 
675
   * substitute the correct strings for the $target and $input typemap
 
676
   * parameters, and dump the resulting code to the wrapper file.
 
677
   * --------------------------------------------------------------------- */
 
678
 
 
679
  Parm *applyInputTypemap(Parm *p, String *ln, String *source, Wrapper *f) {
 
680
    String *tm;
 
681
    SwigType *pt = Getattr(p,"type");
 
682
    if ((tm = Getattr(p,"tmap:in"))) {
 
683
      Replaceall(tm,"$target",ln);
 
684
      Replaceall(tm,"$source",source);
 
685
      Replaceall(tm,"$input",source);
 
686
      Setattr(p,"emit:input",Copy(source));
 
687
      Printf(f->code,"%s\n", tm);
 
688
      p = Getattr(p,"tmap:in:next");
 
689
    } else {
 
690
      Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
 
691
        "Unable to use type %s as a function argument.\n", SwigType_str(pt,0));
 
692
      p = nextSibling(p);
 
693
    }
 
694
    return p;
 
695
  }
 
696
 
 
697
  Parm *skipIgnoredArgs(Parm *p) {
 
698
    while (checkAttribute(p,"tmap:in:numinputs","0")) {
 
699
      p = Getattr(p,"tmap:in:next");
 
700
    }
 
701
    return p;
 
702
  }
 
703
 
 
704
  /* ---------------------------------------------------------------------
 
705
   * marshalInputArgs()
 
706
   *
 
707
   * Process all of the arguments passed into the scripting language
 
708
   * method and convert them into C/C++ function arguments using the
 
709
   * supplied typemaps.
 
710
   * --------------------------------------------------------------------- */
 
711
  
 
712
  void marshalInputArgs(Node *n, ParmList *l, int numarg, int numreq, String *kwargs, bool allow_kwargs, Wrapper *f) {
 
713
    int i;
 
714
    Parm *p;
 
715
    String *tm;
 
716
    String *source;
 
717
    String *target;
 
718
 
 
719
    source = NewString("");
 
720
    target = NewString("");
 
721
 
 
722
    bool use_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
 
723
 
 
724
    /**
 
725
     * The 'start' value indicates which of the C/C++ function arguments
 
726
     * produced here corresponds to the first value in Ruby's argv[] array.
 
727
     * The value of start is either zero or one. If start is zero, then
 
728
     * the first argument (with name arg1) is based on the value of argv[0].
 
729
     * If start is one, then arg1 is based on the value of argv[1].
 
730
     */
 
731
    int start = (current == MEMBER_FUNC || current == MEMBER_VAR || use_director) ? 1 : 0;
 
732
 
 
733
    int varargs = emit_isvarargs(l);
 
734
 
 
735
    Printf(kwargs,"{ ");
 
736
    for (i = 0, p = l; i < numarg; i++) {
 
737
 
 
738
      p = skipIgnoredArgs(p);
 
739
 
 
740
      String *pn = Getattr(p,"name");
 
741
      String *ln = Getattr(p,"lname");
 
742
 
 
743
      /* Produce string representation of source argument */
 
744
      Clear(source);
 
745
 
 
746
      /* First argument is a special case */
 
747
      if (i == 0) {
 
748
        Printv(source, (start == 0) ? "argv[0]" : "self", NIL);
 
749
      } else {
 
750
        Printf(source,"argv[%d]",i-start);
 
751
      }
 
752
 
 
753
      /* Produce string representation of target argument */
 
754
      Clear(target);
 
755
      Printf(target,"%s",Char(ln));
 
756
 
 
757
      if (i >= (numreq)) { /* Check if parsing an optional argument */
 
758
        Printf(f->code,"    if (argc > %d) {\n", i -  start);
 
759
      }
 
760
      
 
761
      /* Record argument name for keyword argument handling */
 
762
      if (Len(pn)) {
 
763
        Printf(kwargs,"\"%s\",", pn);
 
764
      } else {
 
765
        Printf(kwargs,"\"arg%d\",", i+1);
 
766
      }
 
767
 
 
768
      /* Look for an input typemap */
 
769
      p = applyInputTypemap(p, ln, source, f);
 
770
      if (i >= numreq) {
 
771
        Printf(f->code,"}\n");
 
772
      }
 
773
    }
 
774
    
 
775
    /* Finish argument marshalling */
 
776
    Printf(kwargs," NULL }");
 
777
    if (allow_kwargs) {
 
778
      Printv(f->locals, tab4, "char *kwnames[] = ", kwargs, ";\n", NIL);
 
779
    }
 
780
    
 
781
    /* Trailing varargs */
 
782
    if (varargs) {
 
783
      if (p && (tm = Getattr(p,"tmap:in"))) {
 
784
        Clear(source);
 
785
        Printf(source,"argv[%d]",i-start);
 
786
        Replaceall(tm,"$input",source);
 
787
        Setattr(p,"emit:input",Copy(source));
 
788
        Printf(f->code,"if (argc > %d) {\n", i-start);
 
789
        Printv(f->code,tm,"\n",NIL);
 
790
        Printf(f->code,"}\n");
 
791
      }
 
792
    }
 
793
    
 
794
    Delete(source);
 
795
    Delete(target);
 
796
  }
 
797
 
 
798
  /* ---------------------------------------------------------------------
 
799
   * insertConstraintCheckingCode(ParmList *l, Wrapper *f)
 
800
   *
 
801
   * Checks each of the parameters in the parameter list for a "check"
 
802
   * typemap and (if it finds one) inserts the typemapping code into
 
803
   * the function wrapper.
 
804
   * --------------------------------------------------------------------- */
 
805
  
 
806
  void insertConstraintCheckingCode(ParmList *l, Wrapper *f) {
 
807
    Parm *p;
 
808
    String *tm;
 
809
    for (p = l; p;) {
 
810
      if ((tm = Getattr(p,"tmap:check"))) {
 
811
        Replaceall(tm,"$target",Getattr(p,"lname"));
 
812
        Printv(f->code,tm,"\n",NIL);
 
813
        p = Getattr(p,"tmap:check:next");
 
814
      } else {
 
815
        p = nextSibling(p);
 
816
      }
 
817
    }
 
818
  }
 
819
 
 
820
  /* ---------------------------------------------------------------------
 
821
   * insertCleanupCode(ParmList *l, String *cleanup)
 
822
   *
 
823
   * Checks each of the parameters in the parameter list for a "freearg"
 
824
   * typemap and (if it finds one) inserts the typemapping code into
 
825
   * the function wrapper.
 
826
   * --------------------------------------------------------------------- */
 
827
  
 
828
  void insertCleanupCode(ParmList *l, String *cleanup) {
 
829
    String *tm;
 
830
    for (Parm *p = l; p; ) {
 
831
      if ((tm = Getattr(p,"tmap:freearg"))) {
 
832
        Replaceall(tm,"$source",Getattr(p,"lname"));
 
833
        Printv(cleanup,tm,"\n",NIL);
 
834
        p = Getattr(p,"tmap:freearg:next");
 
835
      } else {
 
836
        p = nextSibling(p);
 
837
      }
 
838
    }
 
839
  }
 
840
 
 
841
  /* ---------------------------------------------------------------------
 
842
   * insertArgOutputCode(ParmList *l, String *outarg, int& need_result)
 
843
   *
 
844
   * Checks each of the parameters in the parameter list for a "argout"
 
845
   * typemap and (if it finds one) inserts the typemapping code into
 
846
   * the function wrapper.
 
847
   * --------------------------------------------------------------------- */
 
848
  
 
849
  void insertArgOutputCode(ParmList *l, String *outarg, int& need_result) {
 
850
    String *tm;
 
851
    for (Parm *p = l; p; ) {
 
852
      if ((tm = Getattr(p,"tmap:argout"))) {
 
853
        Replaceall(tm,"$source",Getattr(p,"lname"));
 
854
        Replaceall(tm,"$target","vresult");
 
855
        Replaceall(tm,"$result","vresult");
 
856
        Replaceall(tm,"$arg",Getattr(p,"emit:input"));
 
857
        Replaceall(tm,"$input",Getattr(p,"emit:input"));
 
858
        Printv(outarg,tm,"\n",NIL);
 
859
        need_result = 1;
 
860
        p = Getattr(p,"tmap:argout:next");
 
861
      } else {
 
862
        p = nextSibling(p);
 
863
      }
 
864
    }
 
865
  }
 
866
  
 
867
  /* ---------------------------------------------------------------------
 
868
   * validIdentifier()
 
869
   *
 
870
   * Is this a valid identifier in the scripting language?
 
871
   * Ruby method names can include any combination of letters, numbers
 
872
   * and underscores. A Ruby method name may optionally end with
 
873
   * a question mark ("?"), exclamation point ("!") or equals sign ("=").
 
874
   *
 
875
   * Methods whose names end with question marks are, by convention,
 
876
   * predicate methods that return true or false (e.g. Array#empty?).
 
877
   *
 
878
   * Methods whose names end with exclamation points are, by convention,
 
879
   * "mutators" that modify the instance in place (e.g. Array#sort!).
 
880
   *
 
881
   * Methods whose names end with an equals sign are attribute setters
 
882
   * (e.g. Thread#critical=).
 
883
   * --------------------------------------------------------------------- */
 
884
 
 
885
  virtual int validIdentifier(String *s) {
 
886
    char *c = Char(s);
 
887
    while (*c) {
 
888
      if ( !( isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=') ) ) return 0;
 
889
      c++;
 
890
    }
 
891
    return 1;
 
892
  }
 
893
  
 
894
  /* ---------------------------------------------------------------------
 
895
   * functionWrapper()
 
896
   *
 
897
   * Create a function declaration and register it with the interpreter.
 
898
   * --------------------------------------------------------------------- */
 
899
 
 
900
  virtual int functionWrapper(Node *n) {
 
901
    String *nodeType;
 
902
    bool constructor;
 
903
    bool destructor;
 
904
    String *storage;
 
905
    bool isVirtual;
 
906
 
 
907
    String *symname = Copy(Getattr(n,"sym:name"));
 
908
    SwigType *t = Getattr(n,"type");
 
909
    ParmList *l = Getattr(n,"parms");
 
910
    Node *parent   = Getattr(n,"parentNode");
 
911
    String *tm;
 
912
    
 
913
    int need_result = 0;
 
914
    
 
915
    /* Ruby needs no destructor wrapper */
 
916
    if (current == DESTRUCTOR)
 
917
      return SWIG_NOWRAP;
 
918
 
 
919
    nodeType = Getattr(n, "nodeType");
 
920
    constructor = (!Cmp(nodeType, "constructor")); 
 
921
    destructor = (!Cmp(nodeType, "destructor")); 
 
922
    storage   = Getattr(n, "storage");
 
923
    isVirtual = (Cmp(storage, "virtual") == 0);
 
924
 
 
925
    /* If the C++ class constructor is overloaded, we only want to
 
926
     * write out the "new" singleton method once since it is always
 
927
     * the same. (It's the "initialize" method that will handle the
 
928
     * overloading). */
 
929
 
 
930
    if (current == CONSTRUCTOR_ALLOCATE &&
 
931
        Swig_symbol_isoverloaded(n) &&
 
932
        Getattr(n, "sym:nextSibling") != 0) return SWIG_OK;
 
933
    
 
934
    String *overname = 0;
 
935
    if (Getattr(n, "sym:overloaded")) {
 
936
      overname = Getattr(n, "sym:overname");
 
937
    } else {
 
938
      if (!addSymbol(symname, n))
 
939
        return SWIG_ERROR;
 
940
    }
 
941
 
 
942
    String *cleanup = NewString("");
 
943
    String *outarg = NewString("");
 
944
    String *kwargs = NewString("");
 
945
    Wrapper *f = NewWrapper();
 
946
 
 
947
    /* Rename predicate methods */
 
948
    if (Getattr(n, "feature:predicate")) {
 
949
      Append(symname, "?");
 
950
    }
 
951
 
 
952
    /* Determine the name of the SWIG wrapper function */
 
953
    String *wname = Swig_name_wrapper(symname);
 
954
    if (overname && current != CONSTRUCTOR_ALLOCATE) {
 
955
      Append(wname,overname);
 
956
    }
 
957
  
 
958
    /* Emit arguments */
 
959
    if (current != CONSTRUCTOR_ALLOCATE) {
 
960
      emit_args(t,l,f);
 
961
    }
 
962
 
 
963
    /* Attach standard typemaps */
 
964
    if (current != CONSTRUCTOR_ALLOCATE) {
 
965
      emit_attach_parmmaps(l, f);
 
966
    }
 
967
    Setattr(n, "wrap:parms", l);
 
968
 
 
969
    /* Get number of arguments */
 
970
    int  numarg = emit_num_arguments(l);
 
971
    int  numreq = emit_num_required(l);
 
972
    int  varargs = emit_isvarargs(l);
 
973
    bool allow_kwargs = use_kw || Getattr(n,"feature:kwargs");
 
974
    
 
975
    bool use_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
 
976
    int start = (current == MEMBER_FUNC || current == MEMBER_VAR || use_director) ? 1 : 0;
 
977
 
 
978
    /* Now write the wrapper function itself */
 
979
    if        (current == CONSTRUCTOR_ALLOCATE) {
 
980
      Printf(f->def, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n");
 
981
      Printv(f->def, "static VALUE\n", wname, "(VALUE self) {", NIL);
 
982
      Printf(f->def, "#else\n");
 
983
      Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
 
984
      Printf(f->def, "#endif\n");
 
985
    } else if (current == CONSTRUCTOR_INITIALIZE) {
 
986
      Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
 
987
      if (!varargs) {
 
988
        Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start);
 
989
      } else {
 
990
        Printf(f->code,"if (argc < %d)\n", numreq-start);
 
991
      }
 
992
      Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start);
 
993
    } else {
 
994
      Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
 
995
      if (!varargs) {
 
996
        Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start);
 
997
      } else {
 
998
        Printf(f->code,"if (argc < %d)\n", numreq-start);
 
999
      }
 
1000
      Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start);
 
1001
    }
 
1002
 
 
1003
    /* Now walk the function parameter list and generate code */
 
1004
    /* to get arguments */
 
1005
    if (current != CONSTRUCTOR_ALLOCATE) {
 
1006
      marshalInputArgs(n, l, numarg, numreq, kwargs, allow_kwargs, f);
 
1007
    }
 
1008
 
 
1009
    // FIXME?
 
1010
    if (use_director) {
 
1011
      numarg--;
 
1012
      numreq--;
 
1013
    }
 
1014
 
 
1015
    /* Insert constraint checking code */
 
1016
    insertConstraintCheckingCode(l, f);
 
1017
  
 
1018
    /* Insert cleanup code */
 
1019
    insertCleanupCode(l, cleanup);
 
1020
 
 
1021
    /* Insert argument output code */
 
1022
    insertArgOutputCode(l, outarg, need_result);
 
1023
 
 
1024
    /* if the object is a director, and the method call originated from its
 
1025
     * underlying python object, resolve the call by going up the c++ 
 
1026
     * inheritance chain.  otherwise try to resolve the method in python.  
 
1027
     * without this check an infinite loop is set up between the director and 
 
1028
     * shadow class method calls.
 
1029
     */
 
1030
 
 
1031
    // NOTE: this code should only be inserted if this class is the
 
1032
    // base class of a director class.  however, in general we haven't
 
1033
    // yet analyzed all classes derived from this one to see if they are
 
1034
    // directors.  furthermore, this class may be used as the base of
 
1035
    // a director class defined in a completely different module at a
 
1036
    // later time, so this test must be included whether or not directorbase
 
1037
    // is true.  we do skip this code if directors have not been enabled
 
1038
    // at the command line to preserve source-level compatibility with
 
1039
    // non-polymorphic swig.  also, if this wrapper is for a smart-pointer
 
1040
    // method, there is no need to perform the test since the calling object
 
1041
    // (the smart-pointer) and the director object (the "pointee") are
 
1042
    // distinct.
 
1043
 
 
1044
    if (directorsEnabled()) {
 
1045
      if (!is_smart_pointer()) {
 
1046
        if (/*directorbase &&*/ !constructor && !destructor && isVirtual) {
 
1047
          Wrapper_add_local(f, "director", "Swig::Director *director = 0");
 
1048
          Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
 
1049
          Printf(f->code, "if (director && (director->swig_get_self() == self)) director->swig_set_up();\n");
 
1050
        }
 
1051
      }
 
1052
    }
 
1053
 
 
1054
    /* Now write code to make the function call */
 
1055
    if (current != CONSTRUCTOR_ALLOCATE) {
 
1056
      if (current == CONSTRUCTOR_INITIALIZE) {
 
1057
        String *action = Getattr(n,"wrap:action");
 
1058
        if (action) {
 
1059
          Append(action,"DATA_PTR(self) = result;");
 
1060
        }
 
1061
      }
 
1062
      emit_action(n,f);
 
1063
    }
 
1064
 
 
1065
    /* Return value if necessary */
 
1066
    if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_ALLOCATE && current != CONSTRUCTOR_INITIALIZE) {
 
1067
      need_result = 1;
 
1068
      if (Getattr(n, "feature:predicate")) {
 
1069
        Printv(f->code, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL);
 
1070
      } else {
 
1071
        tm = Swig_typemap_lookup_new("out",n,"result",0);
 
1072
        if (tm) {
 
1073
          Replaceall(tm,"$result","vresult");
 
1074
          Replaceall(tm,"$source","result");
 
1075
          Replaceall(tm,"$target","vresult");
 
1076
          if (Getattr(n, "feature:new"))
 
1077
            Replaceall(tm,"$owner", "1");
 
1078
          else
 
1079
            Replaceall(tm,"$owner", "0");
 
1080
 
 
1081
          // FIXME: this will not try to unwrap directors returned as non-director
 
1082
          //        base class pointers!
 
1083
    
 
1084
          /* New addition to unwrap director return values so that the original
 
1085
           * python object is returned instead. 
 
1086
           */
 
1087
          bool unwrap = false;
 
1088
          String *decl = Getattr(n, "decl");
 
1089
          int is_pointer = SwigType_ispointer_return(decl);
 
1090
          int is_reference = SwigType_isreference_return(decl);
 
1091
          if (is_pointer || is_reference) {
 
1092
            String *type = Getattr(n, "type");
 
1093
            //Node *classNode = Swig_methodclass(n);
 
1094
            //Node *module = Getattr(classNode, "module");
 
1095
            Node *module = Getattr(parent, "module");
 
1096
            Node *target = Swig_directormap(module, type);
 
1097
            if (target) unwrap = true;
 
1098
          }
 
1099
          if (unwrap) {
 
1100
            Wrapper_add_local(f, "resultdirector", "Swig::Director *resultdirector = 0");
 
1101
            Printf(f->code, "resultdirector = dynamic_cast<Swig::Director *>(result);\n");
 
1102
            Printf(f->code, "if (resultdirector) {\n");
 
1103
            Printf(f->code, "  vresult = resultdirector->swig_get_self();\n");
 
1104
            Printf(f->code, "} else {\n"); 
 
1105
            Printf(f->code,"%s\n", tm);
 
1106
            Printf(f->code, "}\n");
 
1107
          } else {
 
1108
            Printf(f->code,"%s\n", tm);
 
1109
          }
 
1110
        } else {
 
1111
          Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
 
1112
                       "Unable to use return type %s.\n", SwigType_str(t,0));
 
1113
        }
 
1114
      }
 
1115
    }
 
1116
 
 
1117
    /* Extra code needed for new and initialize methods */  
 
1118
    if (current == CONSTRUCTOR_ALLOCATE) {
 
1119
      need_result = 1;
 
1120
      Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(t)));
 
1121
      Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n");
 
1122
      Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n");
 
1123
      Printf(f->code, "#endif\n");
 
1124
    } else if (current == CONSTRUCTOR_INITIALIZE) {
 
1125
      need_result = 1;
 
1126
      // Printf(f->code, "DATA_PTR(self) = result;\n");
 
1127
    }
 
1128
 
 
1129
    /* Dump argument output code; */
 
1130
    Printv(f->code,outarg,NIL);
 
1131
 
 
1132
    /* Dump the argument cleanup code */
 
1133
    if (current != CONSTRUCTOR_ALLOCATE)
 
1134
      Printv(f->code,cleanup,NIL);
 
1135
 
 
1136
    /* Look for any remaining cleanup.  This processes the %new directive */
 
1137
    if (Getattr(n, "feature:new")) {
 
1138
      tm = Swig_typemap_lookup_new("newfree",n,"result",0);
 
1139
      if (tm) {
 
1140
        Replaceall(tm,"$source","result");
 
1141
        Printv(f->code,tm, "\n",NIL);
 
1142
      }
 
1143
    }
 
1144
 
 
1145
    /* Special processing on return value. */
 
1146
    tm = Swig_typemap_lookup_new("ret",n,"result",0);
 
1147
    if (tm) {
 
1148
      Replaceall(tm,"$source","result");
 
1149
      Printv(f->code,tm, NIL);
 
1150
    }
 
1151
 
 
1152
    /* Wrap things up (in a manner of speaking) */
 
1153
    if (need_result) {
 
1154
      if (current == CONSTRUCTOR_ALLOCATE) {
 
1155
        Printv(f->code, tab4, "return vresult;\n", NIL);
 
1156
      } else if (current == CONSTRUCTOR_INITIALIZE) {
 
1157
        Printv(f->code, tab4, "return self;\n", NIL);
 
1158
      } else {
 
1159
        Wrapper_add_local(f,"vresult","VALUE vresult = Qnil");
 
1160
        Printv(f->code, tab4, "return vresult;\n", NIL);
 
1161
      }
 
1162
    } else {
 
1163
      Printv(f->code, tab4, "return Qnil;\n", NIL);
 
1164
    }
 
1165
 
 
1166
    /* Error handling code */
 
1167
    /*
 
1168
    Printf(f->code,"fail:\n");
 
1169
    Printv(f->code,cleanup,NIL);
 
1170
    Printv(f->code,"return Qnil;\n",NIL);
 
1171
    */
 
1172
    Printf(f->code,"}\n");
 
1173
 
 
1174
    /* Substitute the cleanup code */
 
1175
    Replaceall(f->code,"$cleanup",cleanup);
 
1176
 
 
1177
    /* Emit the function */
 
1178
    Wrapper_print(f, f_wrappers);
 
1179
 
 
1180
    /* Now register the function with the interpreter */
 
1181
    if (!Swig_symbol_isoverloaded(n)) {
 
1182
      create_command(n, symname);
 
1183
    } else {
 
1184
      if (current == CONSTRUCTOR_ALLOCATE) {
 
1185
        create_command(n, symname);
 
1186
      } else {
 
1187
        Setattr(n, "wrap:name", wname);
 
1188
        if (!Getattr(n, "sym:nextSibling"))
 
1189
          dispatchFunction(n);
 
1190
      }
 
1191
    }
 
1192
    
 
1193
    Delete(kwargs);
 
1194
    Delete(cleanup);
 
1195
    Delete(outarg);
 
1196
    DelWrapper(f);
 
1197
    Delete(symname);
 
1198
  
 
1199
    return SWIG_OK;
 
1200
  }
 
1201
 
 
1202
  /* ------------------------------------------------------------
 
1203
   * dispatchFunction()
 
1204
   * ------------------------------------------------------------ */
 
1205
   
 
1206
  void dispatchFunction(Node *n) {
 
1207
    /* Last node in overloaded chain */
 
1208
 
 
1209
    int maxargs;
 
1210
    String *tmp = NewString("");
 
1211
    String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs);
 
1212
        
 
1213
    /* Generate a dispatch wrapper for all overloaded functions */
 
1214
 
 
1215
    Wrapper *f       = NewWrapper();
 
1216
    String  *symname = Getattr(n, "sym:name");
 
1217
    String  *wname   = Swig_name_wrapper(symname);
 
1218
 
 
1219
    Printv(f->def,      
 
1220
           "static VALUE ", wname,
 
1221
           "(int nargs, VALUE *args, VALUE self) {",
 
1222
           NIL);
 
1223
    
 
1224
    Wrapper_add_local(f, "argc", "int argc");
 
1225
    if (current == MEMBER_FUNC || current == MEMBER_VAR) {
 
1226
      Printf(tmp, "VALUE argv[%d]", maxargs+1);
 
1227
    } else {
 
1228
      Printf(tmp, "VALUE argv[%d]", maxargs);
 
1229
    }
 
1230
    Wrapper_add_local(f, "argv", tmp);
 
1231
    Wrapper_add_local(f, "ii", "int ii");
 
1232
    if (current == MEMBER_FUNC || current == MEMBER_VAR) {
 
1233
      Printf(f->code, "argc = nargs + 1;\n");
 
1234
      Printf(f->code, "argv[0] = self;\n");
 
1235
      Printf(f->code, "for (ii = 1; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
 
1236
      Printf(f->code, "argv[ii] = args[ii-1];\n");
 
1237
      Printf(f->code, "}\n");
 
1238
    } else {
 
1239
      Printf(f->code, "argc = nargs;\n");
 
1240
      Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
 
1241
      Printf(f->code, "argv[ii] = args[ii];\n");
 
1242
      Printf(f->code, "}\n");
 
1243
    }
 
1244
    
 
1245
    Replaceall(dispatch, "$args", "nargs, args, self");
 
1246
    Printv(f->code, dispatch, "\n", NIL);
 
1247
    Printf(f->code, "rb_raise(rb_eArgError, \"No matching function for overloaded '%s'\");\n", symname);
 
1248
    Printf(f->code,"return Qnil;\n");
 
1249
    Printv(f->code, "}\n", NIL);
 
1250
    Wrapper_print(f, f_wrappers);
 
1251
    create_command(n, Char(symname));
 
1252
 
 
1253
    DelWrapper(f);
 
1254
    Delete(dispatch);
 
1255
    Delete(tmp);
 
1256
    Delete(wname);
 
1257
  }
 
1258
  
 
1259
  /* ---------------------------------------------------------------------
 
1260
   * variableWrapper()
 
1261
   * --------------------------------------------------------------------- */
 
1262
 
 
1263
  virtual int variableWrapper(Node *n) {
 
1264
 
 
1265
    char *name  = GetChar(n,"name");
 
1266
    char *iname = GetChar(n,"sym:name");
 
1267
    SwigType *t = Getattr(n,"type");
 
1268
    String *tm;
 
1269
    String *getfname, *setfname;
 
1270
    Wrapper *getf, *setf;
 
1271
 
 
1272
    getf = NewWrapper();
 
1273
    setf = NewWrapper();
 
1274
 
 
1275
    /* create getter */
 
1276
    getfname = NewString(Swig_name_get(iname));
 
1277
    Printv(getf->def, "static VALUE\n", getfname, "(", NIL);
 
1278
    Printf(getf->def, "VALUE self");
 
1279
    Printf(getf->def, ") {");
 
1280
    Wrapper_add_local(getf,"_val","VALUE _val");
 
1281
 
 
1282
    tm = Swig_typemap_lookup_new("varout",n, name, 0);
 
1283
    if (tm) {
 
1284
      Replaceall(tm,"$result","_val");
 
1285
      Replaceall(tm,"$target","_val");
 
1286
      Replaceall(tm,"$source",name);
 
1287
      Printv(getf->code,tm, NIL);
 
1288
    } else {
 
1289
      Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
 
1290
                   "Unable to read variable of type %s\n", SwigType_str(t,0));
 
1291
    }
 
1292
    Printv(getf->code, tab4, "return _val;\n}\n", NIL);
 
1293
    Wrapper_print(getf,f_wrappers);
 
1294
 
 
1295
    if (Getattr(n,"feature:immutable")) {
 
1296
      setfname = NewString("NULL");
 
1297
    } else {
 
1298
      /* create setter */
 
1299
      setfname = NewString(Swig_name_set(iname));
 
1300
      Printv(setf->def, "static VALUE\n", setfname, "(VALUE self, ", NIL);
 
1301
      Printf(setf->def, "VALUE _val) {");
 
1302
    
 
1303
      tm = Swig_typemap_lookup_new("varin",n,name,0);
 
1304
      if (tm) {
 
1305
        Replaceall(tm,"$input","_val");
 
1306
        Replaceall(tm,"$source","_val");
 
1307
        Replaceall(tm,"$target",name);
 
1308
        Printv(setf->code,tm,"\n",NIL);
 
1309
      } else {
 
1310
        Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number,
 
1311
                     "Unable to set variable of type %s\n", SwigType_str(t,0));
 
1312
      }
 
1313
      Printv(setf->code, tab4, "return _val;\n",NIL);
 
1314
      Printf(setf->code,"}\n");
 
1315
      Wrapper_print(setf,f_wrappers);
 
1316
    }
 
1317
 
 
1318
    /* define accessor method */
 
1319
    if (CPlusPlus) {
 
1320
      Insert(getfname,0,"VALUEFUNC(");
 
1321
      Append(getfname,")");
 
1322
      Insert(setfname,0,"VALUEFUNC(");
 
1323
      Append(setfname,")");
 
1324
    }
 
1325
 
 
1326
    String *s = NewString("");
 
1327
    switch (current) {
 
1328
    case STATIC_VAR:
 
1329
      /* C++ class variable */
 
1330
      Printv(s,
 
1331
             tab4, "rb_define_singleton_method(", klass->vname, ", \"",
 
1332
             klass->strip(iname), "\", ", getfname, ", 0);\n",
 
1333
             NIL);
 
1334
      if (!Getattr(n,"feature:immutable")) {
 
1335
        Printv(s,
 
1336
               tab4, "rb_define_singleton_method(", klass->vname, ", \"",
 
1337
               klass->strip(iname), "=\", ", setfname, ", 1);\n",
 
1338
               NIL);
 
1339
      }
 
1340
      Printv(klass->init,s,NIL);
 
1341
      break;
 
1342
    default:
 
1343
      /* C global variable */
 
1344
      /* wrapped in Ruby module attribute */
 
1345
      assert(current == NO_CPP);
 
1346
      if (!useGlobalModule) {
 
1347
        Printv(s,
 
1348
               tab4, "rb_define_singleton_method(", modvar, ", \"",
 
1349
               iname, "\", ", getfname, ", 0);\n",
 
1350
               NIL);
 
1351
        if (!Getattr(n,"feature:immutable")) {
 
1352
          Printv(s,
 
1353
                 tab4, "rb_define_singleton_method(", modvar, ", \"",
 
1354
                 iname, "=\", ", setfname, ", 1);\n",
 
1355
                 NIL);
 
1356
        }
 
1357
      } else {
 
1358
        Printv(s,
 
1359
               tab4, "rb_define_global_method(\"",
 
1360
               iname, "\", ", getfname, ", 0);\n",
 
1361
               NIL);
 
1362
        if (!Getattr(n,"feature:immutable")) {
 
1363
          Printv(s,
 
1364
                 tab4, "rb_define_global_method(\"",
 
1365
                 iname, "=\", ", setfname, ", 1);\n",
 
1366
                 NIL);
 
1367
        }
 
1368
      }
 
1369
      Printv(f_init,s,NIL);
 
1370
      Delete(s);
 
1371
      break;
 
1372
    }
 
1373
    Delete(getfname);
 
1374
    Delete(setfname);
 
1375
    DelWrapper(setf);
 
1376
    DelWrapper(getf);
 
1377
    return SWIG_OK;
 
1378
  }
 
1379
 
 
1380
 
 
1381
  /* ---------------------------------------------------------------------
 
1382
   * validate_const_name(char *name)
 
1383
   *
 
1384
   * Validate constant name.
 
1385
   * --------------------------------------------------------------------- */
 
1386
 
 
1387
  char *
 
1388
  validate_const_name(char *name, const char *reason) {
 
1389
    if (!name || name[0] == '\0')
 
1390
      return name;
 
1391
    
 
1392
    if (isupper(name[0]))
 
1393
      return name;
 
1394
    
 
1395
    if (islower(name[0])) {
 
1396
      name[0] = toupper(name[0]);
 
1397
      Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number,
 
1398
                   "Wrong %s name (corrected to `%s')\n", reason, name);
 
1399
      return name;
 
1400
    }
 
1401
    
 
1402
    Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number,
 
1403
                 "Wrong %s name\n", reason);
 
1404
    
 
1405
    return name;
 
1406
  }
 
1407
  
 
1408
  /* ---------------------------------------------------------------------
 
1409
   * constantWrapper()
 
1410
   * --------------------------------------------------------------------- */
 
1411
 
 
1412
  virtual int constantWrapper(Node *n) {
 
1413
    Swig_require("constantWrapper",n, "*sym:name", "type", "value", NIL);
 
1414
    
 
1415
    char *iname     = GetChar(n,"sym:name");
 
1416
    SwigType *type  = Getattr(n,"type");
 
1417
    char *value     = GetChar(n,"value");
 
1418
    
 
1419
    if (current == CLASS_CONST) {
 
1420
      iname = klass->strip(iname);
 
1421
    }
 
1422
    validate_const_name(iname, "constant");
 
1423
    SetChar(n, "sym:name", iname);
 
1424
    
 
1425
    /* Special hook for member pointer */
 
1426
    if (SwigType_type(type) == T_MPOINTER) {
 
1427
      String *wname = Swig_name_wrapper(iname);
 
1428
      Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
 
1429
      value = Char(wname);
 
1430
    }
 
1431
    String *tm = Swig_typemap_lookup_new("constant", n, value, 0);
 
1432
    if (tm) {
 
1433
      Replaceall(tm, "$source", value);
 
1434
      Replaceall(tm, "$target", iname);
 
1435
      Replaceall(tm, "$symname", iname);
 
1436
      Replaceall(tm, "$value", value);
 
1437
      if (current == CLASS_CONST) {
 
1438
        if (multipleInheritance) {
 
1439
          Replaceall(tm, "$module", klass->mImpl);
 
1440
          Printv(klass->init, tm, "\n", NIL);
 
1441
        } else {
 
1442
          Replaceall(tm, "$module", klass->vname);
 
1443
          Printv(klass->init, tm, "\n", NIL);
 
1444
        }
 
1445
      } else {
 
1446
        if (!useGlobalModule) {
 
1447
          Replaceall(tm, "$module", modvar);
 
1448
        } else {
 
1449
          Replaceall(tm, "$module", "rb_cObject");
 
1450
        }
 
1451
        Printf(f_init, "%s\n", tm);
 
1452
      }
 
1453
    } else {
 
1454
      Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
 
1455
                   "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
 
1456
    }
 
1457
    Swig_restore(n);
 
1458
    return SWIG_OK;
 
1459
  }
 
1460
  
 
1461
  /* -----------------------------------------------------------------------------
 
1462
   * classDeclaration() 
 
1463
   *
 
1464
   * Records information about classes---even classes that might be defined in
 
1465
   * other modules referenced by %import.
 
1466
   * ----------------------------------------------------------------------------- */
 
1467
 
 
1468
  virtual int classDeclaration(Node *n) {
 
1469
    String *name = Getattr(n,"name");
 
1470
    String *symname = Getattr(n,"sym:name");
 
1471
    String *tdname = Getattr(n,"tdname");
 
1472
  
 
1473
    name = tdname ? tdname : name;
 
1474
    String *namestr = SwigType_namestr(name);
 
1475
    klass = RCLASS(classes, Char(namestr));
 
1476
    if (!klass) {
 
1477
      klass = new RClass();
 
1478
      String *valid_name = NewString(symname ? symname : namestr);
 
1479
      validate_const_name(Char(valid_name), "class");
 
1480
      klass->set_name(namestr, symname, valid_name);
 
1481
      SET_RCLASS(classes, Char(namestr), klass);
 
1482
      Delete(valid_name);
 
1483
    }
 
1484
    Delete(namestr);
 
1485
    return Language::classDeclaration(n);
 
1486
  }
 
1487
 
 
1488
  /**
 
1489
   * Process the comma-separated list of mixed-in module names (if any).
 
1490
   */
 
1491
  void includeRubyModules(Node *n) {
 
1492
    String *mixin = Getattr(n,"feature:mixin");
 
1493
    if (mixin) {
 
1494
      List *modules = Split(mixin,',',INT_MAX);
 
1495
      if (modules && Len(modules) > 0) {
 
1496
        Iterator mod = First(modules);
 
1497
        while (mod.item) {
 
1498
          if (Len(mod.item) > 0) {
 
1499
            Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod.item);
 
1500
          }
 
1501
          mod = Next(mod);
 
1502
        }
 
1503
      }
 
1504
      Delete(modules);
 
1505
    }
 
1506
  }
 
1507
 
 
1508
  void handleBaseClasses(Node *n) {
 
1509
    List *baselist = Getattr(n,"bases");
 
1510
    if (baselist && Len(baselist)) {
 
1511
      Iterator base = First(baselist);
 
1512
      while (base.item) {
 
1513
        String *basename = Getattr(base.item,"name");
 
1514
        String *basenamestr = SwigType_namestr(basename);
 
1515
        RClass *super = RCLASS(classes, Char(basenamestr));
 
1516
        Delete(basenamestr);
 
1517
        if (super) {
 
1518
          SwigType *btype = NewString(basename);
 
1519
          SwigType_add_pointer(btype);
 
1520
          SwigType_remember(btype);
 
1521
          if (multipleInheritance) {
 
1522
            String *bmangle = SwigType_manglestr(btype);
 
1523
            Insert(bmangle,0,"((swig_class *) SWIGTYPE");
 
1524
            Append(bmangle,"->clientdata)->mImpl");
 
1525
            Printv(klass->init, "rb_include_module(", klass->mImpl, ", ", bmangle, ");\n", NIL);
 
1526
            Delete(bmangle);
 
1527
          } else {
 
1528
            String *bmangle = SwigType_manglestr(btype);
 
1529
            Insert(bmangle,0,"((swig_class *) SWIGTYPE");
 
1530
            Append(bmangle,"->clientdata)->klass");
 
1531
            Replaceall(klass->init,"$super",bmangle);
 
1532
            Delete(bmangle);
 
1533
          }
 
1534
          Delete(btype);
 
1535
        }
 
1536
        base = Next(base);
 
1537
        if (!multipleInheritance) {
 
1538
          /* Warn about multiple inheritance for additional base class(es) listed */
 
1539
          while (base.item) {
 
1540
            basename = Getattr(n,"name");
 
1541
            Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number, 
 
1542
                         "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", basename, basename);
 
1543
            base = Next(base);
 
1544
          }
 
1545
        }
 
1546
      }
 
1547
    }
 
1548
  }
 
1549
 
 
1550
  /**
 
1551
   * Check to see if a %markfunc was specified.
 
1552
   */
 
1553
  void handleMarkFuncDirective(Node *n) {
 
1554
    String *markfunc = Getattr(n, "feature:markfunc");
 
1555
    if (markfunc) {
 
1556
      Printf(klass->init, "c%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc);
 
1557
    } else {
 
1558
      Printf(klass->init, "c%s.mark = 0;\n", klass->name);
 
1559
    }
 
1560
  }
 
1561
 
 
1562
  /**
 
1563
   * Check to see if a %freefunc was specified.
 
1564
   */
 
1565
  void handleFreeFuncDirective(Node *n) {
 
1566
    String *freefunc = Getattr(n, "feature:freefunc");
 
1567
    if (freefunc) {
 
1568
      Printf(klass->init, "c%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc);
 
1569
    } else {
 
1570
      if (klass->destructor_defined) {
 
1571
        Printf(klass->init, "c%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname);
 
1572
      }
 
1573
    }
 
1574
    Replaceall(klass->header,"$freeproto", "");
 
1575
  }
 
1576
  
 
1577
  /* ----------------------------------------------------------------------
 
1578
   * classHandler()
 
1579
   * ---------------------------------------------------------------------- */
 
1580
 
 
1581
  virtual int classHandler(Node *n) {
 
1582
 
 
1583
    String *name = Getattr(n,"name");
 
1584
    String *symname = Getattr(n,"sym:name");
 
1585
    String *namestr = SwigType_namestr(name); // does template expansion
 
1586
 
 
1587
    klass = RCLASS(classes, Char(namestr));
 
1588
    assert(klass != 0);
 
1589
    Delete(namestr);
 
1590
    String *valid_name = NewString(symname);
 
1591
    validate_const_name(Char(valid_name), "class");
 
1592
 
 
1593
    Clear(klass->type);
 
1594
    Printv(klass->type, Getattr(n,"classtype"), NIL);
 
1595
    Printv(klass->header, "\nswig_class c", valid_name, ";\n", NIL);
 
1596
    Printv(klass->init, "\n", tab4, NIL);
 
1597
    if (multipleInheritance) {
 
1598
      if (!useGlobalModule) {
 
1599
        Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
 
1600
               ", \"", klass->name, "\", rb_cObject);\n", NIL);
 
1601
      } else {
 
1602
        Printv(klass->init, klass->vname, " = rb_define_class(\"",
 
1603
               klass->name, "\", rb_cObject);\n", NIL);
 
1604
      }
 
1605
      Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\n", NIL);
 
1606
    } else {
 
1607
      if (!useGlobalModule) {
 
1608
        Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
 
1609
               ", \"", klass->name, "\", $super);\n", NIL);
 
1610
      } else {
 
1611
        Printv(klass->init, klass->vname, " = rb_define_class(\"",
 
1612
               klass->name, "\", $super);\n", NIL);
 
1613
      }
 
1614
    }
 
1615
 
 
1616
    SwigType *tt = NewString(name);
 
1617
    SwigType_add_pointer(tt);
 
1618
    SwigType_remember(tt);
 
1619
    String *tm = SwigType_manglestr(tt);
 
1620
    Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &c%s);\n", tm, valid_name);
 
1621
    Delete(tm);
 
1622
    Delete(tt);
 
1623
    Delete(valid_name);
 
1624
    
 
1625
    includeRubyModules(n);
 
1626
 
 
1627
    Printv(klass->init, "$allocator",NIL);
 
1628
    Printv(klass->init, "$initializer",NIL);
 
1629
 
 
1630
    Printv(klass->header,
 
1631
           "$freeproto",
 
1632
           NIL);
 
1633
 
 
1634
    Language::classHandler(n);
 
1635
 
 
1636
    handleBaseClasses(n);
 
1637
    handleMarkFuncDirective(n);
 
1638
    handleFreeFuncDirective(n);
 
1639
    
 
1640
    if (multipleInheritance) {
 
1641
      Printv(klass->init, "rb_include_module(", klass->vname, ", ", klass->mImpl, ");\n", NIL);
 
1642
    }
 
1643
 
 
1644
    Printv(f_header, klass->header,NIL);
 
1645
 
 
1646
    String *s = NewString("");
 
1647
    Printv(s, tab4, "rb_undef_alloc_func(", klass->vname, ");\n", NIL);
 
1648
    Replaceall(klass->init,"$allocator", s);
 
1649
    Replaceall(klass->init,"$initializer", "");
 
1650
    Replaceall(klass->init,"$super", "rb_cObject");
 
1651
    Delete(s);
 
1652
 
 
1653
    Printv(f_init,klass->init,NIL);
 
1654
    klass = 0;
 
1655
    return SWIG_OK;
 
1656
  }
 
1657
 
 
1658
  /* ----------------------------------------------------------------------
 
1659
   * memberfunctionHandler()
 
1660
   *
 
1661
   * Method for adding C++ member function
 
1662
   *
 
1663
   * By default, we're going to create a function of the form :
 
1664
   *
 
1665
   *         Foo_bar(this,args)
 
1666
   *
 
1667
   * Where Foo is the classname, bar is the member name and the this pointer
 
1668
   * is explicitly attached to the beginning.
 
1669
   *
 
1670
   * The renaming only applies to the member function part, not the full
 
1671
   * classname.
 
1672
   *
 
1673
   * --------------------------------------------------------------------- */
 
1674
  
 
1675
  virtual int memberfunctionHandler(Node *n) {
 
1676
    current = MEMBER_FUNC;
 
1677
    Language::memberfunctionHandler(n);
 
1678
    current = NO_CPP;
 
1679
    return SWIG_OK;
 
1680
  }
 
1681
  
 
1682
  /* ---------------------------------------------------------------------
 
1683
   * constructorHandler()
 
1684
   *
 
1685
   * Method for adding C++ member constructor
 
1686
   * -------------------------------------------------------------------- */
 
1687
 
 
1688
  virtual int constructorHandler(Node *n) {
 
1689
    int   use_director = Swig_directorclass(n);
 
1690
 
 
1691
    /* First wrap the allocate method */
 
1692
    current = CONSTRUCTOR_ALLOCATE;
 
1693
    Swig_name_register((String_or_char *) "construct", (String_or_char *) "%c_allocate");
 
1694
    Language::constructorHandler(n);
 
1695
 
 
1696
    /* 
 
1697
     * If we're wrapping the constructor of a C++ director class, prepend a new parameter
 
1698
     * to receive the scripting language object (e.g. 'self')
 
1699
     *
 
1700
     */
 
1701
    Swig_save("ruby:constructorHandler",n,"parms",NIL);
 
1702
    if (use_director) {
 
1703
      Parm *parms = Getattr(n, "parms");
 
1704
      Parm *self;
 
1705
      String *name = NewString("self");
 
1706
      String *type = NewString("VALUE");
 
1707
      self = NewParm(type, name);
 
1708
      Delete(type);
 
1709
      Delete(name);
 
1710
      Setattr(self, "lname", "Qnil");
 
1711
      if (parms) set_nextSibling(self, parms);
 
1712
      Setattr(n, "parms", self);
 
1713
      Setattr(n, "wrap:self", "1");
 
1714
      Delete(self);
 
1715
    }
 
1716
 
 
1717
    /* Now do the instance initialize method */
 
1718
    current = CONSTRUCTOR_INITIALIZE;
 
1719
    Swig_name_register((String_or_char *) "construct", (String_or_char *) "new_%c");
 
1720
    Language::constructorHandler(n);
 
1721
 
 
1722
    /* Restore original parameter list */
 
1723
    Delattr(n, "wrap:self");
 
1724
    Swig_restore(n);
 
1725
 
 
1726
    /* Done */
 
1727
    Swig_name_unregister((String_or_char *) "construct");
 
1728
    current = NO_CPP;
 
1729
    klass->constructor_defined = 1;
 
1730
    return SWIG_OK;
 
1731
  }
 
1732
 
 
1733
  /* ---------------------------------------------------------------------
 
1734
   * destructorHandler()
 
1735
   * -------------------------------------------------------------------- */
 
1736
 
 
1737
  virtual int destructorHandler(Node *n) {
 
1738
    current = DESTRUCTOR;
 
1739
    Language::destructorHandler(n);
 
1740
 
 
1741
    String *freefunc = NewString("");
 
1742
    String *freeproto = NewString("");
 
1743
    String *freebody = NewString("");
 
1744
  
 
1745
    Printv(freefunc, "free_", klass->mname, NIL);
 
1746
    Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", NIL);
 
1747
    Printv(freebody, "static void\n",
 
1748
           freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n",
 
1749
           tab4, NIL);
 
1750
    if (Extend) {
 
1751
      String *wrap = Getattr(n, "wrap:code");
 
1752
      if (wrap) {
 
1753
        File *f_code = Swig_filebyname("header");
 
1754
        if (f_code) {
 
1755
          Printv(f_code, wrap, NIL);
 
1756
        }
 
1757
      }
 
1758
      /*    Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", NIL); */
 
1759
      Printv(freebody,Getattr(n,"wrap:action"), NIL);
 
1760
    } else {
 
1761
      /* When no extend mode, swig emits no destroy function. */
 
1762
      if (CPlusPlus)
 
1763
        Printf(freebody, "delete %s", Swig_cparm_name(0,0));
 
1764
      else
 
1765
        Printf(freebody, "free((char*) %s)", Swig_cparm_name(0,0));
 
1766
    }
 
1767
    Printv(freebody, ";\n}\n", NIL);
 
1768
  
 
1769
    Replaceall(klass->header,"$freeproto", freeproto);
 
1770
    Printv(f_wrappers, freebody, NIL);
 
1771
  
 
1772
    klass->destructor_defined = 1;
 
1773
    current = NO_CPP;
 
1774
    Delete(freefunc);
 
1775
    Delete(freeproto);
 
1776
    Delete(freebody);
 
1777
    return SWIG_OK;
 
1778
  }
 
1779
 
 
1780
  /* ---------------------------------------------------------------------
 
1781
   * membervariableHandler()
 
1782
   *
 
1783
   * This creates a pair of functions to set/get the variable of a member.
 
1784
   * -------------------------------------------------------------------- */
 
1785
 
 
1786
  virtual int membervariableHandler(Node *n) {
 
1787
    current = MEMBER_VAR;
 
1788
    Language::membervariableHandler(n);
 
1789
    current = NO_CPP;
 
1790
    return SWIG_OK;
 
1791
  }
 
1792
 
 
1793
  /* -----------------------------------------------------------------------
 
1794
   * staticmemberfunctionHandler()
 
1795
   *
 
1796
   * Wrap a static C++ function
 
1797
   * ---------------------------------------------------------------------- */
 
1798
 
 
1799
  virtual int staticmemberfunctionHandler(Node *n) {
 
1800
    current = STATIC_FUNC;
 
1801
    Language::staticmemberfunctionHandler(n);
 
1802
    current = NO_CPP;
 
1803
    return SWIG_OK;
 
1804
  }
 
1805
  
 
1806
  /* ----------------------------------------------------------------------
 
1807
   * memberconstantHandler()
 
1808
   *
 
1809
   * Create a C++ constant
 
1810
   * --------------------------------------------------------------------- */
 
1811
 
 
1812
  virtual int memberconstantHandler(Node *n) {
 
1813
    current = CLASS_CONST;
 
1814
    Language::memberconstantHandler(n);
 
1815
    current = NO_CPP;
 
1816
    return SWIG_OK;
 
1817
  }
 
1818
  
 
1819
  /* ---------------------------------------------------------------------
 
1820
   * staticmembervariableHandler()
 
1821
   * --------------------------------------------------------------------- */
 
1822
 
 
1823
  virtual int staticmembervariableHandler(Node *n) {
 
1824
    current = STATIC_VAR;
 
1825
    Language::staticmembervariableHandler(n);
 
1826
    current = NO_CPP;
 
1827
    return SWIG_OK;
 
1828
  }
 
1829
 
 
1830
  /* C++ director class generation */
 
1831
  virtual int classDirector(Node *n) {
 
1832
    return Language::classDirector(n);
 
1833
  }
 
1834
  
 
1835
  virtual int classDirectorInit(Node *n) {
 
1836
    String *declaration;
 
1837
    declaration = Swig_director_declaration(n);
 
1838
    Printf(f_directors_h, "\n");
 
1839
    Printf(f_directors_h, "%s\n", declaration);
 
1840
    Printf(f_directors_h, "public:\n");
 
1841
    Delete(declaration);
 
1842
    return Language::classDirectorInit(n);
 
1843
  }
 
1844
  
 
1845
  virtual int classDirectorEnd(Node *n) {
 
1846
    Printf(f_directors_h, "};\n\n");
 
1847
    return Language::classDirectorEnd(n);
 
1848
  }
 
1849
  
 
1850
  virtual int unrollVirtualMethods(Node *n, Node *parent, Hash *vm, int default_director, int &virtual_destructor) {
 
1851
    return Language::unrollVirtualMethods(n, parent, vm, default_director, virtual_destructor);
 
1852
  }
 
1853
  
 
1854
  /* ------------------------------------------------------------
 
1855
   * classDirectorConstructor()
 
1856
   * ------------------------------------------------------------ */
 
1857
 
 
1858
  virtual int classDirectorConstructor(Node *n) {
 
1859
    Node *parent = Getattr(n, "parentNode");
 
1860
    String *sub = NewString("");
 
1861
    String *decl = Getattr(n, "decl");
 
1862
    String *supername = Swig_class_name(parent);
 
1863
    String *classname = NewString("");
 
1864
    Printf(classname, "SwigDirector_%s", supername);
 
1865
 
 
1866
    /* insert self and disown parameters */
 
1867
    Parm *p, *ip;
 
1868
    ParmList *superparms = Getattr(n, "parms");
 
1869
    ParmList *parms = CopyParmList(superparms);
 
1870
    String *type = NewString("VALUE");
 
1871
    p = NewParm(type, NewString("self"));
 
1872
    set_nextSibling(p, parms);
 
1873
    parms = p;
 
1874
    for (ip = parms; nextSibling(ip); ) ip = nextSibling(ip);
 
1875
    p = NewParm(NewString("bool"), NewString("disown"));
 
1876
    Setattr(p, "arg:byname", "1");
 
1877
    Setattr(n, "director:postfix_args", p);
 
1878
    Setattr(p, "value", "0");
 
1879
    set_nextSibling(ip, p);
 
1880
    
 
1881
    /* constructor */
 
1882
    {
 
1883
      Wrapper *w = NewWrapper();
 
1884
      String *call;
 
1885
      String *basetype = Getattr(parent, "classtype");
 
1886
      String *target = Swig_method_decl(decl, classname, parms, 0, 0);
 
1887
      call = Swig_csuperclass_call(0, basetype, superparms);
 
1888
      Printf(w->def, "%s::%s: %s, Swig::Director(self, disown) { }", classname, target, call);
 
1889
      Delete(target);
 
1890
      Wrapper_print(w, f_directors);
 
1891
      Delete(call);
 
1892
      DelWrapper(w);
 
1893
    }
 
1894
    
 
1895
    /* constructor header */
 
1896
    {
 
1897
      String *target = Swig_method_decl(decl, classname, parms, 0, 1);
 
1898
      Printf(f_directors_h, "    %s;\n", target);
 
1899
      Delete(target);
 
1900
    }
 
1901
 
 
1902
    Delete(sub);
 
1903
    Delete(classname);
 
1904
    Delete(supername);
 
1905
    Delete(parms);
 
1906
    return Language::classDirectorConstructor(n);
 
1907
  }
 
1908
  
 
1909
  virtual int classDirectorDefaultConstructor(Node *n) {
 
1910
    String *classname;
 
1911
    Wrapper *w;
 
1912
    classname = Swig_class_name(n);
 
1913
    w = NewWrapper();
 
1914
    Printf(w->def, "SwigDirector_%s::SwigDirector_%s(VALUE self, bool disown) : Swig::Director(self, disown) { }", classname, classname);
 
1915
    Wrapper_print(w, f_directors);
 
1916
    DelWrapper(w);
 
1917
    Printf(f_directors_h, "    SwigDirector_%s(VALUE self, bool disown = true);\n", classname);
 
1918
    Delete(classname);
 
1919
    return Language::classDirectorDefaultConstructor(n);
 
1920
  }
 
1921
  
 
1922
  /* ---------------------------------------------------------------
 
1923
   * classDirectorMethod()
 
1924
   *
 
1925
   * Emit a virtual director method to pass a method call on to the 
 
1926
   * underlying Ruby instance.
 
1927
   *
 
1928
   * --------------------------------------------------------------- */
 
1929
 
 
1930
  void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args) {
 
1931
 
 
1932
    Wrapper *body = NewWrapper();
 
1933
    Wrapper *rescue = NewWrapper();
 
1934
 
 
1935
    String *methodName = Getattr(n, "sym:name");
 
1936
    String *bodyName = NewStringf("%s_%s_body", className, methodName);
 
1937
    String *rescueName = NewStringf("%s_%s_rescue", className, methodName);
 
1938
    String *depthCountName = NewStringf("%s_%s_call_depth", className, methodName);
 
1939
 
 
1940
    // Check for an exception typemap of some kind
 
1941
    String *tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
 
1942
    if (!tm) {
 
1943
      tm = Getattr(n, "feature:director:except");
 
1944
    }
 
1945
 
 
1946
    if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0))
 
1947
    {
 
1948
      // Declare a global to hold the depth count
 
1949
      Printf(f_directors, "static int %s = 0;\n", depthCountName);
 
1950
 
 
1951
      // Function body
 
1952
      Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName);
 
1953
      Wrapper_add_localv(body, "args", "Swig::body_args *", "args", "= reinterpret_cast<Swig::body_args *>(data)", NIL);
 
1954
      Wrapper_add_localv(body, "result", "VALUE", "result", "= Qnil", NIL);
 
1955
      Printf(body->code, "%s++;\n", depthCountName, NIL);
 
1956
      Printv(body->code, "result = rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL);
 
1957
      Printf(body->code, "%s--;\n", depthCountName, NIL);
 
1958
      Printv(body->code, "return result;\n", NIL);
 
1959
      Printv(body->code, "}", NIL);
 
1960
      
 
1961
      // Exception handler
 
1962
      Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName); 
 
1963
      Replaceall(tm, "$error", "error");
 
1964
      Printf(rescue->code, "if (%s == 0) ", depthCountName);
 
1965
      Printv(rescue->code, Str(tm), "\n", NIL);
 
1966
      Printf(rescue->code, "%s--;\n", depthCountName);
 
1967
      Printv(rescue->code, "rb_exc_raise(error);\n", NIL);
 
1968
      Printv(rescue->code, "}", NIL);
 
1969
      
 
1970
      // Main code
 
1971
      Wrapper_add_localv(w, "args", "Swig::body_args", "args", NIL);
 
1972
      Printv(w->code, "args.recv = swig_get_self();\n", NIL);
 
1973
      Printf(w->code, "args.id = rb_intern(\"%s\");\n", methodName);
 
1974
      Printf(w->code, "args.argc = %d;\n", argc);
 
1975
      if (argc > 0) {
 
1976
        Wrapper_add_localv(w, "i", "int", "i", NIL);
 
1977
        Printf(w->code, "args.argv = new VALUE[%d];\n", argc);
 
1978
        Printf(w->code, "for (i = 0; i < %d; i++) {\n", argc);
 
1979
        Printv(w->code, "args.argv[i] = Qnil;\n", NIL);
 
1980
        Printv(w->code, "}\n", NIL);
 
1981
      } else {
 
1982
        Printv(w->code, "args.argv = 0;\n", NIL);
 
1983
      }
 
1984
      Printf(w->code,
 
1985
        "result = rb_rescue2((VALUE(*)(ANYARGS)) %s, reinterpret_cast<VALUE>(&args), (VALUE(*)(ANYARGS)) %s, reinterpret_cast<VALUE>(&args), rb_eStandardError, 0);\n",
 
1986
        bodyName, rescueName);
 
1987
      if (argc > 0) {
 
1988
        Printv(w->code, "delete [] args.argv;\n", NIL);
 
1989
      }
 
1990
 
 
1991
      // Dump wrapper code
 
1992
      Wrapper_print(body, f_directors);
 
1993
      Wrapper_print(rescue, f_directors);
 
1994
    }
 
1995
    else
 
1996
    {
 
1997
      if (argc > 0) {
 
1998
        Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", methodName, argc, args);
 
1999
      } else {
 
2000
        Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", methodName);
 
2001
      }
 
2002
    }
 
2003
 
 
2004
    // Clean up
 
2005
    Delete(bodyName);
 
2006
    Delete(rescueName);
 
2007
    Delete(depthCountName);
 
2008
    DelWrapper(body);
 
2009
    DelWrapper(rescue);
 
2010
  }
 
2011
  
 
2012
  virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
 
2013
    int is_void = 0;
 
2014
    int is_pointer = 0;
 
2015
    String *decl;
 
2016
    String *type;
 
2017
    String *name;
 
2018
    String *classname;
 
2019
    String *declaration;
 
2020
    ParmList *l;
 
2021
    Wrapper *w;
 
2022
    String *tm;
 
2023
    String *wrap_args;
 
2024
    String *return_type;
 
2025
    Parm* p;
 
2026
    String *value = Getattr(n, "value");
 
2027
    String *storage = Getattr(n,"storage");
 
2028
    bool pure_virtual = false;
 
2029
    int status = SWIG_OK;
 
2030
    int idx;
 
2031
 
 
2032
    if (Cmp(storage,"virtual") == 0) {
 
2033
      if (Cmp(value,"0") == 0) {
 
2034
        pure_virtual = true;
 
2035
      }
 
2036
    }
 
2037
 
 
2038
    classname = Getattr(parent, "sym:name");
 
2039
    type = Getattr(n, "type");
 
2040
    name = Getattr(n, "name");
 
2041
 
 
2042
    w = NewWrapper();
 
2043
    declaration = NewString("");
 
2044
        
 
2045
    /* determine if the method returns a pointer */
 
2046
    decl = Getattr(n, "decl");
 
2047
    is_pointer = SwigType_ispointer_return(decl);
 
2048
    is_void = (!Cmp(type, "void") && !is_pointer);
 
2049
 
 
2050
    /* form complete return type */
 
2051
    return_type = Copy(type);
 
2052
    {
 
2053
        SwigType *t = Copy(decl);
 
2054
        SwigType *f = 0;
 
2055
        f = SwigType_pop_function(t);
 
2056
        SwigType_push(return_type, t);
 
2057
        Delete(f);
 
2058
        Delete(t);
 
2059
    }
 
2060
 
 
2061
    /* virtual method definition */
 
2062
    l = Getattr(n, "parms");
 
2063
    String *target;
 
2064
    String *pclassname = NewStringf("SwigDirector_%s", classname);
 
2065
    String *qualified_name = NewStringf("%s::%s", pclassname, name);
 
2066
    target = Swig_method_decl(decl, qualified_name, l, 0, 0);
 
2067
    String *rtype = SwigType_str(type, 0);
 
2068
    Printf(w->def, "%s %s {", rtype, target);
 
2069
    Delete(qualified_name);
 
2070
    Delete(target);
 
2071
    /* header declaration */
 
2072
    target = Swig_method_decl(decl, name, l, 0, 1);
 
2073
    Printf(declaration, "    virtual %s %s;\n", rtype, target);
 
2074
    Delete(target);
 
2075
    
 
2076
    /* attach typemaps to arguments (C/C++ -> Ruby) */
 
2077
    String *arglist = NewString("");
 
2078
 
 
2079
 
 
2080
    /**
 
2081
     * For each parameter to the C++ member function, copy the parameter name
 
2082
     * to its "lname"; this ensures that Swig_typemap_attach_parms() will do
 
2083
     * the right thing when it sees strings like "$1" in your "directorin" typemaps.
 
2084
     * Not sure if it's OK to leave it like this, but seems OK so far.
 
2085
     */
 
2086
    typemap_copy_pname_to_lname(l);
 
2087
    
 
2088
    Swig_typemap_attach_parms("in", l, w);
 
2089
    Swig_typemap_attach_parms("directorin", l, w);
 
2090
    Swig_typemap_attach_parms("directorout", l, w);
 
2091
    Swig_typemap_attach_parms("directorargout", l, w);
 
2092
 
 
2093
    int num_arguments = emit_num_arguments(l);
 
2094
    int i;
 
2095
    char source[256];
 
2096
 
 
2097
    wrap_args = NewString("");
 
2098
    int outputs = 0;
 
2099
    if (!is_void) outputs++;
 
2100
        
 
2101
    /* build argument list and type conversion string */
 
2102
    for (i=0, idx=0, p = l; i < num_arguments; i++) {
 
2103
 
 
2104
      while (Getattr(p, "tmap:ignore")) {
 
2105
        p = Getattr(p, "tmap:ignore:next");
 
2106
      }
 
2107
 
 
2108
      if (Getattr(p, "tmap:directorargout") != 0) outputs++;
 
2109
      
 
2110
      String* parameterName = Getattr(p, "name");
 
2111
      String* parameterType = Getattr(p, "type");
 
2112
      
 
2113
      Putc(',',arglist);
 
2114
      if ((tm = Getattr(p, "tmap:directorin")) != 0) {
 
2115
        sprintf(source, "obj%d", idx++);
 
2116
        Replaceall(tm, "$input", source);
 
2117
        Replaceall(tm, "$owner", "0");
 
2118
        Printv(wrap_args, tm, "\n", NIL);
 
2119
        Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
 
2120
        Printv(arglist, source, NIL);
 
2121
        p = Getattr(p, "tmap:directorin:next");
 
2122
        continue;
 
2123
      } else if (Cmp(parameterType, "void")) {
 
2124
        /**
 
2125
         * Special handling for pointers to other C++ director classes.
 
2126
         * Ideally this would be left to a typemap, but there is currently no
 
2127
         * way to selectively apply the dynamic_cast<> to classes that have
 
2128
         * directors.  In other words, the type "SwigDirector_$1_lname" only exists
 
2129
         * for classes with directors.  We avoid the problem here by checking
 
2130
         * module.wrap::directormap, but it's not clear how to get a typemap to
 
2131
         * do something similar.  Perhaps a new default typemap (in addition
 
2132
         * to SWIGTYPE) called DIRECTORTYPE?
 
2133
         */
 
2134
        if (SwigType_ispointer(parameterType) || SwigType_isreference(parameterType)) {
 
2135
          Node *module = Getattr(parent, "module");
 
2136
          Node *target = Swig_directormap(module, parameterType);
 
2137
          sprintf(source, "obj%d", idx++);
 
2138
          String *nonconst = 0;
 
2139
          /* strip pointer/reference --- should move to Swig/stype.c */
 
2140
          String *nptype = NewString(Char(parameterType)+2);
 
2141
          /* name as pointer */
 
2142
          String *ppname = Copy(parameterName);
 
2143
          if (SwigType_isreference(parameterType)) {
 
2144
             Insert(ppname,0,"&");
 
2145
          }
 
2146
          /* if necessary, cast away const since Ruby doesn't support it! */
 
2147
          if (SwigType_isconst(nptype)) {
 
2148
            nonconst = NewStringf("nc_tmp_%s", parameterName);
 
2149
            String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(parameterType, 0), ppname);
 
2150
            Wrapper_add_localv(w, nonconst, SwigType_lstr(parameterType, 0), nonconst, nonconst_i, NIL);
 
2151
            Delete(nonconst_i);
 
2152
            Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
 
2153
                         "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(parameterType, parameterName), classname, name);
 
2154
          } else {
 
2155
            nonconst = Copy(ppname);
 
2156
          }
 
2157
          Delete(nptype);
 
2158
          Delete(ppname);
 
2159
          String *mangle = SwigType_manglestr(parameterType);
 
2160
          if (target) {
 
2161
            String *director = NewStringf("director_%s", mangle);
 
2162
            Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
 
2163
            Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
 
2164
            Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
 
2165
            Printf(wrap_args, "if (!%s) {\n", director);
 
2166
            Printf(wrap_args,   "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
 
2167
            Printf(wrap_args, "} else {\n");
 
2168
            Printf(wrap_args,   "%s = %s->swig_get_self();\n", source, director);
 
2169
            Printf(wrap_args, "}\n");
 
2170
            Delete(director);
 
2171
            Printv(arglist, source, NIL);
 
2172
          } else {
 
2173
            Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
 
2174
            Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", 
 
2175
                   source, nonconst, mangle); 
 
2176
            //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", 
 
2177
            //       source, nonconst, base);
 
2178
            Printv(arglist, source, NIL);
 
2179
          }
 
2180
          Delete(mangle);
 
2181
          Delete(nonconst);
 
2182
        } else {
 
2183
          Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
 
2184
                       "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(parameterType, 0), classname, name);
 
2185
          status = SWIG_NOWRAP;
 
2186
          break;
 
2187
        }
 
2188
      }
 
2189
      p = nextSibling(p);
 
2190
    }
 
2191
 
 
2192
    /* declare method return value 
 
2193
     * if the return value is a reference or const reference, a specialized typemap must
 
2194
     * handle it, including declaration of c_result ($result).
 
2195
     */
 
2196
    if (!is_void) {
 
2197
      Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
 
2198
    }
 
2199
    /* declare Ruby return value */
 
2200
    Wrapper_add_local(w, "result", "VALUE result");
 
2201
 
 
2202
    /* direct call to superclass if _up is set */
 
2203
    Printf(w->code, "if (swig_get_up()) {\n");
 
2204
    if (pure_virtual) {
 
2205
        Printf(w->code, "throw Swig::DirectorPureVirtualException();\n");
 
2206
    } else {
 
2207
        if (is_void) {
 
2208
          Printf(w->code, "%s;\n", Swig_method_call(super,l));
 
2209
          Printf(w->code, "return;\n");
 
2210
        } else {
 
2211
          Printf(w->code, "return %s;\n", Swig_method_call(super,l));
 
2212
        }
 
2213
    }
 
2214
    Printf(w->code, "}\n");
 
2215
    
 
2216
    /* wrap complex arguments to VALUEs */
 
2217
    Printv(w->code, wrap_args, NIL);
 
2218
 
 
2219
    /* pass the method call on to the Ruby object */
 
2220
    exceptionSafeMethodCall(classname, n, w, idx, arglist);
 
2221
 
 
2222
    /*
 
2223
    * Ruby method may return a simple object, or an Array of objects.
 
2224
    * For in/out arguments, we have to extract the appropriate VALUEs from the Array,
 
2225
    * then marshal everything back to C/C++ (return value and output arguments).
 
2226
    */
 
2227
 
 
2228
    /* Marshal return value and other outputs (if any) from VALUE to C/C++ type */
 
2229
 
 
2230
    String* cleanup = NewString("");
 
2231
    String* outarg = NewString("");
 
2232
 
 
2233
    if (outputs > 1) {
 
2234
      Wrapper_add_local(w, "output", "VALUE output");
 
2235
      Printf(w->code, "if (TYPE(result) != T_ARRAY) {\n");
 
2236
      Printf(w->code, "throw Swig::DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n");
 
2237
      Printf(w->code, "}\n");
 
2238
    }
 
2239
 
 
2240
    idx = 0;
 
2241
 
 
2242
    /* Marshal return value */
 
2243
    if (!is_void) {
 
2244
      /* This seems really silly.  The node's type excludes qualifier/pointer/reference markers,
 
2245
       * which have to be retrieved from the decl field to construct return_type.  But the typemap
 
2246
       * lookup routine uses the node's type, so we have to swap in and out the correct type.
 
2247
       * It's not just me, similar silliness also occurs in Language::cDeclaration().
 
2248
       */
 
2249
      Setattr(n, "type", return_type);
 
2250
      tm = Swig_typemap_lookup_new("directorout", n, "result", w);
 
2251
      Setattr(n, "type", type);
 
2252
      if (tm == 0) {
 
2253
        String *name = NewString("result");
 
2254
        tm = Swig_typemap_search("directorout", return_type, name, NULL);
 
2255
        Delete(name);
 
2256
      }
 
2257
      if (tm != 0) {
 
2258
        if (outputs > 1) {
 
2259
          Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
 
2260
          Replaceall(tm, "$input", "output");
 
2261
        } else {
 
2262
          Replaceall(tm, "$input", "result");
 
2263
        }
 
2264
        /* TODO check this */
 
2265
        if (Getattr(n,"wrap:disown")) {
 
2266
          Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
 
2267
        } else {
 
2268
          Replaceall(tm,"$disown","0");
 
2269
        }
 
2270
        Replaceall(tm, "$result", "c_result");
 
2271
        Printv(w->code, tm, "\n", NIL);
 
2272
      } else {
 
2273
        Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
 
2274
                     "Unable to return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), classname, name);
 
2275
        status = SWIG_ERROR;
 
2276
      }
 
2277
    }
 
2278
          
 
2279
    /* Marshal outputs */
 
2280
    for (p = l; p; ) {
 
2281
      if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
 
2282
        if (outputs > 1) {
 
2283
          Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
 
2284
          Replaceall(tm, "$input", "output");
 
2285
        } else {
 
2286
          Replaceall(tm, "$input", "result");
 
2287
        }
 
2288
        Replaceall(tm, "$result", Getattr(p, "name"));
 
2289
        Printv(w->code, tm, "\n", NIL);
 
2290
        p = Getattr(p, "tmap:directorargout:next");
 
2291
      } else {
 
2292
        p = nextSibling(p);
 
2293
      }
 
2294
    }
 
2295
 
 
2296
    /* any existing helper functions to handle this? */
 
2297
    if (!is_void) {
 
2298
      if (!SwigType_isreference(return_type)) {
 
2299
        Printf(w->code, "return c_result;\n");
 
2300
      } else {
 
2301
        Printf(w->code, "return *c_result;\n");
 
2302
      }
 
2303
    }
 
2304
 
 
2305
    Printf(w->code, "}\n");
 
2306
 
 
2307
    /* emit the director method */
 
2308
    if (status == SWIG_OK) {
 
2309
      Wrapper_print(w, f_directors);
 
2310
      Printv(f_directors_h, declaration, NIL);
 
2311
    }
 
2312
 
 
2313
    /* clean up */
 
2314
    Delete(wrap_args);
 
2315
    Delete(arglist);
 
2316
    Delete(rtype);
 
2317
    Delete(return_type);
 
2318
    Delete(pclassname);
 
2319
    Delete(cleanup);
 
2320
    Delete(outarg);
 
2321
    DelWrapper(w);
 
2322
    return status;
 
2323
  }
 
2324
  
 
2325
  virtual int classDirectorConstructors(Node *n) {
 
2326
    return Language::classDirectorConstructors(n);
 
2327
  }
 
2328
  
 
2329
  virtual int classDirectorMethods(Node *n) {
 
2330
    return Language::classDirectorMethods(n);
 
2331
  }
 
2332
  
 
2333
  virtual int classDirectorDisown(Node *n) {
 
2334
    return Language::classDirectorDisown(n);
 
2335
  }
 
2336
 
 
2337
  void typemap_copy_pname_to_lname(ParmList *parms)
 
2338
  {
 
2339
    Parm *p;
 
2340
    String *pname;
 
2341
    String *lname;
 
2342
 
 
2343
    p = parms;
 
2344
    while (p) {
 
2345
      pname = Getattr(p,"name");
 
2346
      lname = Copy(pname);
 
2347
      Setattr(p,"lname",lname);
 
2348
      p = nextSibling(p);
 
2349
    }
 
2350
  }
 
2351
};  /* class RUBY */
 
2352
  
 
2353
/* -----------------------------------------------------------------------------
 
2354
 * swig_ruby()    - Instantiate module
 
2355
 * ----------------------------------------------------------------------------- */
 
2356
 
 
2357
extern "C" Language *
 
2358
swig_ruby(void) {
 
2359
  return new RUBY();
 
2360
}
 
2361
 
 
2362
 
 
2363
/*
 
2364
 * Local Variables:
 
2365
 * c-basic-offset: 2
 
2366
 * End:
 
2367
 */
 
2368