1
/********************************************************************
4
* $Header: /cvsroot/SWIG/Source/Modules/ruby.cxx,v 1.47 2003/12/22 17:23:02 ljohnson Exp $
6
* Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
7
* Copyright (C) 2000 Information-technology Promotion Agency, Japan
11
********************************************************************/
13
char cvsroot_ruby_cxx[] = "$Header: /cvsroot/SWIG/Source/Modules/ruby.cxx,v 1.47 2003/12/22 17:23:02 ljohnson Exp $";
16
#define SWIG_PROTECTED_TARGET_METHODS 1
19
#include "swigconfig.h"
24
#include <limits.h> /* for INT_MAX */
30
String *name; /* class name (renamed) */
31
String *cname; /* original C class/struct name */
32
String *mname; /* Mangled name */
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.
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.
55
int constructor_defined;
56
int destructor_defined;
61
cname = NewString("");
62
mname = NewString("");
63
vname = NewString("");
64
mImpl = NewString("");
66
prefix = NewString("");
67
header = NewString("");
69
constructor_defined = 0;
70
destructor_defined = 0;
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 */
93
mname = Swig_name_mangle(cname);
95
/* Renamed class name */
99
/* Variable name for the VALUE that refers to the Ruby Class object */
101
Printf(vname, "c%s.klass", name);
103
/* Variable name for the VALUE that refers to the Ruby Class object */
105
Printf(mImpl, "c%s.mImpl", name);
109
Printv(prefix,(rn ? rn : cn), "_", NIL);
112
char *strip(const String_or_char *s) {
115
if (Strncmp(s, prefix, Len(prefix)) == 0) {
116
Replaceall(temp,prefix,"");
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";
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))
136
class RUBY : public Language {
143
Hash *classes; /* key=cname val=RClass */
144
RClass *klass; /* Currently processing class */
145
Hash *special_methods; /* Python style special method name table */
156
bool useGlobalModule;
157
bool multipleInheritance;
163
CONSTRUCTOR_ALLOCATE,
164
CONSTRUCTOR_INITIALIZE,
174
/* ---------------------------------------------------------------------
177
* Initialize member data
178
* --------------------------------------------------------------------- */
193
useGlobalModule = false;
194
multipleInheritance = false;
197
/* ---------------------------------------------------------------------
200
* Parse command line options and initializes variables.
201
* --------------------------------------------------------------------- */
203
virtual void main(int argc, char *argv[]) {
205
/* Set location of SWIG library */
206
SWIG_library_directory("ruby");
208
/* Look for certain command line options */
209
for (int i = 1; i < argc; i++) {
211
if (strcmp(argv[i],"-feature") == 0) {
213
char *name = argv[i+1];
214
feature = NewString(name);
221
} else if (strcmp(argv[i],"-globalmodule") == 0) {
222
useGlobalModule = true;
224
} else if (strcmp(argv[i],"-minherit") == 0) {
225
multipleInheritance = true;
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);
236
/* Add a symbol to the parser for conditional compilation */
237
Preprocessor_define("SWIGRUBY 1", 0);
239
/* Add typemap definitions */
240
SWIG_typemap_lang("ruby");
241
SWIG_config_file("ruby.swg");
246
* Generate initialization code to define the Ruby module(s),
247
* accounting for nested modules as necessary.
249
void defineRubyModule() {
250
List *modules = Split(module,':',INT_MAX);
251
if (modules != 0 && Len(modules) > 0) {
256
if (Len(m.item) > 0) {
258
Printv(f_init, tab4, modvar,
259
" = rb_define_module_under(", modvar, ", \"", m.item, "\");\n", NIL);
261
Printv(f_init, tab4, modvar,
262
" = rb_define_module(\"", m.item, "\");\n", NIL);
263
mv = NewString(modvar);
273
void registerMagicMethods() {
275
special_methods = NewHash();
277
/* Python style special method name. */
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?");
286
Setattr(special_methods, "__call__", "call");
289
Setattr(special_methods, "__len__", "length");
290
Setattr(special_methods, "__getitem__", "[]");
291
Setattr(special_methods, "__setitem__", "[]=");
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__", "==");
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");
322
/* ---------------------------------------------------------------------
324
* --------------------------------------------------------------------- */
326
virtual int top(Node *n) {
329
* See if any Ruby module options have been specified as options
330
* to the %module directive.
332
Node *swigModule = Getattr(n, "module");
334
Node *options = Getattr(swigModule, "options");
336
if (Getattr(options, "directors")) {
339
if (Getattr(options, "dirprot")) {
342
if (Getattr(options, "ruby_globalmodule")) {
343
useGlobalModule = true;
345
if (Getattr(options, "ruby_minherit")) {
346
multipleInheritance = true;
351
/* Set comparison with none for ConstructorToFunction */
352
setSubclassInstanceCheck(NewString("CLASS_OF(self) != Qnil")); // FIXME
353
// setSubclassInstanceCheck(NewString("CLASS_OF(self) != cFoo.klass"));
355
/* Initialize all of the output files */
356
String *outfile = Getattr(n,"outfile");
357
String *outfile_h = Getattr(n, "outfile_h");
359
f_runtime = NewFile(outfile,"w");
361
Printf(stderr,"*** Can't open '%s'\n", outfile);
362
SWIG_exit(EXIT_FAILURE);
365
if (directorsEnabled()) {
366
f_runtime_h = NewFile(outfile_h,"w");
368
Printf(stderr,"*** Can't open '%s'\n", outfile_h);
369
SWIG_exit(EXIT_FAILURE);
373
f_init = NewString("");
374
f_header = NewString("");
375
f_wrappers = NewString("");
376
f_directors_h = NewString("");
377
f_directors = NewString("");
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);
392
registerMagicMethods();
394
Swig_banner(f_runtime);
397
Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
400
if (directorsEnabled()) {
401
Printf(f_runtime,"#define SWIG_DIRECTORS\n");
404
/* typedef void *VALUE */
405
SwigType *value = NewSwigType(T_VOID);
406
SwigType_add_pointer(value);
407
SwigType_typedef(value,(char*)"VALUE");
410
/* Set module name */
411
set_module(Char(Getattr(n,"name")));
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));
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);
430
/* Start generating the initialization function */
433
"#ifdef __cplusplus\n",
436
"SWIGEXPORT(void) Init_", feature, "(void) {\n",
441
Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL);
443
if (!useGlobalModule)
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",
457
/* Finish off our init function */
458
Printf(f_init,"}\n");
459
SwigType_emit_type_table(f_runtime,f_wrappers);
461
/* Close all of the files */
462
Dump(f_header,f_runtime);
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");
472
Dump(f_wrappers,f_runtime);
473
Wrapper_pretty_print(f_init,f_runtime);
484
/* -----------------------------------------------------------------------------
486
* ----------------------------------------------------------------------------- */
488
virtual int importDirective(Node *n) {
489
String *modname = Getattr(n,"module");
491
Printf(f_init,"rb_require(\"%s\");\n", modname);
493
return Language::importDirective(n);
496
/* ---------------------------------------------------------------------
497
* set_module(const char *mod_name)
499
* Sets the module name. Does nothing if it's already set (so it can
500
* be overridden as a command line option).
501
*---------------------------------------------------------------------- */
503
void set_module(const char *s) {
504
String *mod_name = NewString(s);
506
/* Start with the empty string */
507
module = NewString("");
509
/* Account for nested modules */
510
List *modules = Split(mod_name,':',INT_MAX);
511
if (modules != 0 && Len(modules) > 0) {
513
Iterator m = First(modules);
515
if (Len(m.item) > 0) {
516
String *cap = NewString(m.item);
517
(Char(cap))[0] = toupper((Char(cap))[0]);
519
Append(module, "::");
527
feature = Copy(last);
529
(Char(last))[0] = toupper((Char(last))[0]);
530
modvar = NewStringf("m%s", last);
537
/* --------------------------------------------------------------------------
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);
548
* Process the comma-separated list of aliases (if any).
550
void defineAliases(Node *n, const String_or_char *iname) {
551
String *aliasv = Getattr(n,"feature:alias");
553
List *aliases = Split(aliasv,',',INT_MAX);
554
if (aliases && Len(aliases) > 0) {
555
Iterator alias = First(aliases);
557
if (Len(alias.item) > 0) {
558
Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
567
/* ---------------------------------------------------------------------
568
* create_command(Node *n, char *iname)
570
* Creates a new command from a C function.
571
* iname = Name of function in scripting language
573
* A note about what "protected" and "private" mean in Ruby:
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.
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
* --------------------------------------------------------------------- */
584
void create_command(Node *n, const String_or_char *iname) {
586
String *alloc_func = Swig_name_wrapper(iname);
587
String *wname = Swig_name_wrapper(iname);
589
Insert(wname,0,"VALUEFUNC(");
592
if (current != NO_CPP)
593
iname = klass->strip(iname);
594
if (Getattr(special_methods, iname)) {
595
iname = GetChar(special_methods, iname);
598
String *s = NewString("");
599
String *temp = NewString("");
604
#ifdef SWIG_PROTECTED_TARGET_METHODS
605
const char* rb_define_method = is_protected(n) ?
606
"rb_define_protected_method" : "rb_define_method";
608
const char* rb_define_method = "rb_define_method";
610
if (multipleInheritance) {
611
Printv(klass->init, tab4, rb_define_method,"(", klass->mImpl, ", \"",
612
iname, "\", ", wname, ", -1);\n", NIL);
614
Printv(klass->init, tab4, rb_define_method, "(", klass->vname, ", \"",
615
iname, "\", ", wname, ", -1);\n", NIL);
619
case CONSTRUCTOR_ALLOCATE:
620
Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL);
621
Replaceall(klass->init,"$allocator", s);
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);
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);
636
Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
637
temp, "\", ", wname, ", -1);\n", NIL);
641
Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname,
642
", \"", iname, "\", ", wname, ", -1);\n", NIL);
645
if (!useGlobalModule) {
646
Printv(s, tab4, "rb_define_module_function(", modvar, ", \"",
647
iname, "\", ", wname, ", -1);\n",NIL);
648
Printv(f_init,s,NIL);
650
Printv(s, tab4, "rb_define_global_function(\"",
651
iname, "\", ", wname, ", -1);\n",NIL);
652
Printv(f_init,s,NIL);
658
assert(false); // Should not have gotten here for these types
663
defineAliases(n, iname);
671
/* ---------------------------------------------------------------------
672
* applyInputTypemap()
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
* --------------------------------------------------------------------- */
679
Parm *applyInputTypemap(Parm *p, String *ln, String *source, Wrapper *f) {
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");
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));
697
Parm *skipIgnoredArgs(Parm *p) {
698
while (checkAttribute(p,"tmap:in:numinputs","0")) {
699
p = Getattr(p,"tmap:in:next");
704
/* ---------------------------------------------------------------------
707
* Process all of the arguments passed into the scripting language
708
* method and convert them into C/C++ function arguments using the
710
* --------------------------------------------------------------------- */
712
void marshalInputArgs(Node *n, ParmList *l, int numarg, int numreq, String *kwargs, bool allow_kwargs, Wrapper *f) {
719
source = NewString("");
720
target = NewString("");
722
bool use_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
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].
731
int start = (current == MEMBER_FUNC || current == MEMBER_VAR || use_director) ? 1 : 0;
733
int varargs = emit_isvarargs(l);
736
for (i = 0, p = l; i < numarg; i++) {
738
p = skipIgnoredArgs(p);
740
String *pn = Getattr(p,"name");
741
String *ln = Getattr(p,"lname");
743
/* Produce string representation of source argument */
746
/* First argument is a special case */
748
Printv(source, (start == 0) ? "argv[0]" : "self", NIL);
750
Printf(source,"argv[%d]",i-start);
753
/* Produce string representation of target argument */
755
Printf(target,"%s",Char(ln));
757
if (i >= (numreq)) { /* Check if parsing an optional argument */
758
Printf(f->code," if (argc > %d) {\n", i - start);
761
/* Record argument name for keyword argument handling */
763
Printf(kwargs,"\"%s\",", pn);
765
Printf(kwargs,"\"arg%d\",", i+1);
768
/* Look for an input typemap */
769
p = applyInputTypemap(p, ln, source, f);
771
Printf(f->code,"}\n");
775
/* Finish argument marshalling */
776
Printf(kwargs," NULL }");
778
Printv(f->locals, tab4, "char *kwnames[] = ", kwargs, ";\n", NIL);
781
/* Trailing varargs */
783
if (p && (tm = Getattr(p,"tmap:in"))) {
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");
798
/* ---------------------------------------------------------------------
799
* insertConstraintCheckingCode(ParmList *l, Wrapper *f)
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
* --------------------------------------------------------------------- */
806
void insertConstraintCheckingCode(ParmList *l, Wrapper *f) {
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");
820
/* ---------------------------------------------------------------------
821
* insertCleanupCode(ParmList *l, String *cleanup)
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
* --------------------------------------------------------------------- */
828
void insertCleanupCode(ParmList *l, String *cleanup) {
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");
841
/* ---------------------------------------------------------------------
842
* insertArgOutputCode(ParmList *l, String *outarg, int& need_result)
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
* --------------------------------------------------------------------- */
849
void insertArgOutputCode(ParmList *l, String *outarg, int& need_result) {
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);
860
p = Getattr(p,"tmap:argout:next");
867
/* ---------------------------------------------------------------------
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 ("=").
875
* Methods whose names end with question marks are, by convention,
876
* predicate methods that return true or false (e.g. Array#empty?).
878
* Methods whose names end with exclamation points are, by convention,
879
* "mutators" that modify the instance in place (e.g. Array#sort!).
881
* Methods whose names end with an equals sign are attribute setters
882
* (e.g. Thread#critical=).
883
* --------------------------------------------------------------------- */
885
virtual int validIdentifier(String *s) {
888
if ( !( isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=') ) ) return 0;
894
/* ---------------------------------------------------------------------
897
* Create a function declaration and register it with the interpreter.
898
* --------------------------------------------------------------------- */
900
virtual int functionWrapper(Node *n) {
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");
915
/* Ruby needs no destructor wrapper */
916
if (current == DESTRUCTOR)
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);
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
930
if (current == CONSTRUCTOR_ALLOCATE &&
931
Swig_symbol_isoverloaded(n) &&
932
Getattr(n, "sym:nextSibling") != 0) return SWIG_OK;
934
String *overname = 0;
935
if (Getattr(n, "sym:overloaded")) {
936
overname = Getattr(n, "sym:overname");
938
if (!addSymbol(symname, n))
942
String *cleanup = NewString("");
943
String *outarg = NewString("");
944
String *kwargs = NewString("");
945
Wrapper *f = NewWrapper();
947
/* Rename predicate methods */
948
if (Getattr(n, "feature:predicate")) {
949
Append(symname, "?");
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);
959
if (current != CONSTRUCTOR_ALLOCATE) {
963
/* Attach standard typemaps */
964
if (current != CONSTRUCTOR_ALLOCATE) {
965
emit_attach_parmmaps(l, f);
967
Setattr(n, "wrap:parms", l);
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");
975
bool use_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
976
int start = (current == MEMBER_FUNC || current == MEMBER_VAR || use_director) ? 1 : 0;
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);
988
Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start);
990
Printf(f->code,"if (argc < %d)\n", numreq-start);
992
Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start);
994
Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
996
Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start);
998
Printf(f->code,"if (argc < %d)\n", numreq-start);
1000
Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start);
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);
1015
/* Insert constraint checking code */
1016
insertConstraintCheckingCode(l, f);
1018
/* Insert cleanup code */
1019
insertCleanupCode(l, cleanup);
1021
/* Insert argument output code */
1022
insertArgOutputCode(l, outarg, need_result);
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.
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
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");
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");
1059
Append(action,"DATA_PTR(self) = result;");
1065
/* Return value if necessary */
1066
if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_ALLOCATE && current != CONSTRUCTOR_INITIALIZE) {
1068
if (Getattr(n, "feature:predicate")) {
1069
Printv(f->code, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL);
1071
tm = Swig_typemap_lookup_new("out",n,"result",0);
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");
1079
Replaceall(tm,"$owner", "0");
1081
// FIXME: this will not try to unwrap directors returned as non-director
1082
// base class pointers!
1084
/* New addition to unwrap director return values so that the original
1085
* python object is returned instead.
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;
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");
1108
Printf(f->code,"%s\n", tm);
1111
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
1112
"Unable to use return type %s.\n", SwigType_str(t,0));
1117
/* Extra code needed for new and initialize methods */
1118
if (current == CONSTRUCTOR_ALLOCATE) {
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) {
1126
// Printf(f->code, "DATA_PTR(self) = result;\n");
1129
/* Dump argument output code; */
1130
Printv(f->code,outarg,NIL);
1132
/* Dump the argument cleanup code */
1133
if (current != CONSTRUCTOR_ALLOCATE)
1134
Printv(f->code,cleanup,NIL);
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);
1140
Replaceall(tm,"$source","result");
1141
Printv(f->code,tm, "\n",NIL);
1145
/* Special processing on return value. */
1146
tm = Swig_typemap_lookup_new("ret",n,"result",0);
1148
Replaceall(tm,"$source","result");
1149
Printv(f->code,tm, NIL);
1152
/* Wrap things up (in a manner of speaking) */
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);
1159
Wrapper_add_local(f,"vresult","VALUE vresult = Qnil");
1160
Printv(f->code, tab4, "return vresult;\n", NIL);
1163
Printv(f->code, tab4, "return Qnil;\n", NIL);
1166
/* Error handling code */
1168
Printf(f->code,"fail:\n");
1169
Printv(f->code,cleanup,NIL);
1170
Printv(f->code,"return Qnil;\n",NIL);
1172
Printf(f->code,"}\n");
1174
/* Substitute the cleanup code */
1175
Replaceall(f->code,"$cleanup",cleanup);
1177
/* Emit the function */
1178
Wrapper_print(f, f_wrappers);
1180
/* Now register the function with the interpreter */
1181
if (!Swig_symbol_isoverloaded(n)) {
1182
create_command(n, symname);
1184
if (current == CONSTRUCTOR_ALLOCATE) {
1185
create_command(n, symname);
1187
Setattr(n, "wrap:name", wname);
1188
if (!Getattr(n, "sym:nextSibling"))
1189
dispatchFunction(n);
1202
/* ------------------------------------------------------------
1203
* dispatchFunction()
1204
* ------------------------------------------------------------ */
1206
void dispatchFunction(Node *n) {
1207
/* Last node in overloaded chain */
1210
String *tmp = NewString("");
1211
String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs);
1213
/* Generate a dispatch wrapper for all overloaded functions */
1215
Wrapper *f = NewWrapper();
1216
String *symname = Getattr(n, "sym:name");
1217
String *wname = Swig_name_wrapper(symname);
1220
"static VALUE ", wname,
1221
"(int nargs, VALUE *args, VALUE self) {",
1224
Wrapper_add_local(f, "argc", "int argc");
1225
if (current == MEMBER_FUNC || current == MEMBER_VAR) {
1226
Printf(tmp, "VALUE argv[%d]", maxargs+1);
1228
Printf(tmp, "VALUE argv[%d]", maxargs);
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");
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");
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));
1259
/* ---------------------------------------------------------------------
1261
* --------------------------------------------------------------------- */
1263
virtual int variableWrapper(Node *n) {
1265
char *name = GetChar(n,"name");
1266
char *iname = GetChar(n,"sym:name");
1267
SwigType *t = Getattr(n,"type");
1269
String *getfname, *setfname;
1270
Wrapper *getf, *setf;
1272
getf = NewWrapper();
1273
setf = NewWrapper();
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");
1282
tm = Swig_typemap_lookup_new("varout",n, name, 0);
1284
Replaceall(tm,"$result","_val");
1285
Replaceall(tm,"$target","_val");
1286
Replaceall(tm,"$source",name);
1287
Printv(getf->code,tm, NIL);
1289
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
1290
"Unable to read variable of type %s\n", SwigType_str(t,0));
1292
Printv(getf->code, tab4, "return _val;\n}\n", NIL);
1293
Wrapper_print(getf,f_wrappers);
1295
if (Getattr(n,"feature:immutable")) {
1296
setfname = NewString("NULL");
1299
setfname = NewString(Swig_name_set(iname));
1300
Printv(setf->def, "static VALUE\n", setfname, "(VALUE self, ", NIL);
1301
Printf(setf->def, "VALUE _val) {");
1303
tm = Swig_typemap_lookup_new("varin",n,name,0);
1305
Replaceall(tm,"$input","_val");
1306
Replaceall(tm,"$source","_val");
1307
Replaceall(tm,"$target",name);
1308
Printv(setf->code,tm,"\n",NIL);
1310
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number,
1311
"Unable to set variable of type %s\n", SwigType_str(t,0));
1313
Printv(setf->code, tab4, "return _val;\n",NIL);
1314
Printf(setf->code,"}\n");
1315
Wrapper_print(setf,f_wrappers);
1318
/* define accessor method */
1320
Insert(getfname,0,"VALUEFUNC(");
1321
Append(getfname,")");
1322
Insert(setfname,0,"VALUEFUNC(");
1323
Append(setfname,")");
1326
String *s = NewString("");
1329
/* C++ class variable */
1331
tab4, "rb_define_singleton_method(", klass->vname, ", \"",
1332
klass->strip(iname), "\", ", getfname, ", 0);\n",
1334
if (!Getattr(n,"feature:immutable")) {
1336
tab4, "rb_define_singleton_method(", klass->vname, ", \"",
1337
klass->strip(iname), "=\", ", setfname, ", 1);\n",
1340
Printv(klass->init,s,NIL);
1343
/* C global variable */
1344
/* wrapped in Ruby module attribute */
1345
assert(current == NO_CPP);
1346
if (!useGlobalModule) {
1348
tab4, "rb_define_singleton_method(", modvar, ", \"",
1349
iname, "\", ", getfname, ", 0);\n",
1351
if (!Getattr(n,"feature:immutable")) {
1353
tab4, "rb_define_singleton_method(", modvar, ", \"",
1354
iname, "=\", ", setfname, ", 1);\n",
1359
tab4, "rb_define_global_method(\"",
1360
iname, "\", ", getfname, ", 0);\n",
1362
if (!Getattr(n,"feature:immutable")) {
1364
tab4, "rb_define_global_method(\"",
1365
iname, "=\", ", setfname, ", 1);\n",
1369
Printv(f_init,s,NIL);
1381
/* ---------------------------------------------------------------------
1382
* validate_const_name(char *name)
1384
* Validate constant name.
1385
* --------------------------------------------------------------------- */
1388
validate_const_name(char *name, const char *reason) {
1389
if (!name || name[0] == '\0')
1392
if (isupper(name[0]))
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);
1402
Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number,
1403
"Wrong %s name\n", reason);
1408
/* ---------------------------------------------------------------------
1410
* --------------------------------------------------------------------- */
1412
virtual int constantWrapper(Node *n) {
1413
Swig_require("constantWrapper",n, "*sym:name", "type", "value", NIL);
1415
char *iname = GetChar(n,"sym:name");
1416
SwigType *type = Getattr(n,"type");
1417
char *value = GetChar(n,"value");
1419
if (current == CLASS_CONST) {
1420
iname = klass->strip(iname);
1422
validate_const_name(iname, "constant");
1423
SetChar(n, "sym:name", iname);
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);
1431
String *tm = Swig_typemap_lookup_new("constant", n, value, 0);
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);
1442
Replaceall(tm, "$module", klass->vname);
1443
Printv(klass->init, tm, "\n", NIL);
1446
if (!useGlobalModule) {
1447
Replaceall(tm, "$module", modvar);
1449
Replaceall(tm, "$module", "rb_cObject");
1451
Printf(f_init, "%s\n", tm);
1454
Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
1455
"Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
1461
/* -----------------------------------------------------------------------------
1462
* classDeclaration()
1464
* Records information about classes---even classes that might be defined in
1465
* other modules referenced by %import.
1466
* ----------------------------------------------------------------------------- */
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");
1473
name = tdname ? tdname : name;
1474
String *namestr = SwigType_namestr(name);
1475
klass = RCLASS(classes, Char(namestr));
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);
1485
return Language::classDeclaration(n);
1489
* Process the comma-separated list of mixed-in module names (if any).
1491
void includeRubyModules(Node *n) {
1492
String *mixin = Getattr(n,"feature:mixin");
1494
List *modules = Split(mixin,',',INT_MAX);
1495
if (modules && Len(modules) > 0) {
1496
Iterator mod = First(modules);
1498
if (Len(mod.item) > 0) {
1499
Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod.item);
1508
void handleBaseClasses(Node *n) {
1509
List *baselist = Getattr(n,"bases");
1510
if (baselist && Len(baselist)) {
1511
Iterator base = First(baselist);
1513
String *basename = Getattr(base.item,"name");
1514
String *basenamestr = SwigType_namestr(basename);
1515
RClass *super = RCLASS(classes, Char(basenamestr));
1516
Delete(basenamestr);
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);
1528
String *bmangle = SwigType_manglestr(btype);
1529
Insert(bmangle,0,"((swig_class *) SWIGTYPE");
1530
Append(bmangle,"->clientdata)->klass");
1531
Replaceall(klass->init,"$super",bmangle);
1537
if (!multipleInheritance) {
1538
/* Warn about multiple inheritance for additional base class(es) listed */
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);
1551
* Check to see if a %markfunc was specified.
1553
void handleMarkFuncDirective(Node *n) {
1554
String *markfunc = Getattr(n, "feature:markfunc");
1556
Printf(klass->init, "c%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc);
1558
Printf(klass->init, "c%s.mark = 0;\n", klass->name);
1563
* Check to see if a %freefunc was specified.
1565
void handleFreeFuncDirective(Node *n) {
1566
String *freefunc = Getattr(n, "feature:freefunc");
1568
Printf(klass->init, "c%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc);
1570
if (klass->destructor_defined) {
1571
Printf(klass->init, "c%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname);
1574
Replaceall(klass->header,"$freeproto", "");
1577
/* ----------------------------------------------------------------------
1579
* ---------------------------------------------------------------------- */
1581
virtual int classHandler(Node *n) {
1583
String *name = Getattr(n,"name");
1584
String *symname = Getattr(n,"sym:name");
1585
String *namestr = SwigType_namestr(name); // does template expansion
1587
klass = RCLASS(classes, Char(namestr));
1590
String *valid_name = NewString(symname);
1591
validate_const_name(Char(valid_name), "class");
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);
1602
Printv(klass->init, klass->vname, " = rb_define_class(\"",
1603
klass->name, "\", rb_cObject);\n", NIL);
1605
Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\n", NIL);
1607
if (!useGlobalModule) {
1608
Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
1609
", \"", klass->name, "\", $super);\n", NIL);
1611
Printv(klass->init, klass->vname, " = rb_define_class(\"",
1612
klass->name, "\", $super);\n", NIL);
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);
1625
includeRubyModules(n);
1627
Printv(klass->init, "$allocator",NIL);
1628
Printv(klass->init, "$initializer",NIL);
1630
Printv(klass->header,
1634
Language::classHandler(n);
1636
handleBaseClasses(n);
1637
handleMarkFuncDirective(n);
1638
handleFreeFuncDirective(n);
1640
if (multipleInheritance) {
1641
Printv(klass->init, "rb_include_module(", klass->vname, ", ", klass->mImpl, ");\n", NIL);
1644
Printv(f_header, klass->header,NIL);
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");
1653
Printv(f_init,klass->init,NIL);
1658
/* ----------------------------------------------------------------------
1659
* memberfunctionHandler()
1661
* Method for adding C++ member function
1663
* By default, we're going to create a function of the form :
1665
* Foo_bar(this,args)
1667
* Where Foo is the classname, bar is the member name and the this pointer
1668
* is explicitly attached to the beginning.
1670
* The renaming only applies to the member function part, not the full
1673
* --------------------------------------------------------------------- */
1675
virtual int memberfunctionHandler(Node *n) {
1676
current = MEMBER_FUNC;
1677
Language::memberfunctionHandler(n);
1682
/* ---------------------------------------------------------------------
1683
* constructorHandler()
1685
* Method for adding C++ member constructor
1686
* -------------------------------------------------------------------- */
1688
virtual int constructorHandler(Node *n) {
1689
int use_director = Swig_directorclass(n);
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);
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')
1701
Swig_save("ruby:constructorHandler",n,"parms",NIL);
1703
Parm *parms = Getattr(n, "parms");
1705
String *name = NewString("self");
1706
String *type = NewString("VALUE");
1707
self = NewParm(type, name);
1710
Setattr(self, "lname", "Qnil");
1711
if (parms) set_nextSibling(self, parms);
1712
Setattr(n, "parms", self);
1713
Setattr(n, "wrap:self", "1");
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);
1722
/* Restore original parameter list */
1723
Delattr(n, "wrap:self");
1727
Swig_name_unregister((String_or_char *) "construct");
1729
klass->constructor_defined = 1;
1733
/* ---------------------------------------------------------------------
1734
* destructorHandler()
1735
* -------------------------------------------------------------------- */
1737
virtual int destructorHandler(Node *n) {
1738
current = DESTRUCTOR;
1739
Language::destructorHandler(n);
1741
String *freefunc = NewString("");
1742
String *freeproto = NewString("");
1743
String *freebody = NewString("");
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",
1751
String *wrap = Getattr(n, "wrap:code");
1753
File *f_code = Swig_filebyname("header");
1755
Printv(f_code, wrap, NIL);
1758
/* Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", NIL); */
1759
Printv(freebody,Getattr(n,"wrap:action"), NIL);
1761
/* When no extend mode, swig emits no destroy function. */
1763
Printf(freebody, "delete %s", Swig_cparm_name(0,0));
1765
Printf(freebody, "free((char*) %s)", Swig_cparm_name(0,0));
1767
Printv(freebody, ";\n}\n", NIL);
1769
Replaceall(klass->header,"$freeproto", freeproto);
1770
Printv(f_wrappers, freebody, NIL);
1772
klass->destructor_defined = 1;
1780
/* ---------------------------------------------------------------------
1781
* membervariableHandler()
1783
* This creates a pair of functions to set/get the variable of a member.
1784
* -------------------------------------------------------------------- */
1786
virtual int membervariableHandler(Node *n) {
1787
current = MEMBER_VAR;
1788
Language::membervariableHandler(n);
1793
/* -----------------------------------------------------------------------
1794
* staticmemberfunctionHandler()
1796
* Wrap a static C++ function
1797
* ---------------------------------------------------------------------- */
1799
virtual int staticmemberfunctionHandler(Node *n) {
1800
current = STATIC_FUNC;
1801
Language::staticmemberfunctionHandler(n);
1806
/* ----------------------------------------------------------------------
1807
* memberconstantHandler()
1809
* Create a C++ constant
1810
* --------------------------------------------------------------------- */
1812
virtual int memberconstantHandler(Node *n) {
1813
current = CLASS_CONST;
1814
Language::memberconstantHandler(n);
1819
/* ---------------------------------------------------------------------
1820
* staticmembervariableHandler()
1821
* --------------------------------------------------------------------- */
1823
virtual int staticmembervariableHandler(Node *n) {
1824
current = STATIC_VAR;
1825
Language::staticmembervariableHandler(n);
1830
/* C++ director class generation */
1831
virtual int classDirector(Node *n) {
1832
return Language::classDirector(n);
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);
1845
virtual int classDirectorEnd(Node *n) {
1846
Printf(f_directors_h, "};\n\n");
1847
return Language::classDirectorEnd(n);
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);
1854
/* ------------------------------------------------------------
1855
* classDirectorConstructor()
1856
* ------------------------------------------------------------ */
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);
1866
/* insert self and disown parameters */
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);
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);
1883
Wrapper *w = NewWrapper();
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);
1890
Wrapper_print(w, f_directors);
1895
/* constructor header */
1897
String *target = Swig_method_decl(decl, classname, parms, 0, 1);
1898
Printf(f_directors_h, " %s;\n", target);
1906
return Language::classDirectorConstructor(n);
1909
virtual int classDirectorDefaultConstructor(Node *n) {
1912
classname = Swig_class_name(n);
1914
Printf(w->def, "SwigDirector_%s::SwigDirector_%s(VALUE self, bool disown) : Swig::Director(self, disown) { }", classname, classname);
1915
Wrapper_print(w, f_directors);
1917
Printf(f_directors_h, " SwigDirector_%s(VALUE self, bool disown = true);\n", classname);
1919
return Language::classDirectorDefaultConstructor(n);
1922
/* ---------------------------------------------------------------
1923
* classDirectorMethod()
1925
* Emit a virtual director method to pass a method call on to the
1926
* underlying Ruby instance.
1928
* --------------------------------------------------------------- */
1930
void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args) {
1932
Wrapper *body = NewWrapper();
1933
Wrapper *rescue = NewWrapper();
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);
1940
// Check for an exception typemap of some kind
1941
String *tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
1943
tm = Getattr(n, "feature:director:except");
1946
if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0))
1948
// Declare a global to hold the depth count
1949
Printf(f_directors, "static int %s = 0;\n", depthCountName);
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);
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);
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);
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);
1982
Printv(w->code, "args.argv = 0;\n", NIL);
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);
1988
Printv(w->code, "delete [] args.argv;\n", NIL);
1991
// Dump wrapper code
1992
Wrapper_print(body, f_directors);
1993
Wrapper_print(rescue, f_directors);
1998
Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", methodName, argc, args);
2000
Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", methodName);
2007
Delete(depthCountName);
2012
virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
2019
String *declaration;
2024
String *return_type;
2026
String *value = Getattr(n, "value");
2027
String *storage = Getattr(n,"storage");
2028
bool pure_virtual = false;
2029
int status = SWIG_OK;
2032
if (Cmp(storage,"virtual") == 0) {
2033
if (Cmp(value,"0") == 0) {
2034
pure_virtual = true;
2038
classname = Getattr(parent, "sym:name");
2039
type = Getattr(n, "type");
2040
name = Getattr(n, "name");
2043
declaration = NewString("");
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);
2050
/* form complete return type */
2051
return_type = Copy(type);
2053
SwigType *t = Copy(decl);
2055
f = SwigType_pop_function(t);
2056
SwigType_push(return_type, t);
2061
/* virtual method definition */
2062
l = Getattr(n, "parms");
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);
2071
/* header declaration */
2072
target = Swig_method_decl(decl, name, l, 0, 1);
2073
Printf(declaration, " virtual %s %s;\n", rtype, target);
2076
/* attach typemaps to arguments (C/C++ -> Ruby) */
2077
String *arglist = NewString("");
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.
2086
typemap_copy_pname_to_lname(l);
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);
2093
int num_arguments = emit_num_arguments(l);
2097
wrap_args = NewString("");
2099
if (!is_void) outputs++;
2101
/* build argument list and type conversion string */
2102
for (i=0, idx=0, p = l; i < num_arguments; i++) {
2104
while (Getattr(p, "tmap:ignore")) {
2105
p = Getattr(p, "tmap:ignore:next");
2108
if (Getattr(p, "tmap:directorargout") != 0) outputs++;
2110
String* parameterName = Getattr(p, "name");
2111
String* parameterType = Getattr(p, "type");
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");
2123
} else if (Cmp(parameterType, "void")) {
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?
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,"&");
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);
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);
2155
nonconst = Copy(ppname);
2159
String *mangle = SwigType_manglestr(parameterType);
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");
2171
Printv(arglist, source, NIL);
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);
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;
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).
2197
Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
2199
/* declare Ruby return value */
2200
Wrapper_add_local(w, "result", "VALUE result");
2202
/* direct call to superclass if _up is set */
2203
Printf(w->code, "if (swig_get_up()) {\n");
2205
Printf(w->code, "throw Swig::DirectorPureVirtualException();\n");
2208
Printf(w->code, "%s;\n", Swig_method_call(super,l));
2209
Printf(w->code, "return;\n");
2211
Printf(w->code, "return %s;\n", Swig_method_call(super,l));
2214
Printf(w->code, "}\n");
2216
/* wrap complex arguments to VALUEs */
2217
Printv(w->code, wrap_args, NIL);
2219
/* pass the method call on to the Ruby object */
2220
exceptionSafeMethodCall(classname, n, w, idx, arglist);
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).
2228
/* Marshal return value and other outputs (if any) from VALUE to C/C++ type */
2230
String* cleanup = NewString("");
2231
String* outarg = NewString("");
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");
2242
/* Marshal return value */
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().
2249
Setattr(n, "type", return_type);
2250
tm = Swig_typemap_lookup_new("directorout", n, "result", w);
2251
Setattr(n, "type", type);
2253
String *name = NewString("result");
2254
tm = Swig_typemap_search("directorout", return_type, name, NULL);
2259
Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
2260
Replaceall(tm, "$input", "output");
2262
Replaceall(tm, "$input", "result");
2264
/* TODO check this */
2265
if (Getattr(n,"wrap:disown")) {
2266
Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
2268
Replaceall(tm,"$disown","0");
2270
Replaceall(tm, "$result", "c_result");
2271
Printv(w->code, tm, "\n", NIL);
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;
2279
/* Marshal outputs */
2281
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
2283
Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
2284
Replaceall(tm, "$input", "output");
2286
Replaceall(tm, "$input", "result");
2288
Replaceall(tm, "$result", Getattr(p, "name"));
2289
Printv(w->code, tm, "\n", NIL);
2290
p = Getattr(p, "tmap:directorargout:next");
2296
/* any existing helper functions to handle this? */
2298
if (!SwigType_isreference(return_type)) {
2299
Printf(w->code, "return c_result;\n");
2301
Printf(w->code, "return *c_result;\n");
2305
Printf(w->code, "}\n");
2307
/* emit the director method */
2308
if (status == SWIG_OK) {
2309
Wrapper_print(w, f_directors);
2310
Printv(f_directors_h, declaration, NIL);
2317
Delete(return_type);
2325
virtual int classDirectorConstructors(Node *n) {
2326
return Language::classDirectorConstructors(n);
2329
virtual int classDirectorMethods(Node *n) {
2330
return Language::classDirectorMethods(n);
2333
virtual int classDirectorDisown(Node *n) {
2334
return Language::classDirectorDisown(n);
2337
void typemap_copy_pname_to_lname(ParmList *parms)
2345
pname = Getattr(p,"name");
2346
lname = Copy(pname);
2347
Setattr(p,"lname",lname);
2353
/* -----------------------------------------------------------------------------
2354
* swig_ruby() - Instantiate module
2355
* ----------------------------------------------------------------------------- */
2357
extern "C" Language *