From a275bbd30f25fe852f7a2e117b25ecb7c8d78dfd Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Tue, 27 Dec 2005 21:48:56 +0000 Subject: [PATCH] add the 'naturalvar' option/mode/feature, to allow member variables to be treated in a natural way, as the global ones. This mean use the const SWIGTYPE &(C++)/SWIGTYPE(C) typemaps instead of the plain SWIGTYPE * typemap for the set/get methods. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8089 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/common.mk | 2 + Examples/test-suite/naturalvar.i | 38 ++++++++++++ .../test-suite/python/naturalvar_runme.py | 12 ++++ Source/Modules/lang.cxx | 30 +++++++++- Source/Modules/main.cxx | 6 ++ Source/Modules/swigmod.h | 2 + Source/Swig/cwrap.c | 59 ++++++++++++++----- Source/Swig/swig.h | 2 +- 8 files changed, 134 insertions(+), 17 deletions(-) create mode 100644 Examples/test-suite/naturalvar.i create mode 100644 Examples/test-suite/python/naturalvar_runme.py diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 15c2e2c50..026737649 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -181,6 +181,7 @@ CPP_TEST_CASES += \ namespace_typedef_class \ namespace_typemap \ namespace_virtual_method \ + naturalvar \ newobject1 \ ordering \ operator_overload \ @@ -329,6 +330,7 @@ CPP_STD_TEST_CASES += \ li_std_pair \ li_std_string \ li_std_vector \ + naturalvar \ template_typedef_fnc \ template_type_namespace \ template_opaque diff --git a/Examples/test-suite/naturalvar.i b/Examples/test-suite/naturalvar.i new file mode 100644 index 000000000..85cb40c13 --- /dev/null +++ b/Examples/test-suite/naturalvar.i @@ -0,0 +1,38 @@ +%module(naturalvar) naturalvar + +#ifdef __cplusplus +%include std_string.i +%inline +{ + struct Foo + { + }; + + + std::string s; + struct Bar + { + int i; + Foo f; + std::string s; + }; +} +#else +%inline +{ + typedef struct _foo + { + }Foo; + + + char *s; + typedef struct _bar + { + int i; + Foo f; + char *s; + } Bar; +} +#endif + + diff --git a/Examples/test-suite/python/naturalvar_runme.py b/Examples/test-suite/python/naturalvar_runme.py new file mode 100644 index 000000000..a0481ec60 --- /dev/null +++ b/Examples/test-suite/python/naturalvar_runme.py @@ -0,0 +1,12 @@ +from naturalvar import * + +f = Foo() +b = Bar() + +b.f = f + +cvar.s = "hello" +b.s = "hello" + +if b.s != cvar.s: + raise RuntimeError diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 5dd5f07a9..6d9c338cd 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -20,6 +20,7 @@ char cvsroot_lang_cxx[] = "$Header$"; static int director_mode = 0; /* set to 0 on default */ static int director_protected_mode = 0; /* set to 0 on default */ +static int naturalvar_mode = 0; /* Set director_protected_mode */ void Wrapper_director_mode_set(int flag) { @@ -30,6 +31,10 @@ void Wrapper_director_protected_mode_set(int flag) { director_protected_mode = flag; } +void Wrapper_naturalvar_mode_set(int flag) { + naturalvar_mode = flag; +} + extern "C" { int Swig_director_mode() { @@ -377,6 +382,18 @@ void swig_pragma(char *lang, char *name, char *value) { * ---------------------------------------------------------------------- */ int Language::top(Node *n) { + Node *mod = Getattr(n, "module"); + if (mod) { + Node *options = Getattr(mod, "options"); + if (options) { + if (Getattr(options, "naturalvar")) { + naturalvar_mode = 1; + } + if (Getattr(options, "nonaturalvar")) { + naturalvar_mode = 0; + } + } + } return emit_children(n); } @@ -1251,7 +1268,11 @@ Language::membervariableHandler(Node *n) { tm = Swig_typemap_lookup_new("memberin",n,target,0); } int flags = Extend | SmartPointer; - //if (CPlusPlus) flags |= CWRAP_VAR_REFERENCE; + + if (naturalvar_mode || GetFlag(n,"feature:naturalvar")) { + flags |= CWRAP_NATURAL_VAR; + } + Swig_MembersetToFunction(n,ClassType, flags); if (!Extend) { /* Check for a member in typemap here */ @@ -1296,7 +1317,12 @@ Language::membervariableHandler(Node *n) { } /* Emit get function */ { - Swig_MembergetToFunction(n,ClassType, Extend | SmartPointer); + int flags = Extend | SmartPointer; + if (naturalvar_mode || GetFlag(n,"feature:naturalvar")) { + flags |= CWRAP_NATURAL_VAR; + } + + Swig_MembergetToFunction(n,ClassType, flags); Setattr(n,"sym:name", mrename_get); functionWrapper(n); } diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 2f9bb8e33..2275f35c1 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -411,6 +411,12 @@ void SWIG_getoptions(int argc, char *argv[]) } else if (strcmp(argv[i],"-nofastdispatch") == 0) { Wrapper_fast_dispatch_mode_set(0); Swig_mark_arg(i); + } else if (strcmp(argv[i],"-naturalvar") == 0) { + Wrapper_naturalvar_mode_set(1); + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-nonaturalvar") == 0) { + Wrapper_naturalvar_mode_set(0); + Swig_mark_arg(i); } else if (strcmp(argv[i],"-directors") == 0) { SWIG_setfeature("feature:director","1"); Wrapper_director_mode_set(1); diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index 5300040a8..ef737c65d 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -354,6 +354,8 @@ void Wrapper_director_mode_set(int); void Wrapper_director_protected_mode_set(int); void Wrapper_fast_dispatch_mode_set(int); void Wrapper_cast_dispatch_mode_set(int); +void Wrapper_naturalvar_mode_set(int); + void clean_overloaded(Node *n); diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index b424eac29..82f47a6d4 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -101,7 +101,7 @@ Swig_clocal(SwigType *t, const String_or_char *name, const String_or_char *value * This function only converts user defined types to pointers. * ----------------------------------------------------------------------------- */ -static int varref = 0; +static int varcref = 0; String * Swig_wrapped_var_type(SwigType *t) { SwigType *ty; @@ -114,9 +114,29 @@ Swig_wrapped_var_type(SwigType *t) { } if (SwigType_isclass(t)) { - if (varref) { - if (!SwigType_isconst(ty)) SwigType_add_qualifier(ty, "const"); - SwigType_add_reference(ty); + SwigType_add_pointer(ty); + } + return ty; +} + +String * +Swig_wrapped_member_var_type(SwigType *t) { + SwigType *ty; + + if (!Strstr(t,"enum $unnamed")) { + ty = Copy(t); + } else { + /* Change the type for unnamed enum instance variables */ + ty = NewString("int"); + } + if (SwigType_isclass(t)) { + if (varcref) { + if (cparse_cplusplus) { + if (!SwigType_isconst(ty)) SwigType_add_qualifier(ty, "const"); + SwigType_add_reference(ty); + } else { + return Copy(ty); + } } else { SwigType_add_pointer(ty); } @@ -124,10 +144,19 @@ Swig_wrapped_var_type(SwigType *t) { return ty; } + static String * Swig_wrapped_var_deref(SwigType *t, String_or_char *name) { if (SwigType_isclass(t)) { - return NewStringf("*%s",name); + if (varcref) { + if (cparse_cplusplus) { + return NewStringf("*%s",name); + } else{ + return NewStringf("%s",name); + } + } else { + return NewStringf("*%s",name); + } } else { return SwigType_rcaststr(t,name); } @@ -136,9 +165,8 @@ Swig_wrapped_var_deref(SwigType *t, String_or_char *name) { static String * Swig_wrapped_var_assign(SwigType *t, const String_or_char *name) { if (SwigType_isclass(t)) { - if (varref) { - String* ty = SwigType_lstr(t,0); - return NewStringf("(const %s&)%s",ty, name); + if (varcref) { + return NewStringf("%s",name); } else { return NewStringf("&%s",name); } @@ -1176,7 +1204,7 @@ Swig_MembersetToFunction(Node *n, String *classname, int flags) { String *self= 0; String *sname; - varref = flags & CWRAP_VAR_REFERENCE; + varcref = flags & CWRAP_NATURAL_VAR; if (flags & CWRAP_SMART_POINTER) { self = NewString("(*this)->"); @@ -1195,7 +1223,7 @@ Swig_MembersetToFunction(Node *n, String *classname, int flags) { Setattr(parms,"self","1"); Delete(t); - ty = Swig_wrapped_var_type(type); + ty = Swig_wrapped_member_var_type(type); p = NewParm(ty,name); set_nextSibling(parms,p); @@ -1233,7 +1261,7 @@ Swig_MembersetToFunction(Node *n, String *classname, int flags) { Delete(sname); Delete(mangled); Delete(self); - varref = 0; + varcref = 0; return SWIG_OK; } @@ -1254,7 +1282,8 @@ Swig_MembergetToFunction(Node *n, String *classname, int flags) { String *mangled; String *self = 0; String *gname; - varref = flags & CWRAP_VAR_REFERENCE; + + varcref = flags & CWRAP_NATURAL_VAR; if (flags & CWRAP_SMART_POINTER) { if (checkAttribute(n, "storage", "static")) { @@ -1279,7 +1308,7 @@ Swig_MembergetToFunction(Node *n, String *classname, int flags) { Setattr(parms,"self","1"); Delete(t); - ty = Swig_wrapped_var_type(type); + ty = Swig_wrapped_member_var_type(type); if (flags & CWRAP_EXTEND) { String *call; String *cres; @@ -1307,7 +1336,9 @@ Swig_MembergetToFunction(Node *n, String *classname, int flags) { Delete(membername); Delete(gname); Delete(mangled); - varref = 0; + + varcref = 0; + return SWIG_OK; } diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 3526061f2..6dc9b8d23 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -499,7 +499,7 @@ extern int Swig_VarsetToFunction(Node *n); #define CWRAP_EXTEND 0x01 #define CWRAP_SMART_POINTER 0x02 -#define CWRAP_VAR_REFERENCE 0x04 +#define CWRAP_NATURAL_VAR 0x04 /* --- Director Helpers --- */ extern Node *Swig_methodclass(Node *n);