Initial changes for limited MI support in Ruby (still under construction!)
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4707 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
0805ba938d
commit
183be41892
2 changed files with 115 additions and 65 deletions
|
|
@ -71,7 +71,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
|
VALUE mImpl;
|
||||||
void (*mark)(void *);
|
void (*mark)(void *);
|
||||||
void (*destroy)(void *);
|
void (*destroy)(void *);
|
||||||
} swig_class;
|
} swig_class;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,23 @@ class RClass {
|
||||||
String *name; /* class name (renamed) */
|
String *name; /* class name (renamed) */
|
||||||
String *cname; /* original C class/struct name */
|
String *cname; /* original C class/struct name */
|
||||||
String *mname; /* Mangled name */
|
String *mname; /* Mangled name */
|
||||||
String *vname; /* variable name */
|
|
||||||
|
/**
|
||||||
|
* The C variable name used in the SWIG-generated wrapper code to refer to
|
||||||
|
* this class; usually it is of the form "cClassName.klass", where cClassName
|
||||||
|
* is a swig_class struct instance and klass is a member of that struct.
|
||||||
|
*/
|
||||||
|
String *vname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The C variable name used in the SWIG-generated wrapper code to refer to
|
||||||
|
* the module that implements this class's methods (when we're trying to
|
||||||
|
* support C++ multiple inheritance). Usually it is of the form
|
||||||
|
* "cClassName.mImpl", where cClassName is a swig_class struct instance
|
||||||
|
* and mImpl is a member of that struct.
|
||||||
|
*/
|
||||||
|
String *mImpl;
|
||||||
|
|
||||||
String *type;
|
String *type;
|
||||||
String *prefix;
|
String *prefix;
|
||||||
String *header;
|
String *header;
|
||||||
|
|
@ -44,6 +60,7 @@ class RClass {
|
||||||
cname = NewString("");
|
cname = NewString("");
|
||||||
mname = NewString("");
|
mname = NewString("");
|
||||||
vname = NewString("");
|
vname = NewString("");
|
||||||
|
mImpl = NewString("");
|
||||||
type = NewString("");
|
type = NewString("");
|
||||||
prefix = NewString("");
|
prefix = NewString("");
|
||||||
header = NewString("");
|
header = NewString("");
|
||||||
|
|
@ -56,6 +73,7 @@ class RClass {
|
||||||
Delete(name);
|
Delete(name);
|
||||||
Delete(cname);
|
Delete(cname);
|
||||||
Delete(vname);
|
Delete(vname);
|
||||||
|
Delete(mImpl);
|
||||||
Delete(mname);
|
Delete(mname);
|
||||||
Delete(type);
|
Delete(type);
|
||||||
Delete(prefix);
|
Delete(prefix);
|
||||||
|
|
@ -65,14 +83,27 @@ class RClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_name(const String_or_char *cn, const String_or_char *rn, const String_or_char *valn) {
|
void set_name(const String_or_char *cn, const String_or_char *rn, const String_or_char *valn) {
|
||||||
|
/* Original C/C++ class (or struct) name */
|
||||||
Clear(cname);
|
Clear(cname);
|
||||||
Append(cname,cn);
|
Append(cname,cn);
|
||||||
|
|
||||||
|
/* Mangled name */
|
||||||
Delete(mname);
|
Delete(mname);
|
||||||
mname = Swig_name_mangle(cname);
|
mname = Swig_name_mangle(cname);
|
||||||
|
|
||||||
|
/* Renamed class name */
|
||||||
Clear(name);
|
Clear(name);
|
||||||
Append(name,valn);
|
Append(name,valn);
|
||||||
|
|
||||||
|
/* Variable name for the VALUE that refers to the Ruby Class object */
|
||||||
Clear(vname);
|
Clear(vname);
|
||||||
Printf(vname,"c%s.klass",name);
|
Printf(vname, "c%s.klass", name);
|
||||||
|
|
||||||
|
/* Variable name for the VALUE that refers to the Ruby Class object */
|
||||||
|
Clear(mImpl);
|
||||||
|
Printf(mImpl, "c%s.mImpl", name);
|
||||||
|
|
||||||
|
/* Prefix */
|
||||||
Clear(prefix);
|
Clear(prefix);
|
||||||
Printv(prefix,(rn ? rn : cn), "_", NIL);
|
Printv(prefix,(rn ? rn : cn), "_", NIL);
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +124,7 @@ usage = "\
|
||||||
Ruby Options (available with -ruby)\n\
|
Ruby Options (available with -ruby)\n\
|
||||||
-ldflags - Print runtime libraries to link with\n\
|
-ldflags - Print runtime libraries to link with\n\
|
||||||
-globalmodule - Wrap everything into the global module\n\
|
-globalmodule - Wrap everything into the global module\n\
|
||||||
|
-minherit - Attempt to support multiple inheritance\n\
|
||||||
-feature name - Set feature name (used by `require')\n";
|
-feature name - Set feature name (used by `require')\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -116,6 +148,7 @@ private:
|
||||||
File *f_init;
|
File *f_init;
|
||||||
bool use_kw;
|
bool use_kw;
|
||||||
bool useGlobalModule;
|
bool useGlobalModule;
|
||||||
|
bool multipleInheritance;
|
||||||
|
|
||||||
// Wrap modes
|
// Wrap modes
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -152,6 +185,7 @@ public:
|
||||||
f_init = 0;
|
f_init = 0;
|
||||||
use_kw = false;
|
use_kw = false;
|
||||||
useGlobalModule = false;
|
useGlobalModule = false;
|
||||||
|
multipleInheritance = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
/* ---------------------------------------------------------------------
|
||||||
|
|
@ -181,6 +215,9 @@ public:
|
||||||
} else if (strcmp(argv[i],"-globalmodule") == 0) {
|
} else if (strcmp(argv[i],"-globalmodule") == 0) {
|
||||||
useGlobalModule = true;
|
useGlobalModule = true;
|
||||||
Swig_mark_arg(i);
|
Swig_mark_arg(i);
|
||||||
|
} else if (strcmp(argv[i],"-minherit") == 0) {
|
||||||
|
multipleInheritance = true;
|
||||||
|
Swig_mark_arg(i);
|
||||||
} else if (strcmp(argv[i],"-help") == 0) {
|
} else if (strcmp(argv[i],"-help") == 0) {
|
||||||
Printf(stderr,"%s\n", usage);
|
Printf(stderr,"%s\n", usage);
|
||||||
} else if (strcmp (argv[i],"-ldflags") == 0) {
|
} else if (strcmp (argv[i],"-ldflags") == 0) {
|
||||||
|
|
@ -471,8 +508,13 @@ public:
|
||||||
|
|
||||||
switch (current) {
|
switch (current) {
|
||||||
case MEMBER_FUNC:
|
case MEMBER_FUNC:
|
||||||
Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
|
if (multipleInheritance) {
|
||||||
iname, "\", ", wname, ", -1);\n", NIL);
|
Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"",
|
||||||
|
iname, "\", ", wname, ", -1);\n", NIL);
|
||||||
|
} else {
|
||||||
|
Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
|
||||||
|
iname, "\", ", wname, ", -1);\n", NIL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CONSTRUCTOR_ALLOCATE:
|
case CONSTRUCTOR_ALLOCATE:
|
||||||
Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL);
|
Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL);
|
||||||
|
|
@ -487,8 +529,13 @@ public:
|
||||||
Append(temp,iname);
|
Append(temp,iname);
|
||||||
Replaceall(temp,"_set", "=");
|
Replaceall(temp,"_set", "=");
|
||||||
Replaceall(temp,"_get", "");
|
Replaceall(temp,"_get", "");
|
||||||
Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
|
if (multipleInheritance) {
|
||||||
temp, "\", ", wname, ", -1);\n", NIL);
|
Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"",
|
||||||
|
temp, "\", ", wname, ", -1);\n", NIL);
|
||||||
|
} else {
|
||||||
|
Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
|
||||||
|
temp, "\", ", wname, ", -1);\n", NIL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case STATIC_FUNC:
|
case STATIC_FUNC:
|
||||||
Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname,
|
Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname,
|
||||||
|
|
@ -1160,8 +1207,13 @@ public:
|
||||||
Replaceall(tm, "$symname", iname);
|
Replaceall(tm, "$symname", iname);
|
||||||
Replaceall(tm, "$value", value);
|
Replaceall(tm, "$value", value);
|
||||||
if (current == CLASS_CONST) {
|
if (current == CLASS_CONST) {
|
||||||
Replaceall(tm, "$module", klass->vname);
|
if (multipleInheritance) {
|
||||||
Printv(klass->init, tm, "\n", NIL);
|
Replaceall(tm, "$module", klass->vname);
|
||||||
|
Printv(klass->init, tm, "\n", NIL);
|
||||||
|
} else {
|
||||||
|
Replaceall(tm, "$module", klass->mImpl);
|
||||||
|
Printv(klass->init, tm, "\n", NIL);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!useGlobalModule) {
|
if (!useGlobalModule) {
|
||||||
Replaceall(tm, "$module", modvar);
|
Replaceall(tm, "$module", modvar);
|
||||||
|
|
@ -1229,29 +1281,40 @@ public:
|
||||||
List *baselist = Getattr(n,"bases");
|
List *baselist = Getattr(n,"bases");
|
||||||
if (baselist && Len(baselist)) {
|
if (baselist && Len(baselist)) {
|
||||||
Node *base = Firstitem(baselist);
|
Node *base = Firstitem(baselist);
|
||||||
String *basename = Getattr(base,"name");
|
|
||||||
String *basenamestr = SwigType_namestr(basename);
|
|
||||||
RClass *super = RCLASS(classes, Char(basenamestr));
|
|
||||||
Delete(basenamestr);
|
|
||||||
if (super) {
|
|
||||||
SwigType *btype = NewString(basename);
|
|
||||||
SwigType_add_pointer(btype);
|
|
||||||
SwigType_remember(btype);
|
|
||||||
String *bmangle = SwigType_manglestr(btype);
|
|
||||||
Insert(bmangle,0,"((swig_class *) SWIGTYPE");
|
|
||||||
Append(bmangle,"->clientdata)->klass");
|
|
||||||
Replaceall(klass->init,"$super",bmangle);
|
|
||||||
Delete(bmangle);
|
|
||||||
Delete(btype);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Warn about multiple inheritance if additional base class(es) listed */
|
|
||||||
base = Nextitem(baselist);
|
|
||||||
while (base) {
|
while (base) {
|
||||||
basename = Getattr(n,"name");
|
String *basename = Getattr(base,"name");
|
||||||
Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number,
|
String *basenamestr = SwigType_namestr(basename);
|
||||||
"Warning for %s: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", basename, basename);
|
RClass *super = RCLASS(classes, Char(basenamestr));
|
||||||
base = Nextitem(baselist);
|
Delete(basenamestr);
|
||||||
|
if (super) {
|
||||||
|
SwigType *btype = NewString(basename);
|
||||||
|
SwigType_add_pointer(btype);
|
||||||
|
SwigType_remember(btype);
|
||||||
|
if (multipleInheritance) {
|
||||||
|
String *bmangle = SwigType_manglestr(btype);
|
||||||
|
Insert(bmangle,0,"((swig_class *) SWIGTYPE");
|
||||||
|
Append(bmangle,"->clientdata)->mImpl");
|
||||||
|
Printv(klass->init, "rb_include_module(", klass->mImpl, ", ", bmangle, ");\n", NIL);
|
||||||
|
Delete(bmangle);
|
||||||
|
} else {
|
||||||
|
String *bmangle = SwigType_manglestr(btype);
|
||||||
|
Insert(bmangle,0,"((swig_class *) SWIGTYPE");
|
||||||
|
Append(bmangle,"->clientdata)->klass");
|
||||||
|
Replaceall(klass->init,"$super",bmangle);
|
||||||
|
Delete(bmangle);
|
||||||
|
}
|
||||||
|
Delete(btype);
|
||||||
|
}
|
||||||
|
base = Nextitem(baselist);
|
||||||
|
if (!multipleInheritance) {
|
||||||
|
/* Warn about multiple inheritance for additional base class(es) listed */
|
||||||
|
while (base) {
|
||||||
|
basename = Getattr(n,"name");
|
||||||
|
Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number,
|
||||||
|
"Warning for %s: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", basename, basename);
|
||||||
|
base = Nextitem(baselist);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1283,33 +1346,6 @@ public:
|
||||||
Replaceall(klass->header,"$freeproto", "");
|
Replaceall(klass->header,"$freeproto", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void baseClassHandler(Node *n) {
|
|
||||||
Node *c;
|
|
||||||
for (c = firstChild(n); c; c = nextSibling(c)) {
|
|
||||||
char *tag = Char(nodeType(c));
|
|
||||||
if (!tag) {
|
|
||||||
Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree node!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// emit_one(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void copyBaseClassMembers(Node *n) {
|
|
||||||
List *baselist = Getattr(n,"bases");
|
|
||||||
if (baselist && Len(baselist) > 0) {
|
|
||||||
/* Skip the first base class */
|
|
||||||
Node *base = Firstitem(baselist);
|
|
||||||
|
|
||||||
/* Loop over remaining base classes */
|
|
||||||
base = Nextitem(baselist);
|
|
||||||
while (base) {
|
|
||||||
baseClassHandler(base);
|
|
||||||
base = Nextitem(baselist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* classHandler()
|
* classHandler()
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
@ -1330,12 +1366,23 @@ public:
|
||||||
Printv(klass->type, Getattr(n,"classtype"), NIL);
|
Printv(klass->type, Getattr(n,"classtype"), NIL);
|
||||||
Printv(klass->header, "\nswig_class c", valid_name, ";\n", NIL);
|
Printv(klass->header, "\nswig_class c", valid_name, ";\n", NIL);
|
||||||
Printv(klass->init, "\n", tab4, NIL);
|
Printv(klass->init, "\n", tab4, NIL);
|
||||||
if (!useGlobalModule) {
|
if (multipleInheritance) {
|
||||||
Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
|
if (!useGlobalModule) {
|
||||||
", \"", klass->name, "\", $super);\n", NIL);
|
Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
|
||||||
|
", \"", klass->name, "\", rb_cObject);\n", NIL);
|
||||||
|
} else {
|
||||||
|
Printv(klass->init, klass->vname, " = rb_define_class(\"",
|
||||||
|
klass->name, "\", rb_cObject);\n", NIL);
|
||||||
|
}
|
||||||
|
Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\n", NIL);
|
||||||
} else {
|
} else {
|
||||||
Printv(klass->init, klass->vname, " = rb_define_class(\"",
|
if (!useGlobalModule) {
|
||||||
klass->name, "\", $super);\n", NIL);
|
Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
|
||||||
|
", \"", klass->name, "\", $super);\n", NIL);
|
||||||
|
} else {
|
||||||
|
Printv(klass->init, klass->vname, " = rb_define_class(\"",
|
||||||
|
klass->name, "\", $super);\n", NIL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SwigType *tt = NewString(name);
|
SwigType *tt = NewString(name);
|
||||||
|
|
@ -1356,14 +1403,16 @@ public:
|
||||||
"$freeproto",
|
"$freeproto",
|
||||||
NIL);
|
NIL);
|
||||||
|
|
||||||
copyBaseClassMembers(n);
|
|
||||||
|
|
||||||
Language::classHandler(n);
|
Language::classHandler(n);
|
||||||
|
|
||||||
handleBaseClasses(n);
|
handleBaseClasses(n);
|
||||||
handleMarkFuncDirective(n);
|
handleMarkFuncDirective(n);
|
||||||
handleFreeFuncDirective(n);
|
handleFreeFuncDirective(n);
|
||||||
|
|
||||||
|
if (multipleInheritance) {
|
||||||
|
Printv(klass->init, "rb_include_module(", klass->vname, ", ", klass->mImpl, ");\n", NIL);
|
||||||
|
}
|
||||||
|
|
||||||
Printv(f_header, klass->header,NIL);
|
Printv(f_header, klass->header,NIL);
|
||||||
|
|
||||||
String *s = NewString("");
|
String *s = NewString("");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue