Moving the director protected member support to the top level. Now it should works in all the languages. Test it.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5498 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
825058f7e5
commit
bbde8dafa9
8 changed files with 88 additions and 34 deletions
|
|
@ -47,8 +47,6 @@ DYNAMIC_LIB_PATH = $(RUNTIMEDIR):.
|
||||||
CPP_TEST_BROKEN += \
|
CPP_TEST_BROKEN += \
|
||||||
array_typedef_memberin \
|
array_typedef_memberin \
|
||||||
defvalue_constructor \
|
defvalue_constructor \
|
||||||
director_nested \
|
|
||||||
director_protected \
|
|
||||||
exception_order \
|
exception_order \
|
||||||
namespace_union \
|
namespace_union \
|
||||||
smart_pointer_namespace2 \
|
smart_pointer_namespace2 \
|
||||||
|
|
@ -116,6 +114,8 @@ CPP_TEST_CASES += \
|
||||||
director_finalizer \
|
director_finalizer \
|
||||||
director_unroll \
|
director_unroll \
|
||||||
director_wombat \
|
director_wombat \
|
||||||
|
director_nested \
|
||||||
|
director_protected \
|
||||||
dynamic_cast \
|
dynamic_cast \
|
||||||
enum_plus \
|
enum_plus \
|
||||||
enum_scope \
|
enum_scope \
|
||||||
|
|
|
||||||
|
|
@ -47,14 +47,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual std::string do_step() = 0;
|
virtual std::string do_step() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class C>
|
template <class C>
|
||||||
class FooBar : public Bar
|
class FooBar : public Bar
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual C get_value() = 0;
|
virtual C get_value() const = 0;
|
||||||
};
|
};
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,20 +35,20 @@ try:
|
||||||
except:
|
except:
|
||||||
raise RuntimeError," bad FooBar::pong"
|
raise RuntimeError," bad FooBar::pong"
|
||||||
|
|
||||||
private=1
|
protected=1
|
||||||
try:
|
try:
|
||||||
b.ping()
|
b.ping()
|
||||||
private=0
|
protected=0
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not private:
|
if not protected:
|
||||||
raise RuntimeError,"Boo::ping is private"
|
raise RuntimeError,"Boo::ping is protected"
|
||||||
|
|
||||||
private=1
|
protected=1
|
||||||
try:
|
try:
|
||||||
f.ping()
|
f.ping()
|
||||||
private=0
|
protected=0
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not private:
|
if not protected:
|
||||||
raise RuntimeError,"Foo::ping is private"
|
raise RuntimeError,"Foo::ping is protected"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "swigmod.h"
|
#include "swigmod.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
char cvsroot_emit_cxx[] = "$Header$";
|
char cvsroot_emit_cxx[] = "$Header$";
|
||||||
|
|
||||||
|
|
@ -366,6 +367,27 @@ void emit_action(Node *n, Wrapper *f) {
|
||||||
action = Getattr(n,"wrap:action");
|
action = Getattr(n,"wrap:action");
|
||||||
assert(action != 0);
|
assert(action != 0);
|
||||||
|
|
||||||
|
if (is_protected(n) && is_member_director(n)) {
|
||||||
|
/* We need to add an extra dynamic_cast to
|
||||||
|
access the director class, where the virtual
|
||||||
|
methods are all public */
|
||||||
|
Node* parent = Getattr(n,"parentNode");
|
||||||
|
String* symname = Getattr(parent, "sym:name");
|
||||||
|
String* classtype = Getattr(parent,"classtype");
|
||||||
|
String* dirname = NewStringf("SwigDirector_%s", symname);
|
||||||
|
String* dirdecl = NewStringf("%s *darg1 = 0", dirname);
|
||||||
|
Wrapper_add_local(f, "darg1", dirdecl);
|
||||||
|
Printf(f->code, "darg1 = dynamic_cast<%s *>(arg1);\n",dirname);
|
||||||
|
/* Maybe here a more detailed diagnostic can de added,
|
||||||
|
such as trying to access a protected member, but it seems
|
||||||
|
it is not easy to do it for all the languages at once*/
|
||||||
|
Printf(f->code, "if (!darg1) return NULL;\n");
|
||||||
|
Replaceall(action,"arg1","darg1");
|
||||||
|
Replaceall(action,classtype,dirname);
|
||||||
|
Delete(dirname);
|
||||||
|
Delete(dirdecl);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the return type */
|
/* Get the return type */
|
||||||
|
|
||||||
rt = Getattr(n,"type");
|
rt = Getattr(n,"type");
|
||||||
|
|
|
||||||
|
|
@ -697,8 +697,11 @@ int Language::cDeclaration(Node *n) {
|
||||||
File *f_header = 0;
|
File *f_header = 0;
|
||||||
SwigType *ty, *fullty;
|
SwigType *ty, *fullty;
|
||||||
|
|
||||||
if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP;
|
|
||||||
|
if (CurrentClass && (cplus_mode == CPLUS_PRIVATE)) return SWIG_NOWRAP;
|
||||||
|
if ((cplus_mode == CPLUS_PROTECTED) &&
|
||||||
|
(!director_protected_mode || !is_member_director(CurrentClass,n))) return SWIG_NOWRAP;
|
||||||
|
|
||||||
if (Cmp(storage,"typedef") == 0) {
|
if (Cmp(storage,"typedef") == 0) {
|
||||||
Swig_save("cDeclaration",n,"type",NIL);
|
Swig_save("cDeclaration",n,"type",NIL);
|
||||||
SwigType *t = Copy(type);
|
SwigType *t = Copy(type);
|
||||||
|
|
@ -1712,7 +1715,36 @@ int Language::classHandler(Node *n) {
|
||||||
|
|
||||||
/* emit director disown method */
|
/* emit director disown method */
|
||||||
if (hasDirector) {
|
if (hasDirector) {
|
||||||
classDirectorDisown(n);
|
classDirectorDisown(n);
|
||||||
|
|
||||||
|
/* emit all the protected virtual members as needed */
|
||||||
|
Node *vtable = Getattr(n, "vtable");
|
||||||
|
String* symname = Getattr(n, "sym:name");
|
||||||
|
Node *item;
|
||||||
|
Iterator k;
|
||||||
|
int old_mode = cplus_mode;
|
||||||
|
cplus_mode = CPLUS_PROTECTED;
|
||||||
|
for (k = First(vtable); k.key; k = Next(k)) {
|
||||||
|
item = k.item;
|
||||||
|
String* director = Getattr(item,"director");
|
||||||
|
Node *method = Getattr(item, "methodNode");
|
||||||
|
Node* parentnode = Getattr(method, "parentNode");
|
||||||
|
String* methodname = Getattr(method,"sym:name");
|
||||||
|
String* wrapname = NewStringf("%s_%s", symname,methodname);
|
||||||
|
if (!Getattr(symbols,wrapname)
|
||||||
|
&& !Cmp(director,"1")
|
||||||
|
&& (n != parentnode)
|
||||||
|
&& is_protected(method)) {
|
||||||
|
Node* m = Copy(method);
|
||||||
|
Setattr(m,"parentNode", n);
|
||||||
|
/* ugly trick, to avoid an uglier one later on emit.*/
|
||||||
|
Replace(Getattr(m,"decl"),"q(const).","",1);
|
||||||
|
cDeclaration(m);
|
||||||
|
Delete(m);
|
||||||
|
}
|
||||||
|
Delete(wrapname);
|
||||||
|
}
|
||||||
|
cplus_mode = old_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ static char *usage = (char*)"\
|
||||||
-module <name> - Set module name to <name>\n\
|
-module <name> - Set module name to <name>\n\
|
||||||
-nocontract - Turn off contract checking \n\
|
-nocontract - Turn off contract checking \n\
|
||||||
-nodefault - Do not generate constructors/destructors\n\
|
-nodefault - Do not generate constructors/destructors\n\
|
||||||
|
-nodirprot - Do not wrap director protected members\n\
|
||||||
-noexcept - Do not wrap exception specifiers\n\
|
-noexcept - Do not wrap exception specifiers\n\
|
||||||
-noextern - Do not generate extern declarations\n\
|
-noextern - Do not generate extern declarations\n\
|
||||||
-noruntime - Do not include SWIG runtime code\n\
|
-noruntime - Do not include SWIG runtime code\n\
|
||||||
|
|
@ -201,7 +202,7 @@ extern "C" Node *Swig_cparse(File *);
|
||||||
extern "C" void Swig_cparse_cplusplus(int);
|
extern "C" void Swig_cparse_cplusplus(int);
|
||||||
extern "C" void Swig_cparse_debug_templates(int);
|
extern "C" void Swig_cparse_debug_templates(int);
|
||||||
extern void Wrapper_virtual_elimination_mode_set(int);
|
extern void Wrapper_virtual_elimination_mode_set(int);
|
||||||
|
extern void Wrapper_director_protected_mode_set(int);
|
||||||
|
|
||||||
extern void Swig_contracts(Node *n);
|
extern void Swig_contracts(Node *n);
|
||||||
extern void Swig_contract_mode_set(int flag);
|
extern void Swig_contract_mode_set(int flag);
|
||||||
|
|
@ -280,6 +281,10 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
||||||
Swig_contract_mode_set(1);
|
Swig_contract_mode_set(1);
|
||||||
Preprocessor_define(vers,0);
|
Preprocessor_define(vers,0);
|
||||||
|
|
||||||
|
/* Turn on director protected mode */
|
||||||
|
Wrapper_director_protected_mode_set(1);
|
||||||
|
|
||||||
|
|
||||||
// Check for SWIG_LIB environment variable
|
// Check for SWIG_LIB environment variable
|
||||||
|
|
||||||
if ((c = getenv("SWIG_LIB")) == (char *) 0) {
|
if ((c = getenv("SWIG_LIB")) == (char *) 0) {
|
||||||
|
|
@ -322,6 +327,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
||||||
Wrapper_compact_print_mode_set(1);
|
Wrapper_compact_print_mode_set(1);
|
||||||
} else if (strcmp(temp, "-fvirtual") == 0) {
|
} else if (strcmp(temp, "-fvirtual") == 0) {
|
||||||
Wrapper_virtual_elimination_mode_set(1);
|
Wrapper_virtual_elimination_mode_set(1);
|
||||||
|
} else if (strcmp(temp,"-nodirprot") == 0) {
|
||||||
|
Wrapper_director_protected_mode_set(0);
|
||||||
} else if (strcmp(temp, "-small") == 0) {
|
} else if (strcmp(temp, "-small") == 0) {
|
||||||
Wrapper_compact_print_mode_set(1);
|
Wrapper_compact_print_mode_set(1);
|
||||||
Wrapper_virtual_elimination_mode_set(1);
|
Wrapper_virtual_elimination_mode_set(1);
|
||||||
|
|
@ -360,6 +367,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
||||||
} else if (strcmp(argv[i],"-fvirtual") == 0) {
|
} else if (strcmp(argv[i],"-fvirtual") == 0) {
|
||||||
Wrapper_virtual_elimination_mode_set(1);
|
Wrapper_virtual_elimination_mode_set(1);
|
||||||
Swig_mark_arg(i);
|
Swig_mark_arg(i);
|
||||||
|
} else if (strcmp(argv[i],"-nodirprot") == 0) {
|
||||||
|
Wrapper_director_protected_mode_set(0);
|
||||||
} else if (strcmp(argv[i],"-small") == 0) {
|
} else if (strcmp(argv[i],"-small") == 0) {
|
||||||
Wrapper_compact_print_mode_set(1);
|
Wrapper_compact_print_mode_set(1);
|
||||||
Wrapper_virtual_elimination_mode_set(1);
|
Wrapper_virtual_elimination_mode_set(1);
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
char cvsroot_python_cxx[] = "$Header$";
|
char cvsroot_python_cxx[] = "$Header$";
|
||||||
|
|
||||||
#include "swigmod.h"
|
#include "swigmod.h"
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#ifndef MACSWIG
|
#ifndef MACSWIG
|
||||||
#include "swigconfig.h"
|
#include "swigconfig.h"
|
||||||
|
|
@ -67,11 +66,8 @@ Python Options (available with -python)\n\
|
||||||
-apply - Use apply() in proxy classes\n\
|
-apply - Use apply() in proxy classes\n\
|
||||||
-new_repr - Use more informative version of __repr__ in proxy classes\n\
|
-new_repr - Use more informative version of __repr__ in proxy classes\n\
|
||||||
-noexcept - No automatic exception handling\n\
|
-noexcept - No automatic exception handling\n\
|
||||||
-nodirprot - Don't wrap director protected members\n\
|
|
||||||
-noproxy - Don't generate proxy classes \n\n";
|
-noproxy - Don't generate proxy classes \n\n";
|
||||||
|
|
||||||
extern void Wrapper_director_protected_mode_set(int);
|
|
||||||
|
|
||||||
class PYTHON : public Language {
|
class PYTHON : public Language {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -83,8 +79,6 @@ public:
|
||||||
|
|
||||||
SWIG_library_directory("python");
|
SWIG_library_directory("python");
|
||||||
|
|
||||||
Wrapper_director_protected_mode_set(1);
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (argv[i]) {
|
if (argv[i]) {
|
||||||
if(strcmp(argv[i],"-interface") == 0) {
|
if(strcmp(argv[i],"-interface") == 0) {
|
||||||
|
|
@ -128,8 +122,6 @@ public:
|
||||||
classic = 0;
|
classic = 0;
|
||||||
modern = 1;
|
modern = 1;
|
||||||
Swig_mark_arg(i);
|
Swig_mark_arg(i);
|
||||||
} else if (strcmp(argv[i],"-nodirprot") == 0) {
|
|
||||||
Wrapper_director_protected_mode_set(0);
|
|
||||||
} else if (strcmp(argv[i],"-help") == 0) {
|
} else if (strcmp(argv[i],"-help") == 0) {
|
||||||
fputs(usage,stderr);
|
fputs(usage,stderr);
|
||||||
} else if (strcmp (argv[i], "-ldflags") == 0) {
|
} else if (strcmp (argv[i], "-ldflags") == 0) {
|
||||||
|
|
@ -1313,13 +1305,7 @@ public:
|
||||||
Wrapper_add_local(w, "result", "PyObject *result");
|
Wrapper_add_local(w, "result", "PyObject *result");
|
||||||
|
|
||||||
/* direct call to superclass if _up is set */
|
/* direct call to superclass if _up is set */
|
||||||
if (is_protected(n)) {
|
Printf(w->code, "if (swig_get_up()) {\n");
|
||||||
Printf(w->code, "PyObject *obj = PyObject_GetAttrString(swig_get_self(), \"%s\");\n",
|
|
||||||
Getattr(n,"sym:name"));
|
|
||||||
Printf(w->code, "if (!obj) {\n");
|
|
||||||
} else {
|
|
||||||
Printf(w->code, "if (swig_get_up()) {\n");
|
|
||||||
}
|
|
||||||
if (pure_virtual) {
|
if (pure_virtual) {
|
||||||
Printf(w->code, "throw Swig::DirectorPureVirtualException();\n");
|
Printf(w->code, "throw Swig::DirectorPureVirtualException();\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,17 @@ int is_protected(Node* n)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
int is_member_director(Node* classnode, Node* member)
|
int is_member_director(Node* parentnode, Node* member)
|
||||||
{
|
{
|
||||||
int class_director = !Cmp(Getattr(classnode,"feature:director"), "1");
|
int parent_director = !Cmp(Getattr(parentnode,"feature:director"), "1");
|
||||||
int cdecl_nodirector = !Cmp(Getattr(member,"feature:nodirector"),"1");
|
int cdecl_nodirector = !Cmp(Getattr(member,"feature:nodirector"),"1");
|
||||||
return class_director && !cdecl_nodirector;
|
return parent_director && !cdecl_nodirector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
int is_member_director(Node* member)
|
||||||
|
{
|
||||||
|
return is_member_director(Getattr(member, "parentNode"), member);
|
||||||
|
}
|
||||||
|
|
||||||
#endif //__Modules_utils_h__
|
#endif //__Modules_utils_h__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue