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 += \
|
||||
array_typedef_memberin \
|
||||
defvalue_constructor \
|
||||
director_nested \
|
||||
director_protected \
|
||||
exception_order \
|
||||
namespace_union \
|
||||
smart_pointer_namespace2 \
|
||||
|
|
@ -116,6 +114,8 @@ CPP_TEST_CASES += \
|
|||
director_finalizer \
|
||||
director_unroll \
|
||||
director_wombat \
|
||||
director_nested \
|
||||
director_protected \
|
||||
dynamic_cast \
|
||||
enum_plus \
|
||||
enum_scope \
|
||||
|
|
|
|||
|
|
@ -47,14 +47,14 @@
|
|||
}
|
||||
|
||||
|
||||
virtual std::string do_step() = 0;
|
||||
virtual std::string do_step() const = 0;
|
||||
};
|
||||
|
||||
template <class C>
|
||||
class FooBar : public Bar
|
||||
{
|
||||
public:
|
||||
virtual C get_value() = 0;
|
||||
virtual C get_value() const = 0;
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,20 +35,20 @@ try:
|
|||
except:
|
||||
raise RuntimeError," bad FooBar::pong"
|
||||
|
||||
private=1
|
||||
protected=1
|
||||
try:
|
||||
b.ping()
|
||||
private=0
|
||||
protected=0
|
||||
except:
|
||||
pass
|
||||
if not private:
|
||||
raise RuntimeError,"Boo::ping is private"
|
||||
if not protected:
|
||||
raise RuntimeError,"Boo::ping is protected"
|
||||
|
||||
private=1
|
||||
protected=1
|
||||
try:
|
||||
f.ping()
|
||||
private=0
|
||||
protected=0
|
||||
except:
|
||||
pass
|
||||
if not private:
|
||||
raise RuntimeError,"Foo::ping is private"
|
||||
if not protected:
|
||||
raise RuntimeError,"Foo::ping is protected"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swigmod.h"
|
||||
#include "utils.h"
|
||||
|
||||
char cvsroot_emit_cxx[] = "$Header$";
|
||||
|
||||
|
|
@ -366,6 +367,27 @@ void emit_action(Node *n, Wrapper *f) {
|
|||
action = Getattr(n,"wrap:action");
|
||||
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 */
|
||||
|
||||
rt = Getattr(n,"type");
|
||||
|
|
|
|||
|
|
@ -697,8 +697,11 @@ int Language::cDeclaration(Node *n) {
|
|||
File *f_header = 0;
|
||||
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) {
|
||||
Swig_save("cDeclaration",n,"type",NIL);
|
||||
SwigType *t = Copy(type);
|
||||
|
|
@ -1712,7 +1715,36 @@ int Language::classHandler(Node *n) {
|
|||
|
||||
/* emit director disown method */
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ static char *usage = (char*)"\
|
|||
-module <name> - Set module name to <name>\n\
|
||||
-nocontract - Turn off contract checking \n\
|
||||
-nodefault - Do not generate constructors/destructors\n\
|
||||
-nodirprot - Do not wrap director protected members\n\
|
||||
-noexcept - Do not wrap exception specifiers\n\
|
||||
-noextern - Do not generate extern declarations\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_debug_templates(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_contract_mode_set(int flag);
|
||||
|
|
@ -280,6 +281,10 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
Swig_contract_mode_set(1);
|
||||
Preprocessor_define(vers,0);
|
||||
|
||||
/* Turn on director protected mode */
|
||||
Wrapper_director_protected_mode_set(1);
|
||||
|
||||
|
||||
// Check for SWIG_LIB environment variable
|
||||
|
||||
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);
|
||||
} else if (strcmp(temp, "-fvirtual") == 0) {
|
||||
Wrapper_virtual_elimination_mode_set(1);
|
||||
} else if (strcmp(temp,"-nodirprot") == 0) {
|
||||
Wrapper_director_protected_mode_set(0);
|
||||
} else if (strcmp(temp, "-small") == 0) {
|
||||
Wrapper_compact_print_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) {
|
||||
Wrapper_virtual_elimination_mode_set(1);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-nodirprot") == 0) {
|
||||
Wrapper_director_protected_mode_set(0);
|
||||
} else if (strcmp(argv[i],"-small") == 0) {
|
||||
Wrapper_compact_print_mode_set(1);
|
||||
Wrapper_virtual_elimination_mode_set(1);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
char cvsroot_python_cxx[] = "$Header$";
|
||||
|
||||
#include "swigmod.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifndef MACSWIG
|
||||
#include "swigconfig.h"
|
||||
|
|
@ -67,11 +66,8 @@ Python Options (available with -python)\n\
|
|||
-apply - Use apply() in proxy classes\n\
|
||||
-new_repr - Use more informative version of __repr__ in proxy classes\n\
|
||||
-noexcept - No automatic exception handling\n\
|
||||
-nodirprot - Don't wrap director protected members\n\
|
||||
-noproxy - Don't generate proxy classes \n\n";
|
||||
|
||||
extern void Wrapper_director_protected_mode_set(int);
|
||||
|
||||
class PYTHON : public Language {
|
||||
public:
|
||||
|
||||
|
|
@ -83,8 +79,6 @@ public:
|
|||
|
||||
SWIG_library_directory("python");
|
||||
|
||||
Wrapper_director_protected_mode_set(1);
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i]) {
|
||||
if(strcmp(argv[i],"-interface") == 0) {
|
||||
|
|
@ -128,8 +122,6 @@ public:
|
|||
classic = 0;
|
||||
modern = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-nodirprot") == 0) {
|
||||
Wrapper_director_protected_mode_set(0);
|
||||
} else if (strcmp(argv[i],"-help") == 0) {
|
||||
fputs(usage,stderr);
|
||||
} else if (strcmp (argv[i], "-ldflags") == 0) {
|
||||
|
|
@ -1313,13 +1305,7 @@ public:
|
|||
Wrapper_add_local(w, "result", "PyObject *result");
|
||||
|
||||
/* direct call to superclass if _up is set */
|
||||
if (is_protected(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");
|
||||
}
|
||||
Printf(w->code, "if (swig_get_up()) {\n");
|
||||
if (pure_virtual) {
|
||||
Printf(w->code, "throw Swig::DirectorPureVirtualException();\n");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -24,12 +24,17 @@ int is_protected(Node* n)
|
|||
}
|
||||
|
||||
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");
|
||||
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__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue