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:
Marcelo Matus 2003-12-07 23:00:02 +00:00
commit bbde8dafa9
8 changed files with 88 additions and 34 deletions

View file

@ -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 \

View file

@ -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;
};
%}

View file

@ -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"

View file

@ -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");

View file

@ -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;

View file

@ -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);

View file

@ -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 {

View file

@ -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__