From 0cfc6cbd83f4ec273dac90b0f53b8330574b9c25 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 13 Jul 2016 22:08:45 +0100 Subject: [PATCH 01/63] %interface documentation corrections and tweaks Correction is for %interface_impl. [skip ci] --- Doc/Manual/Java.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index d3c592674..20ffb1a91 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -3359,20 +3359,20 @@ There is more than one macro in order to provide a choice for choosing the Java %interface(CTYPE) - Proxy class name is unchanged, interface name has SwigInterface added as a suffix for C++ class CTYPE. + For C++ class CTYPE, proxy class name is unchanged without any suffix added, interface name has SwigInterface added as a suffix. %interface_impl(CTYPE) - Proxy class name has SwigImpl as a suffix, interface name has SwigInterface added as a suffix for C++ class CTYPE. + For C++ class CTYPE, proxy class name has SwigImpl added as a suffix, interface name has no added suffix. %interface_custom("PROXY", "INTERFACE", CTYPE) - Proxy class name is given by the string PROXY, interface name is given by the string INTERFACE for C++ class CTYPE. The PROXY and INTERFACE names can use the string formatting functions used in %rename. + For C++ class CTYPE, proxy class name is given by the string PROXY, interface name is given by the string INTERFACE. The PROXY and INTERFACE names can use the string formatting functions used in %rename.

-The table below has a few examples showing the resulting proxy and interface names. +The table below has a few examples showing the resulting proxy and interface names for a C++ class called Base.

From 8c8937dbdbc4040bf38552d14f5ad549bef8fe65 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 20 Jul 2016 00:04:47 +0100 Subject: [PATCH 02/63] Minor c++11 doc change --- Doc/Manual/CPlusPlus11.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html index a4845832e..c825d8426 100644 --- a/Doc/Manual/CPlusPlus11.html +++ b/Doc/Manual/CPlusPlus11.html @@ -52,7 +52,7 @@
  • General-purpose smart pointers
  • Extensible random number facility
  • Wrapper reference -
  • Polymorphous wrappers for function objects +
  • Polymorphic wrappers for function objects
  • Type traits for metaprogramming
  • Uniform method for computing return type of function objects @@ -1029,7 +1029,7 @@ Users would need to write their own typemaps if wrapper references are being use

    -

    7.3.8 Polymorphous wrappers for function objects

    +

    7.3.8 Polymorphic wrappers for function objects

    From 9c3f608ef784af01033b824250812dc050545666 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 27 Jul 2016 18:46:23 +0100 Subject: [PATCH 03/63] Remove unused traits.swg This file has code that looks like it was migrated to Lib/std/std_common.i --- Examples/test-suite/traits.i | 6 - Lib/typemaps/traits.swg | 305 ----------------------------------- 2 files changed, 311 deletions(-) delete mode 100644 Examples/test-suite/traits.i delete mode 100644 Lib/typemaps/traits.swg diff --git a/Examples/test-suite/traits.i b/Examples/test-suite/traits.i deleted file mode 100644 index 0d25a60d9..000000000 --- a/Examples/test-suite/traits.i +++ /dev/null @@ -1,6 +0,0 @@ -%module traits - -%include typemaps/traits.swg - - -%fragment("Traits"); diff --git a/Lib/typemaps/traits.swg b/Lib/typemaps/traits.swg deleted file mode 100644 index 406f16066..000000000 --- a/Lib/typemaps/traits.swg +++ /dev/null @@ -1,305 +0,0 @@ -// -// Use the following macro with modern STL implementations -// -//#define SWIG_STD_MODERN_STL -// -// Use this to deactive the previous definition, when using gcc-2.95 -// or similar old compilers. -// -//#define SWIG_STD_NOMODERN_STL - -// Here, we identify compilers we now have problems with STL. -%{ -#if defined(__GNUC__) -# if __GNUC__ == 2 && __GNUC_MINOR <= 96 -# define SWIG_STD_NOMODERN_STL -# endif -#endif -%} - -// -// Common code for supporting the STD C++ namespace -// - -%fragment(""); -%fragment(""); - -%fragment("Traits","header",fragment="") -{ -namespace swig { - /* - type categories - */ - struct pointer_category { }; - struct value_category { }; - - /* - General traits that provides type_name and type_info - */ - template struct traits { }; - - template - inline const char* type_name() { - return traits::type_name(); - } - - template - struct traits_info { - static swig_type_info *type_query(std::string name) { - name += " *"; - return SWIG_TypeQuery(name.c_str()); - } - static swig_type_info *type_info() { - static swig_type_info *info = type_query(type_name()); - return info; - } - }; - - template - inline swig_type_info *type_info() { - return traits_info::type_info(); - } - - /* - Partial specialization for pointers - */ - template struct traits { - typedef pointer_category category; - static std::string make_ptr_name(const char* name) { - std::string ptrname = name; - ptrname += " *"; - return ptrname; - } - static const char* type_name() { - static std::string name = make_ptr_name(swig::type_name()); - return name.c_str(); - } - }; - - - template ::category > - struct traits_check { }; - - /* - Traits that provides the from method for an unknown type - */ - template struct traits_from_ptr { - static SWIG_Object from SWIG_FROM_DECL_ARGS(Type *val) { - return SWIG_NewPointerObj(val, type_info(), flags); - } - }; - - template struct traits_from { - static SWIG_Object from SWIG_FROM_DECL_ARGS(const Type& val) { - return traits_from_ptr::from(new Type(val)); - } - }; - - template struct traits_from { - static SWIG_Object from SWIG_FROM_DECL_ARGS(Type* val) { - return traits_from_ptr<0, Type>::from(val); - } - }; - - template - inline SWIG_Object from SWIG_FROM_DECL_ARGS(const Type& val) { - return traits_from::from(val); - } - - /* - Traits that provides the asptr/asval method for an unknown type - */ - template - struct traits_asptr { - static int asptr SWIG_AS_DECL_ARGS (SWIG_Object obj, Type **val) { - Type *p; - int res = SWIG_ConvertPtr(obj, %as_voidptrptr(&p), type_info(), 0); - if (SWIG_IsOK(res) && val) *val = p; - return res; - } - }; - - template - inline int asptr SWIG_AS_DECL_ARGS(SWIG_Object obj, Type **vptr) { - return traits_asptr::asptr SWIG_AS_CALL_ARGS(obj, vptr); - } - - template - struct traits_asval { - static int asval SWIG_AS_DECL_ARGS(SWIG_Object obj, Type *val) { - if (val) { - Type *p = 0; - int res = traits_asptr::asptr SWIG_AS_CALL_ARGS(obj, &p); - if (SWIG_IsOK(res) && p) { - *val = *p; - if (SWIG_IsNewObj(res)) { - %delete(p); - res = SWIG_DelNewMask(res); - } - } - return res; - } else { - return traits_asptr::asptr SWIG_AS_CALL_ARGS(obj, (Type **)(0)); - } - } - }; - - template - inline int asval SWIG_AS_DECL_ARGS (SWIG_Object obj, Type *val) { - return traits_asval::asval SWIG_AS_CALL_ARGS(obj, val); - } - - /* - Traits that provides the check method for an unknown type - */ -#define SWIG_CHECK_DECL_ARGS(obj) SWIG_AS_DECL_ARGS(obj, void * = 0) -#define SWIG_CHECK_CALL_ARGS(obj) SWIG_AS_CALL_ARGS(obj, 0) - - template - struct traits_checkval { - static int check SWIG_CHECK_DECL_ARGS(SWIG_Object obj) { - if (obj) { - int res = asval SWIG_AS_CALL_ARGS(obj, (Type *)(0)); - return SWIG_CheckState(res); - } else { - return 0; - } - } - }; - - template - struct traits_checkptr { - static int check SWIG_CHECK_DECL_ARGS(SWIG_Object obj) { - if (obj) { - int res = asptr SWIG_AS_CALL_ARGS(obj, (Type **)(0)); - return SWIG_CheckState(res); - } else { - return 0; - } - } - }; - - template - struct traits_check : traits_checkval { - }; - - template - struct traits_check : traits_checkptr { - }; - - template - inline int check SWIG_CHECK_DECL_ARGS(SWIG_Object obj) { - return traits_check::check SWIG_CHECK_CALL_ARGS(obj); - } - -} -} - -/* - Generate the traits for an unknown SWIGTYPE -*/ - -%define %traits_swigtype(Type...) -%fragment(SWIG_Traits_frag(Type),"header",fragment="Traits") { - namespace swig { - template <> struct traits { - typedef pointer_category category; - static const char* type_name() { return #Type; } - }; - } -} -%enddef - - -/* - Generate the traits for a 'value' type, such as 'double', - for which the SWIG_AsVal and SWIG_From methods are already defined. -*/ - -%define %traits_value(Type...) -%fragment(SWIG_Traits_frag(Type),"header", - fragment=SWIG_AsVal_frag(Type), - fragment=SWIG_From_frag(Type), - fragment="Traits") { -namespace swig { - template <> struct traits { - typedef value_category category; - static const char* type_name() { return #Type; } - }; - - template <> struct traits_asval { - typedef Type value_type; - static int asval SWIG_AS_DECL_ARGS (SWIG_Object obj, value_type *val) { - return SWIG_AsVal(Type)(obj, val); - } - }; - - template <> struct traits_from { - typedef Type value_type; - static SWIG_Object from SWIG_FROM_DECL_ARGS (const value_type& val) { - return SWIG_From(Type)(val); - } - }; -} -} -%enddef - -/* - Generate the traits for a 'pointer' type, such as 'std::string', - for which the SWIG_AsPtr and SWIG_From methods are already defined. -*/ - -%define %traits_pointer(Type...) -%fragment(SWIG_Traits_frag(Type),"header", - fragment=SWIG_AsVal_frag(Type), - fragment=SWIG_From_frag(Type), - fragment="Traits") { -namespace swig { - template <> struct traits { - typedef pointer_category category; - static const char* type_name() { return #Type; } - }; - - template <> struct traits_asptr { - typedef Type value_type; - static int asptr SWIG_AS_DECL_ARGS (SWIG_Object obj, value_type **val) { - return SWIG_AsPtr(Type)(obj, val); - } - }; - - template <> struct traits_from { - typedef Type value_type; - static SWIG_Object from SWIG_FROM_DECL_ARGS (const value_type& val) { - return SWIG_From(Type)(val); - } - }; -} -} -%enddef - -/* - Generate the typemaps for a class that has 'value' traits -*/ - -%define %typemap_traits_value(Code,Type...) - %typemaps_asvalfrom(%arg(Code), - %arg(swig::asval), - %arg(swig::from), - %arg(SWIG_Traits_frag(Type)), - %arg(SWIG_Traits_frag(Type)), - Type); -%enddef - -/* - Generate the typemaps for a class that has 'pointer' traits -*/ - -%define %typemap_traits_pointer(Code,Type...) - %typemaps_asptrfrom(%arg(Code), - %arg(swig::asptr), - %arg(swig::from), - %arg(SWIG_Traits_frag(Type)), - %arg(SWIG_Traits_frag(Type)), - Type); -%enddef - From 6e9184b6f82e99a5095b5812a4b6b7040f87d17d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 27 Jul 2016 19:49:38 +0100 Subject: [PATCH 04/63] Fix std::vector of pointers which failed if a pointer to a pointer of the container element type existed (Python) Closes SF Bug 2359417 created after commit 93f039032204821d4fc363346587c90f640a1109 (svn rev 10958) --- Examples/test-suite/common.mk | 2 +- .../test-suite/go/li_std_vector_ptr_runme.go | 9 ++- Examples/test-suite/li_std_vector_ptr.i | 66 ++++++++++++++++++- .../python/li_std_vector_ptr_runme.py | 33 +++++++++- Lib/std/std_common.i | 19 +++++- 5 files changed, 120 insertions(+), 9 deletions(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 1658e509b..c40630b42 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -87,7 +87,6 @@ CPP_TEST_BROKEN += \ director_nested_class \ exception_partial_info \ extend_variable \ - li_std_vector_ptr \ li_boost_shared_ptr_template \ nested_private \ overload_complicated \ @@ -588,6 +587,7 @@ CPP_STD_TEST_CASES += \ li_std_vector \ li_std_vector_enum \ li_std_vector_member_var\ + li_std_vector_ptr \ smart_pointer_inherit \ template_typedef_fnc \ template_type_namespace \ diff --git a/Examples/test-suite/go/li_std_vector_ptr_runme.go b/Examples/test-suite/go/li_std_vector_ptr_runme.go index cee997ad0..a9f7fe91c 100644 --- a/Examples/test-suite/go/li_std_vector_ptr_runme.go +++ b/Examples/test-suite/go/li_std_vector_ptr_runme.go @@ -1,12 +1,19 @@ package main import . "./li_std_vector_ptr" +import "fmt" +func check(val1 int, val2 int) { + if val1 != val2 { + panic(fmt.Sprintf("Values are not the same %d %d", val1, val2)) + } +} func main() { ip1 := MakeIntPtr(11) ip2 := MakeIntPtr(22) vi := NewIntPtrVector() vi.Add(ip1) vi.Add(ip2) - DisplayVector(vi) + check(GetValueFromVector(vi, 0), 11) + check(GetValueFromVector(vi, 1), 22) } diff --git a/Examples/test-suite/li_std_vector_ptr.i b/Examples/test-suite/li_std_vector_ptr.i index 292c9d700..e543ae967 100644 --- a/Examples/test-suite/li_std_vector_ptr.i +++ b/Examples/test-suite/li_std_vector_ptr.i @@ -1,4 +1,4 @@ -// Bug 2359417 +// SF Bug 2359417 %module li_std_vector_ptr %include "std_vector.i" @@ -15,16 +15,76 @@ double* makeDoublePtr(double v) { return new double(v); } -#if 1 +// pointer to pointer in the wrappers was preventing a vector of pointers from working int** makeIntPtrPtr(int* v) { return new int*(v); } -#endif void displayVector(std::vector vpi) { cout << "displayVector..." << endl; for (int i=0; i vpi, size_t index) { + return *vpi[index]; +} +%} + +// A not exposed to wrappers +%{ +struct A { + int val; + A(int val) : val(val) {} +}; +%} + +%template(APtrVector) std::vector; + +%inline %{ +A *makeA(int val) { return new A(val); } +int getVal(A* a) { return a->val; } +int getVectorValueA(std::vector vpi, size_t index) { + return vpi[index]->val; +} +%} + +// B is fully exposed to wrappers +%inline %{ +struct B { + int val; + B(int val = 0) : val(val) {} +}; +%} + +%template(BPtrVector) std::vector; + +%inline %{ +B *makeB(int val) { return new B(val); } +int getVal(B* b) { return b->val; } +int getVectorValueB(std::vector vpi, size_t index) { + return vpi[index]->val; +} +%} + +// C is fully exposed to wrappers (includes code using B **) +%inline %{ +struct C { + int val; + C(int val = 0) : val(val) {} +}; +%} + +%template(CPtrVector) std::vector; + +%inline %{ +// pointer to pointer in the wrappers was preventing a vector of pointers from working +C** makeCIntPtrPtr(C* v) { + return new C*(v); +} +C *makeC(int val) { return new C(val); } +int getVal(C* b) { return b->val; } +int getVectorValueC(std::vector vpi, size_t index) { + return vpi[index]->val; +} %} diff --git a/Examples/test-suite/python/li_std_vector_ptr_runme.py b/Examples/test-suite/python/li_std_vector_ptr_runme.py index 01c654109..b49cdb4e9 100644 --- a/Examples/test-suite/python/li_std_vector_ptr_runme.py +++ b/Examples/test-suite/python/li_std_vector_ptr_runme.py @@ -1,7 +1,38 @@ from li_std_vector_ptr import * +def check(val1, val2): + if val1 != val2: + raise RuntimeError("Values are not the same %s %s" % (val1, val2)) ip1 = makeIntPtr(11) ip2 = makeIntPtr(22) vi = IntPtrVector((ip1, ip2)) -displayVector(vi) +check(getValueFromVector(vi, 0), 11) +check(getValueFromVector(vi, 1), 22) + +vA = APtrVector([makeA(33), makeA(34)]) +check(getVectorValueA(vA, 0), 33) + +vB = BPtrVector([makeB(133), makeB(134)]) +check(getVectorValueB(vB, 0), 133) + +vC = CPtrVector([makeC(1133), makeC(1134)]) +check(getVectorValueC(vC, 0), 1133) + + +vA = [makeA(233), makeA(234)] +check(getVectorValueA(vA, 0), 233) + +vB = [makeB(333), makeB(334)] +check(getVectorValueB(vB, 0), 333) + +vC = [makeC(3333), makeC(3334)] +check(getVectorValueC(vC, 0), 3333) + +# mixed A and B should not be accepted +vAB = [makeA(999), makeB(999)] +try: + check(getVectorValueA(vAB, 0), 999) + raise RuntimeError("missed exception") +except TypeError: + pass diff --git a/Lib/std/std_common.i b/Lib/std/std_common.i index b79eaff3a..05bc4325a 100644 --- a/Lib/std/std_common.i +++ b/Lib/std/std_common.i @@ -99,8 +99,21 @@ namespace swig { return traits::noconst_type >::type_name(); } - template - struct traits_info { + template struct traits_info { + static swig_type_info *type_query(std::string name) { + name += " *"; + return SWIG_TypeQuery(name.c_str()); + } + static swig_type_info *type_info() { + static swig_type_info *info = type_query(type_name()); + return info; + } + }; + + /* + Partial specialization for pointers (traits_info) + */ + template struct traits_info { static swig_type_info *type_query(std::string name) { name += " *"; return SWIG_TypeQuery(name.c_str()); @@ -117,7 +130,7 @@ namespace swig { } /* - Partial specialization for pointers + Partial specialization for pointers (traits) */ template struct traits { typedef pointer_category category; From 91aba9f719273778fe0196f9bc8659131c9e2cf8 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 28 Jul 2016 08:31:03 +0100 Subject: [PATCH 05/63] UTL STL container descriptor checks The vector of pointers (just fixed) were not working correctly because the descriptors returned from swig::type_info() were sometimes returning zero. Zero should only be used for void * as the subsequent call to SWIG_ConvertPtr will blindly cast the pointer without checking descriptor. std::vector does not work and will require further changes: specializing traits_info to return 0 and traits_asptr. I tried this and traits_asptr also needs to be added in which seems odd and requires further investigation... Lib/python/pystdcommon.swg: template <> struct traits_info { static swig_type_info *type_info() { static swig_type_info *info = 0; } }; Lib/std/std_common.i: template <> struct traits_asptr { static int asptr(PyObject *obj, void ***val) { void **p; swig_type_info *descriptor = 0; int res = SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0); if (SWIG_IsOK(res)) { if (val) *val = p; } return res; } }; // this is needed, but am not sure this is expected template <> struct traits_asptr { static int asptr(PyObject *obj, void **val) { void **p; swig_type_info *descriptor = 0; int res = SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0); if (SWIG_IsOK(res)) { if (val) *val = p; } return res; } }; --- Lib/octave/octcontainer.swg | 4 ++-- Lib/octave/octstdcommon.swg | 3 ++- Lib/octave/std_map.i | 3 ++- Lib/octave/std_pair.i | 6 ++++-- Lib/python/pycontainer.swg | 4 ++-- Lib/python/pystdcommon.swg | 3 ++- Lib/python/std_map.i | 3 ++- Lib/python/std_multimap.i | 3 ++- Lib/python/std_pair.i | 6 ++++-- Lib/python/std_unordered_map.i | 3 ++- Lib/python/std_unordered_multimap.i | 3 ++- Lib/r/rstdcommon.swg | 3 ++- Lib/ruby/rubycontainer.swg | 17 +++++++---------- Lib/ruby/rubystdcommon.swg | 3 ++- Lib/ruby/std_map.i | 3 ++- Lib/ruby/std_pair.i | 8 ++++---- Lib/scilab/scistdcommon.swg | 3 ++- Lib/typemaps/implicit.swg | 16 ++++++++-------- 18 files changed, 53 insertions(+), 41 deletions(-) diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg index 0211b33c6..af58f3aaa 100644 --- a/Lib/octave/octcontainer.swg +++ b/Lib/octave/octcontainer.swg @@ -562,8 +562,8 @@ namespace swig { static int asptr(const octave_value& obj, sequence **seq) { if (!obj.is_defined() || Swig::swig_value_deref(obj)) { sequence *p; - if (SWIG_ConvertPtr(obj,(void**)&p, - swig::type_info(),0) == SWIG_OK) { + swig_type_info *descriptor = swig::type_info(); + if (descriptor && SWIG_IsOK(SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) { if (seq) *seq = p; return SWIG_OLDOBJ; } diff --git a/Lib/octave/octstdcommon.swg b/Lib/octave/octstdcommon.swg index 96923f40a..799d369a7 100644 --- a/Lib/octave/octstdcommon.swg +++ b/Lib/octave/octstdcommon.swg @@ -42,7 +42,8 @@ namespace swig { struct traits_asptr { static int asptr(const octave_value& obj, Type **val) { Type *p; - int res = SWIG_ConvertPtr(obj, (void**)&p, type_info(), 0); + swig_type_info *descriptor = type_info(); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = p; } diff --git a/Lib/octave/std_map.i b/Lib/octave/std_map.i index 7b85a548e..fd15661c3 100644 --- a/Lib/octave/std_map.i +++ b/Lib/octave/std_map.i @@ -98,7 +98,8 @@ res = traits_asptr_stdseq, std::pair >::asptr(items, val); } else { map_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } return res; diff --git a/Lib/octave/std_pair.i b/Lib/octave/std_pair.i index ab028d144..a06498bf2 100644 --- a/Lib/octave/std_pair.i +++ b/Lib/octave/std_pair.i @@ -47,7 +47,8 @@ return get_pair(c(0),c(1),val); } else { value_type *p; - int res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = *p; return res; @@ -100,7 +101,8 @@ return get_pair(c(0),c(1),val); } else { value_type *p; - int res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; return res; diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg index 46d04388b..4621c1b34 100644 --- a/Lib/python/pycontainer.swg +++ b/Lib/python/pycontainer.swg @@ -968,8 +968,8 @@ namespace swig { static int asptr(PyObject *obj, sequence **seq) { if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) { sequence *p; - if (::SWIG_ConvertPtr(obj,(void**)&p, - swig::type_info(),0) == SWIG_OK) { + swig_type_info *descriptor = swig::type_info(); + if (descriptor && SWIG_IsOK(::SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) { if (seq) *seq = p; return SWIG_OLDOBJ; } diff --git a/Lib/python/pystdcommon.swg b/Lib/python/pystdcommon.swg index 2af22e2a4..8372426a0 100644 --- a/Lib/python/pystdcommon.swg +++ b/Lib/python/pystdcommon.swg @@ -46,7 +46,8 @@ namespace swig { struct traits_asptr { static int asptr(PyObject *obj, Type **val) { Type *p; - int res = SWIG_ConvertPtr(obj, (void**)&p, type_info(), 0); + swig_type_info *descriptor = type_info(); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = p; } diff --git a/Lib/python/std_map.i b/Lib/python/std_map.i index 65dd91d9c..f61f79c44 100644 --- a/Lib/python/std_map.i +++ b/Lib/python/std_map.i @@ -102,7 +102,8 @@ res = traits_asptr_stdseq >::asptr(items, val); } else { map_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } SWIG_PYTHON_THREAD_END_BLOCK; diff --git a/Lib/python/std_multimap.i b/Lib/python/std_multimap.i index 2c539cf29..3209fb0f8 100644 --- a/Lib/python/std_multimap.i +++ b/Lib/python/std_multimap.i @@ -26,7 +26,8 @@ return traits_asptr_stdseq, std::pair >::asptr(items, val); } else { multimap_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } return res; diff --git a/Lib/python/std_pair.i b/Lib/python/std_pair.i index 5694e7e09..da31918c8 100644 --- a/Lib/python/std_pair.i +++ b/Lib/python/std_pair.i @@ -48,7 +48,8 @@ } } else { value_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = *p; } return res; @@ -98,7 +99,8 @@ } } else { value_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } return res; diff --git a/Lib/python/std_unordered_map.i b/Lib/python/std_unordered_map.i index f956f4fb3..97b48af70 100644 --- a/Lib/python/std_unordered_map.i +++ b/Lib/python/std_unordered_map.i @@ -29,7 +29,8 @@ res = traits_asptr_stdseq, std::pair >::asptr(items, val); } else { unordered_map_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } return res; diff --git a/Lib/python/std_unordered_multimap.i b/Lib/python/std_unordered_multimap.i index b3b723637..aadd15515 100644 --- a/Lib/python/std_unordered_multimap.i +++ b/Lib/python/std_unordered_multimap.i @@ -26,7 +26,8 @@ return traits_asptr_stdseq, std::pair >::asptr(items, val); } else { unordered_multimap_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } return res; diff --git a/Lib/r/rstdcommon.swg b/Lib/r/rstdcommon.swg index b11cf677b..e6c873a07 100644 --- a/Lib/r/rstdcommon.swg +++ b/Lib/r/rstdcommon.swg @@ -40,7 +40,8 @@ namespace swig { struct traits_asptr { static int asptr(SWIG_Object obj, Type **val) { Type *p; - int res = SWIG_ConvertPtr(obj, (void**)&p, type_info(), 0); + swig_type_info *descriptor = type_info(); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = p; } diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index 2908ef7b7..a6d8a59ef 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -464,8 +464,7 @@ namespace swig %typemap(in,noblock=1,fragment="RubySequence_Cont") const_iterator(swig::ConstIterator *iter = 0, int res), const_reverse_iterator(swig::ConstIterator *iter = 0, int res) { - res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), - swig::ConstIterator::descriptor(), 0); + res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::ConstIterator::descriptor(), 0); if (!SWIG_IsOK(res) || !iter) { %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); } else { @@ -497,16 +496,14 @@ namespace swig %typecheck(%checkcode(ITERATOR),noblock=1,fragment="RubySequence_Cont") const_iterator, const_reverse_iterator { swig::ConstIterator *iter = 0; - int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), - swig::ConstIterator::descriptor(), 0); + int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::ConstIterator::descriptor(), 0); $1 = (SWIG_IsOK(res) && iter && (dynamic_cast *>(iter) != 0)); } %typecheck(%checkcode(ITERATOR),noblock=1,fragment="RubySequence_Cont") iterator, reverse_iterator { swig::ConstIterator *iter = 0; - int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), - swig::Iterator::descriptor(), 0); + int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::Iterator::descriptor(), 0); $1 = (SWIG_IsOK(res) && iter && (dynamic_cast *>(iter) != 0)); } @@ -1037,8 +1034,8 @@ namespace swig { } } else { sequence *p; - if (SWIG_ConvertPtr(obj,(void**)&p, - swig::type_info(),0) == SWIG_OK) { + swig_type_info *descriptor = swig::type_info(); + if (descriptor && SWIG_IsOK(SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) { if (seq) *seq = p; return SWIG_OLDOBJ; } @@ -1077,8 +1074,8 @@ namespace swig { } } else { sequence *p; - if (SWIG_ConvertPtr(obj,(void**)&p, - swig::type_info(),0) == SWIG_OK) { + swig_type_info *descriptor = swig::type_info(); + if (descriptor && SWIG_IsOK(SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0))) { if (seq) *seq = p; return SWIG_OLDOBJ; } diff --git a/Lib/ruby/rubystdcommon.swg b/Lib/ruby/rubystdcommon.swg index b4ae3a3cc..f72745b56 100644 --- a/Lib/ruby/rubystdcommon.swg +++ b/Lib/ruby/rubystdcommon.swg @@ -53,7 +53,8 @@ namespace swig { struct traits_asptr { static int asptr(VALUE obj, Type **val) { Type *p; - int res = SWIG_ConvertPtr(obj, (void**)&p, type_info(), 0); + swig_type_info *descriptor = type_info(); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = p; } diff --git a/Lib/ruby/std_map.i b/Lib/ruby/std_map.i index f706ca873..7077fa104 100644 --- a/Lib/ruby/std_map.i +++ b/Lib/ruby/std_map.i @@ -100,7 +100,8 @@ res = traits_asptr_stdseq, std::pair >::asptr(items, val); } else { map_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } return res; diff --git a/Lib/ruby/std_pair.i b/Lib/ruby/std_pair.i index 5b4c8baf2..5bea67c7c 100644 --- a/Lib/ruby/std_pair.i +++ b/Lib/ruby/std_pair.i @@ -44,8 +44,8 @@ } } else { value_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p, - swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = *p; } return res; @@ -90,8 +90,8 @@ } } else { value_type *p; - res = SWIG_ConvertPtr(obj,(void**)&p, - swig::type_info(),0); + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res) && val) *val = p; } return res; diff --git a/Lib/scilab/scistdcommon.swg b/Lib/scilab/scistdcommon.swg index 7fdc72212..63f3ca164 100644 --- a/Lib/scilab/scistdcommon.swg +++ b/Lib/scilab/scistdcommon.swg @@ -42,7 +42,8 @@ namespace swig { struct traits_asptr { static int asptr(const SwigSciObject& obj, Type **val) { Type *p; - int res = SWIG_ConvertPtr(obj, (void**)&p, type_info(), 0); + swig_type_info *descriptor = type_info(); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = p; } diff --git a/Lib/typemaps/implicit.swg b/Lib/typemaps/implicit.swg index 702fb52b8..2fc3108e7 100644 --- a/Lib/typemaps/implicit.swg +++ b/Lib/typemaps/implicit.swg @@ -73,8 +73,8 @@ namespace swig { typedef Type value_type; static int asptr(SWIG_Object obj, value_type **val) { Type *vptr; - static swig_type_info* desc = SWIG_TypeQuery("Type *"); - int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0); + static swig_type_info* descriptor = SWIG_TypeQuery("Type *"); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&vptr, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = vptr; return res; @@ -109,8 +109,8 @@ namespace swig { typedef Type value_type; static int asptr(SWIG_Object obj, value_type **val) { Type *vptr; - static swig_type_info* desc = SWIG_TypeQuery("Type *"); - int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0); + static swig_type_info* descriptor = SWIG_TypeQuery("Type *"); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&vptr, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = vptr; return res; @@ -147,8 +147,8 @@ namespace swig { typedef Type value_type; static int asptr(SWIG_Object obj, value_type **val) { Type *vptr; - static swig_type_info* desc = SWIG_TypeQuery("Type *"); - int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0); + static swig_type_info* descriptor = SWIG_TypeQuery("Type *"); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&vptr, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = vptr; return SWIG_OLDOBJ; @@ -188,8 +188,8 @@ namespace swig { typedef Type value_type; static int asptr(SWIG_Object obj, value_type **val) { Type *vptr; - static swig_type_info* desc = SWIG_TypeQuery("Type *"); - int res = SWIG_ConvertPtr(obj, (void **)&vptr, desc, 0); + static swig_type_info* descriptor = SWIG_TypeQuery("Type *"); + int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&vptr, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { if (val) *val = vptr; return res; From 95a5def3282b59cf26f1a20d4073cbae98cd5fea Mon Sep 17 00:00:00 2001 From: Simon Marchetto Date: Fri, 29 Jul 2016 11:52:26 +0200 Subject: [PATCH 06/63] scilab: fix issue #755 --- Examples/test-suite/scilab/Makefile.in | 2 +- .../test-suite/scilab/scilab_enums_runme.sci | 9 +++++++++ Examples/test-suite/scilab_enums.i | 17 +++++++++++++++++ Source/Modules/scilab.cxx | 2 +- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/scilab/Makefile.in b/Examples/test-suite/scilab/Makefile.in index 9ddd8f1aa..483ed2439 100644 --- a/Examples/test-suite/scilab/Makefile.in +++ b/Examples/test-suite/scilab/Makefile.in @@ -13,7 +13,6 @@ top_builddir = ../@top_builddir@ C_TEST_CASES += \ scilab_consts \ - scilab_enums \ scilab_identifier_name \ CPP_TEST_CASES += \ @@ -21,6 +20,7 @@ CPP_TEST_CASES += \ primitive_types \ scilab_li_matrix \ scilab_multivalue \ + scilab_enums \ scilab_pointer_conversion_functions \ CPP_STD_TEST_CASES += \ diff --git a/Examples/test-suite/scilab/scilab_enums_runme.sci b/Examples/test-suite/scilab/scilab_enums_runme.sci index 3e9fb7ae0..2776bee1e 100644 --- a/Examples/test-suite/scilab/scilab_enums_runme.sci +++ b/Examples/test-suite/scilab/scilab_enums_runme.sci @@ -24,4 +24,13 @@ checkEnum(TYPEDEF_ENUM_1_2, 22); checkEnum(TYPEDEF_ENUM_2_1, 31); checkEnum(TYPEDEF_ENUM_2_2, 32); +checkEnum(ENUM_REF_1, 1); +checkEnum(ENUM_REF_2, 10); + +checkEnum(clsEnum_CLS_ENUM_1, 100); +checkEnum(clsEnum_CLS_ENUM_2, 101); + +checkEnum(clsEnum_CLS_ENUM_REF_1, 101); +checkEnum(clsEnum_CLS_ENUM_REF_2, 110); + exec("swigtest.quit", -1); diff --git a/Examples/test-suite/scilab_enums.i b/Examples/test-suite/scilab_enums.i index 32d5a34de..9c2e393e0 100644 --- a/Examples/test-suite/scilab_enums.i +++ b/Examples/test-suite/scilab_enums.i @@ -35,4 +35,21 @@ typedef enum TYPEDEF_ENUM_2 { TYPEDEF_ENUM_2_2 = 32 } TYPEDEF_ENUM_2; +enum ENUM_REF { + ENUM_REF_1 = 1, + ENUM_REF_2 = ENUM_REF_1 + 9 +}; + +class clsEnum { +public: + enum CLS_ENUM { + CLS_ENUM_1 = 100, + CLS_ENUM_2 = 101 + }; + enum CLS_ENUM_REF { + CLS_ENUM_REF_1 = 101, + CLS_ENUM_REF_2 = CLS_ENUM_REF_1 + 9 + }; +}; + %} diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index 137adc234..e6c279e56 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -664,7 +664,7 @@ public: if (isConstant || isEnum) { if (isEnum) { Setattr(node, "type", "double"); - constantValue = Getattr(node, "enumvalue"); + constantValue = Getattr(node, "value"); } constantTypemap = Swig_typemap_lookup("scilabconstcode", node, nodeName, 0); From d0a45be1ebfe125d51696b48cb5d359bc7431052 Mon Sep 17 00:00:00 2001 From: Simon Marchetto Date: Fri, 29 Jul 2016 16:56:30 +0200 Subject: [PATCH 07/63] scilab: fix issue #746 --- Source/Modules/scilab.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index e6c279e56..c44c92d6c 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -1030,7 +1030,7 @@ public: Printf(gatewayHeaderV5, ",\n"); Printf(gatewayHeaderV5, " {(Myinterfun)sci_gateway, (GT)%s, (char *)\"%s\"}", wrapperFunctionName, scilabFunctionName); - Printf(gatewayHeaderV6, "if (wcscmp(pwstFuncName, L\"%s\") == 0) { addCFunction((wchar_t *)L\"%s\", &%s, (wchar_t *)MODULE_NAME); }\n", scilabFunctionName, scilabFunctionName, wrapperFunctionName); + Printf(gatewayHeaderV6, "if (wcscmp(pwstFuncName, L\"%s\") == 0) { addCStackFunction((wchar_t *)L\"%s\", &%s, (wchar_t *)MODULE_NAME); }\n", scilabFunctionName, scilabFunctionName, wrapperFunctionName); } /* ----------------------------------------------------------------------- From 0177937f7e4d45cbb677a9423b638d732fe65435 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 30 Jul 2016 15:00:55 +0100 Subject: [PATCH 08/63] Fix testcase causing nodejs test failure --- Examples/test-suite/li_std_vector_ptr.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/test-suite/li_std_vector_ptr.i b/Examples/test-suite/li_std_vector_ptr.i index e543ae967..4d6794717 100644 --- a/Examples/test-suite/li_std_vector_ptr.i +++ b/Examples/test-suite/li_std_vector_ptr.i @@ -22,7 +22,7 @@ int** makeIntPtrPtr(int* v) { void displayVector(std::vector vpi) { cout << "displayVector..." << endl; - for (int i=0; i vpi, size_t index) { From 56ab717ff35579e8468d7617162c1b7f46fd2b68 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 30 Jul 2016 21:23:57 +0100 Subject: [PATCH 09/63] Test case warning fixes for nodejs nodejs 4.2.1 on Ubuntu Xenial Xerus --- Examples/test-suite/cpp_enum.i | 6 ++++++ Examples/test-suite/enum_thorough.i | 6 ++++++ Examples/test-suite/enums.i | 6 ++++++ Examples/test-suite/nested.i | 12 ++++++++++++ Examples/test-suite/nested_extend_c.i | 12 ++++++++++++ Examples/test-suite/nested_structs.i | 12 ++++++++++++ Examples/test-suite/typedef_struct.i | 7 +++++++ 7 files changed, 61 insertions(+) diff --git a/Examples/test-suite/cpp_enum.i b/Examples/test-suite/cpp_enum.i index cb212615a..548c65de4 100644 --- a/Examples/test-suite/cpp_enum.i +++ b/Examples/test-suite/cpp_enum.i @@ -6,6 +6,12 @@ The primary purpose of this testcase is to ensure that enums used along with the %inline %{ +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +/* for anonymous enums */ +/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */ +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + enum SOME_ENUM {ENUM_ONE, ENUM_TWO}; struct StructWithEnums { diff --git a/Examples/test-suite/enum_thorough.i b/Examples/test-suite/enum_thorough.i index 66189fbe2..fd5978102 100644 --- a/Examples/test-suite/enum_thorough.i +++ b/Examples/test-suite/enum_thorough.i @@ -47,6 +47,12 @@ %inline %{ +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +/* for anonymous enums */ +/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */ +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + enum { AnonEnum1, AnonEnum2 = 100 }; enum { ReallyAnInteger = 200 }; //enum { AnonEnum3, AnonEnum4 } instance; diff --git a/Examples/test-suite/enums.i b/Examples/test-suite/enums.i index 14c6efbba..b8ffd7588 100644 --- a/Examples/test-suite/enums.i +++ b/Examples/test-suite/enums.i @@ -12,6 +12,12 @@ %inline %{ +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +/* for anonymous enums */ +/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */ +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + typedef enum { CSP_ITERATION_FWD, CSP_ITERATION_BWD = 11 diff --git a/Examples/test-suite/nested.i b/Examples/test-suite/nested.i index 1d4710128..216ee4224 100644 --- a/Examples/test-suite/nested.i +++ b/Examples/test-suite/nested.i @@ -13,6 +13,18 @@ Also tests reported error when a #define placed in a deeply embedded struct/unio %rename(InUnNamed) OuterStructNamed::Inner_union_named; #endif +#if defined(SWIG_JAVASCRIPT_V8) + +%inline %{ +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +/* for nested C class wrappers compiled as C++ code */ +/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */ +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +%} + +#endif + %inline %{ struct TestStruct { diff --git a/Examples/test-suite/nested_extend_c.i b/Examples/test-suite/nested_extend_c.i index 032619f8e..f1d7ff2c8 100644 --- a/Examples/test-suite/nested_extend_c.i +++ b/Examples/test-suite/nested_extend_c.i @@ -1,5 +1,17 @@ %module nested_extend_c +#if defined(SWIG_JAVASCRIPT_V8) + +%inline %{ +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +/* for nested C class wrappers compiled as C++ code */ +/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */ +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +%} + +#endif + #if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) %extend hiA { hiA() { diff --git a/Examples/test-suite/nested_structs.i b/Examples/test-suite/nested_structs.i index f4f7a275a..c70924958 100644 --- a/Examples/test-suite/nested_structs.i +++ b/Examples/test-suite/nested_structs.i @@ -1,5 +1,17 @@ %module nested_structs +#if defined(SWIG_JAVASCRIPT_V8) + +%inline %{ +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +/* for nested C class wrappers compiled as C++ code */ +/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */ +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +%} + +#endif + // bug #491476 %inline %{ struct Outer { diff --git a/Examples/test-suite/typedef_struct.i b/Examples/test-suite/typedef_struct.i index 97456d9a6..185e81105 100644 --- a/Examples/test-suite/typedef_struct.i +++ b/Examples/test-suite/typedef_struct.i @@ -1,6 +1,13 @@ %module typedef_struct %inline %{ + +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +/* for anonymous enums */ +/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */ +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + typedef struct { int numpoints; } LineObj; From 5648418c98e5cefc363db1d4ae3125618297ee79 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Mon, 1 Aug 2016 09:51:46 +1200 Subject: [PATCH 10/63] Remove bogus full stop --- Doc/Manual/Extending.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html index 14dcbdccd..e44d53084 100644 --- a/Doc/Manual/Extending.html +++ b/Doc/Manual/Extending.html @@ -2534,7 +2534,7 @@ also return a pointer to the base class (Language) so that only the int

    -Save the code for your language module in a file named "python.cxx" and. +Save the code for your language module in a file named "python.cxx" and place this file in the Source/Modules directory of the SWIG distribution. To ensure that your module is compiled into SWIG along with the other language modules, modify the file Source/Modules/Makefile.am to include the additional source From 2740812970382202fe97e52f7c881eaa71c2e7c0 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 1 Aug 2016 07:03:42 +0100 Subject: [PATCH 11/63] changes entry for vector fix --- CHANGES.current | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 075c00ef6..6dfac62d4 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-07-01: wsfulton + Fix corner case of wrapping std::vector of T pointers where a pointer to a pointer of T + also exists in the wrapped code. SF Bug 2359417 (967). + 2016-06-26: wkalinin [Java, C#] Patch #681 Fix seg fault when ignoring nested classes. From a950d1309bfb750a522e5bf20a33374a7c39e45c Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 5 Aug 2016 11:52:35 +1200 Subject: [PATCH 12/63] [xml] Fix how the output filename is built Avoid problems when it contains the embedded strings ".c", ".cpp" or ".cxx". Fixes #540 reported by djack42. --- CHANGES.current | 5 +++++ Source/Modules/xml.cxx | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 6dfac62d4..36780b440 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-08-05: olly + [xml] Fix how the output filename is built to avoid problems when + it contains the embedded strings ".c", ".cpp" or ".cxx". + Fixes #540 reported by djack42. + 2016-07-01: wsfulton Fix corner case of wrapping std::vector of T pointers where a pointer to a pointer of T also exists in the wrapped code. SF Bug 2359417 (967). diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx index 45b7f7a89..a69e7b043 100644 --- a/Source/Modules/xml.cxx +++ b/Source/Modules/xml.cxx @@ -81,9 +81,11 @@ public: virtual int top(Node *n) { if (out == 0) { String *outfile = Getattr(n, "outfile"); - Replaceall(outfile, ".cxx", ".xml"); - Replaceall(outfile, ".cpp", ".xml"); - Replaceall(outfile, ".c", ".xml"); + String *ext = Swig_file_extension(outfile); + // If there's an extension, ext will include the ".". + Delslice(outfile, Len(outfile) - Len(ext), DOH_END); + Delete(ext); + Append(outfile, ".xml"); out = NewFile(outfile, "w", SWIG_output_files()); if (!out) { FileErrorDisplay(outfile); From c334efd36bc6cb66cb7b9bdc70d1f9472a441cf8 Mon Sep 17 00:00:00 2001 From: Richard Beare Date: Fri, 5 Aug 2016 15:43:50 +1000 Subject: [PATCH 13/63] Writing R extensions says: Most R header files can be included within C++ programs but they should not be included within an extern "C" block (as they include system headers). This patch moves the Rdefines.h and Rversion.h outside the extern block. --- Lib/r/rrun.swg | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Lib/r/rrun.swg b/Lib/r/rrun.swg index 823b61ea5..f2c14a574 100644 --- a/Lib/r/rrun.swg +++ b/Lib/r/rrun.swg @@ -1,15 +1,4 @@ -#ifdef __cplusplus -#include -extern "C" { -#endif - -/* for raw pointer */ -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_R_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_R_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_R_NewPointerObj(ptr, type, flags) - - /* Remove global namespace pollution */ #if !defined(SWIG_NO_R_NO_REMAP) # define R_NO_REMAP @@ -20,6 +9,17 @@ extern "C" { #include #include + +#ifdef __cplusplus +#include +extern "C" { +#endif + +/* for raw pointer */ +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_R_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_R_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_R_NewPointerObj(ptr, type, flags) + #include #include From f778ee19dfbcbf9cca4f202a59be6ac6175cd8c6 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 16 Aug 2016 19:39:51 +0100 Subject: [PATCH 14/63] Python builtin hashfunc closure fix If the wrong return type in the hash function was used, an error: SystemError: error return without exception set was raised Add some tests for testing builtin slots --- Examples/test-suite/python/Makefile.in | 1 + .../test-suite/python/python_builtin_runme.py | 26 +++++++ Examples/test-suite/python_builtin.i | 74 +++++++++++++++++++ Lib/python/builtin.swg | 6 +- 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 Examples/test-suite/python/python_builtin_runme.py create mode 100644 Examples/test-suite/python_builtin.i diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index a7993b0b8..bfc5450b0 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -58,6 +58,7 @@ CPP_TEST_CASES += \ primitive_types \ python_abstractbase \ python_append \ + python_builtin \ python_destructor_exception \ python_director \ python_docstring \ diff --git a/Examples/test-suite/python/python_builtin_runme.py b/Examples/test-suite/python/python_builtin_runme.py new file mode 100644 index 000000000..6258534c7 --- /dev/null +++ b/Examples/test-suite/python/python_builtin_runme.py @@ -0,0 +1,26 @@ +from python_builtin import * + +if is_python_builtin(): + # Test 1 for tp_hash + if hash(SimpleValue(222)) != 222: + raise RuntimeError("tp_hash not working") + + # Test 2 for tp_hash + try: + # Was incorrectly raising: SystemError: error return without exception set + h = hash(BadHashFunctionReturnType()) + raise RuntimeError("Missing TypeError") + except TypeError: + pass + + # Test 3 for tp_hash + passed = False + try: + h = hash(ExceptionHashFunction()) + except RuntimeError, e: + passed = str(e).find("oops") != -1 + pass + + if not passed: + raise RuntimeError("did not catch exception in hash()") + diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i new file mode 100644 index 000000000..977b57ec7 --- /dev/null +++ b/Examples/test-suite/python_builtin.i @@ -0,0 +1,74 @@ +// Test customizing slots when using the -builtin option + +%module python_builtin + +%inline %{ +#ifdef SWIGPYTHON_BUILTIN +bool is_python_builtin() { return true; } +#else +bool is_python_builtin() { return false; } +#endif +%} + +// Test 1 for tp_hash +#if defined(SWIGPYTHON_BUILTIN) +%feature("python:tp_hash") SimpleValue "SimpleValueHashFunction" +#endif + +%inline %{ +struct SimpleValue { + int value; + SimpleValue(int value) : value(value) {} + static SimpleValue *inout(SimpleValue *sv) { + return sv; + } +}; +%} + +%{ +#if PY_VERSION_HEX >= 0x03020000 +Py_hash_t SimpleValueHashFunction(PyObject *v) +#else +long SimpleValueHashFunction(PyObject *v) +#endif +{ + SwigPyObject *sobj = (SwigPyObject *) v; + SimpleValue *p = (SimpleValue *)sobj->ptr; + return p->value; +} +hashfunc test_hashfunc_cast() { + return SimpleValueHashFunction; +} +%} + +// Test 2 for tp_hash +#if defined(SWIGPYTHON_BUILTIN) +%feature("python:slot", "tp_hash", functype="hashfunc") BadHashFunctionReturnType::bad_hash_function; +#endif + +%inline %{ +struct BadHashFunctionReturnType { + static const char * bad_hash_function() { + return "bad hash function"; + } +}; +%} + +// Test 3 for tp_hash +#if defined(SWIGPYTHON_BUILTIN) +%feature("python:slot", "tp_hash", functype="hashfunc") ExceptionHashFunction::exception_hash_function; +#endif + +%catches(const char *) exception_hash_function; + +%inline %{ +#if PY_VERSION_HEX < 0x03020000 + #define Py_hash_t long +#endif +struct ExceptionHashFunction { + static Py_hash_t exception_hash_function() { + throw "oops"; + } +}; +%} + diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index 5767a1422..abf5f71cb 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -192,9 +192,11 @@ wrapper##_closure(PyObject *a) { \ PyObject *pyresult; \ long result; \ pyresult = wrapper(a, NULL); \ - if (!pyresult || !PyLong_Check(pyresult)) \ - return -1; \ + if (!pyresult) \ + return -1; \ result = PyLong_AsLong(pyresult); \ + if (PyErr_Occurred()) \ + result = -1; \ Py_DECREF(pyresult); \ return result; \ } From 4f681f751de28a2e74b5a8fb2e5954e8b184cbd9 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 18 Aug 2016 07:09:52 +0100 Subject: [PATCH 15/63] Update Python docs on builtin slots --- Doc/Manual/Contents.html | 4 +- Doc/Manual/Python.html | 130 ++++++++++++++++++++++++++++----------- Lib/python/pyopers.swg | 24 +++++--- 3 files changed, 110 insertions(+), 48 deletions(-) diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 0b456fca7..3f283ecb9 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -310,7 +310,7 @@

  • General-purpose smart pointers
  • Extensible random number facility
  • Wrapper reference -
  • Polymorphous wrappers for function objects +
  • Polymorphic wrappers for function objects
  • Type traits for metaprogramming
  • Uniform method for computing return type of function objects @@ -1529,7 +1529,7 @@
  • Built-in Types
  • Memory management
  • Python 2.2 and classic classes diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index ce7f9fe5a..cf0f86024 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -51,7 +51,7 @@
  • Built-in Types
  • Memory management
  • Python 2.2 and classic classes @@ -2442,7 +2442,7 @@ assert(issubclass(B.Derived, A.Base))
  • -

    36.4.2.2 Operator overloads -- use them!

    +

    36.4.2.2 Operator overloads and slots -- use them!

    The entire justification for the -builtin option is improved @@ -2494,52 +2494,110 @@ automatically converted to python slot operators, refer to the file python/pyopers.swig in the SWIG library.

    -

    There are other very useful python slots that you -may explicitly define using %feature directives. For example, -suppose you want to use instances of a wrapped class as keys in a native python -dict. That will work as long as you define a hash function for -instances of your class, and use it to define the python tp_hash -slot: + +

    +Read about all of the available python slots here: +http://docs.python.org/c-api/typeobj.html

    + +

    +There are two ways to define a python slot function: dispatch to a +statically defined function; or dispatch to a method defined on the +operand. +

    + +

    +To dispatch to a statically defined function, use %feature("python:<slot>"), +where <slot> is the name of a field in a PyTypeObject, PyNumberMethods, +PyMappingMethods, PySequenceMethods or PyBufferProcs. +You may override (almost) all of these slots. +

    + + +

    +Let's consider an example setting the tp_hash slot for the MyClass type. +This is akin to providing a __hash__ method (for non-builtin types) to make a type hashable. +The hashable type can then for example be added to a Python dict.

    -%feature("python:slot", "tp_hash", functype="hashfunc") Cheese::cheeseHashFunc;
    +%feature("python:tp_hash") MyClass "myHashFunc";
     
    -class Cheese {
    +class MyClass {
     public:
    -    Cheese (const char *name);
    -    long cheeseHashFunc () const;
    +  long field1;
    +  long field2;
    +  ...
    +};
    +
    +%{
    +#if PY_VERSION_HEX >= 0x03020000
    +  static Py_hash_t myHashFunc(PyObject *pyobj)
    +#else
    +  static long myHashFunc(PyObject *pyobj)
    +#endif
    +  {
    +    MyClass *cobj;
    +    // Convert pyobj to cobj
    +    return (cobj->field1 * (cobj->field2 << 7));
    +  }
    +%}
    +
    +
    + +

    +If you examine the generated code, the supplied hash function will now be +the function callback in the tp_hash slot for the builtin type for MyClass: +

    + +
    +
    +static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
    +    ...
    +    (hashfunc) myHashFunc,       /* tp_hash */
    +    ...
    +
    +
    + +

    +NOTE: It is the responsibility of the programmer (that's you!) to ensure +that a statically defined slot function has the correct signature, the hashfunc +typedef in this case. +

    + +

    +If, instead, you want to dispatch to an instance method, you can +use %feature("python:slot"). For example: +

    + +
    +
    +%feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc;
    +
    +#if PY_VERSION_HEX < 0x03020000
    +  #define Py_hash_t long
    +#endif
    +
    +class MyClass {
    +  public:
    +    Py_hash_t myHashFunc() const;
    +    ...
     };
     
    -

    This will allow you to write python code like this:

    +

    +NOTE: Some python slots use a method signature which does not +match the signature of SWIG-wrapped methods. For those slots, +SWIG will automatically generate a "closure" function to re-marshal +the arguments before dispatching to the wrapped method. Setting +the "functype" attribute of the feature enables SWIG to generate +the chosen closure function. +

    -
    -
    -from my MyPackage import Cheese
    -
    -inventory = {
    -    Cheese("cheddar") : 0,
    -    Cheese("gouda") : 0,
    -    Cheese("camembert") : 0
    -}
    -
    -
    - -

    Because you defined the tp_hash slot, Cheese objects may -be used as hash keys; and when the cheeseHashFunc method is invoked -by a python dict, it will not go through named method dispatch. -A more detailed discussion about %feature("python:slot") can be found +

    +There is further information on %feature("python:slot") in the file python/pyopers.swig in the SWIG library. -You can read about all of the available python slots here:

    - -

    http://docs.python.org/c-api/typeobj.html

    - -

    You may override (almost) all of the slots defined in the PyTypeObject, -PyNumberMethods, PyMappingMethods, PySequenceMethods, and PyBufferProcs -structs.

    diff --git a/Lib/python/pyopers.swg b/Lib/python/pyopers.swg index 292c593a8..9e3d2a125 100644 --- a/Lib/python/pyopers.swg +++ b/Lib/python/pyopers.swg @@ -19,30 +19,34 @@ PyMappingMethods, PySequenceMethods, or PyBufferProcs. For example: %{ - - static long myHashFunc (PyObject *pyobj) { - MyClass *cobj; - // Convert pyobj to cobj - return (cobj->field1 * (cobj->field2 << 7)); - } - + // Note: Py_hash_t was introduced in Python 3.2 + static Py_hash_t myHashFunc(PyObject *pyobj) { + MyClass *cobj; + // Convert pyobj to cobj + return (cobj->field1 * (cobj->field2 << 7)); + } %} %feature("python:tp_hash") MyClass "myHashFunc"; + class MyClass { + public: + ... + }; + NOTE: It is the responsibility of the programmer (that's you) to ensure that a statically defined slot function has the correct signature. If, instead, you want to dispatch to an instance method, you can use %feature("python:slot"). For example: + %feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc; + class MyClass { public: - long myHashFunc () const; + Py_hash_t myHashFunc () const; ... }; - - %feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc; NOTE: Some python slots use a method signature which does not match the signature of SWIG-wrapped methods. For those slots, From a3fc743f325a7089191004f17e70a65d8cab9fa7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 18 Aug 2016 08:41:07 +0100 Subject: [PATCH 16/63] Add Python builtin closure method in comment For less mystifying code and easier code searching --- Source/Modules/python.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index b42cf022f..82385d4c1 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -3321,7 +3321,7 @@ public: } if (in_class && builtin) { - /* Handle operator overloads overloads for builtin types */ + /* Handle operator overloads for builtin types */ String *slot = Getattr(n, "feature:python:slot"); if (slot) { String *func_type = Getattr(n, "feature:python:slot:functype"); @@ -3329,9 +3329,9 @@ public: String *feature_name = NewStringf("feature:python:%s", slot); String *closure_name = Copy(wrapper_name); if (closure_decl) { - if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling")) - Printv(f_wrappers, closure_decl, "\n\n", NIL); Append(closure_name, "_closure"); + if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling")) + Printf(f_wrappers, "%s /* defines %s */\n\n", closure_decl, closure_name); Delete(closure_decl); } if (func_type) { From 67ece1d2bf4d3e04209f792c272162adfc818d15 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 18 Aug 2016 19:21:39 +0100 Subject: [PATCH 17/63] Python getSlot() refactor getSlot() now takes a default that can override "0" default - simpler code and for future commits to override some currently non-overridable slots. --- Source/Modules/python.cxx | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 82385d4c1..fb71a7299 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -167,10 +167,10 @@ static const char *usage3 = "\ Function annotation \n\ \n"; -static String *getSlot(Node *n = NULL, const char *key = NULL) { - static String *slot_default = NewString("0"); - String *val = key && *key ? Getattr(n, key) : NULL; - return val ? val : slot_default; +static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_slot = NULL) { + static String *zero = NewString("0"); + String *val = n && key && *key ? Getattr(n, key) : NULL; + return val ? val : default_slot ? default_slot : zero; } static void printSlot(File *f, const String *slotval, const char *slotname, const char *functype = NULL) { @@ -3956,13 +3956,7 @@ public: // Check for non-public destructor, in which case tp_dealloc will issue // a warning and allow the memory to leak. Any class that doesn't explicitly // have a private/protected destructor has an implicit public destructor. - String *tp_dealloc = Getattr(n, "feature:python:tp_dealloc"); - if (tp_dealloc) { - Printf(f, "SWIGPY_DESTRUCTOR_CLOSURE(%s)\n", tp_dealloc); - tp_dealloc = NewStringf("%s_closure", tp_dealloc); - } else { - tp_dealloc = NewString("SwigPyBuiltin_BadDealloc"); - } + static String *tp_dealloc_bad = NewString("SwigPyBuiltin_BadDealloc"); String *getset_name = NewStringf("%s_getset", templ); String *methods_name = NewStringf("%s_methods", templ); @@ -4075,7 +4069,7 @@ public: printSlot(f, quoted_symname, "tp_name"); printSlot(f, "sizeof(SwigPyObject)", "tp_basicsize"); printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize"); - printSlot(f, tp_dealloc, "tp_dealloc", "destructor"); + printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor"); printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc"); printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc"); printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc"); @@ -4306,7 +4300,6 @@ public: Delete(mname); Delete(pmname); Delete(templ); - Delete(tp_dealloc); Delete(tp_flags); Delete(py3_tp_flags); Delete(quoted_symname); @@ -4967,12 +4960,10 @@ public: if (builtin && in_class) { Node *cls = Swig_methodclass(n); + // Use the destructor for the tp_dealloc slot unless a user overrides it with another method if (!Getattr(cls, "feature:python:tp_dealloc")) { - String *dealloc = Swig_name_destroy(NSPACE_TODO, symname); - String *wdealloc = Swig_name_wrapper(dealloc); - Setattr(cls, "feature:python:tp_dealloc", wdealloc); - Delete(wdealloc); - Delete(dealloc); + Setattr(n, "feature:python:slot", "tp_dealloc"); + Setattr(n, "feature:python:slot:functype", "destructor"); } } From 4c0c802aa06ea4717c1567a5f0a642fe4e5acf6a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 19 Aug 2016 18:35:51 +0100 Subject: [PATCH 18/63] Add Python builtin tp_dealloc override test --- .../test-suite/python/python_builtin_runme.py | 21 ++++++++++ Examples/test-suite/python_builtin.i | 40 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/Examples/test-suite/python/python_builtin_runme.py b/Examples/test-suite/python/python_builtin_runme.py index 6258534c7..89d2b6b64 100644 --- a/Examples/test-suite/python/python_builtin_runme.py +++ b/Examples/test-suite/python/python_builtin_runme.py @@ -24,3 +24,24 @@ if is_python_builtin(): if not passed: raise RuntimeError("did not catch exception in hash()") + # Test 4 for tp_dealloc (which is handled differently to other slots in the SWIG source) + d = Dealloc1() + if cvar.Dealloc1CalledCount != 0: + raise RuntimeError("count should be 0") + del d + if cvar.Dealloc1CalledCount != 1: + raise RuntimeError("count should be 1") + + d = Dealloc2() + if cvar.Dealloc2CalledCount != 0: + raise RuntimeError("count should be 0") + del d + if cvar.Dealloc2CalledCount != 1: + raise RuntimeError("count should be 1") + + d = Dealloc3() + if cvar.Dealloc3CalledCount != 0: + raise RuntimeError("count should be 0") + del d + if cvar.Dealloc3CalledCount != 1: + raise RuntimeError("count should be 1") diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i index 977b57ec7..db4c94a52 100644 --- a/Examples/test-suite/python_builtin.i +++ b/Examples/test-suite/python_builtin.i @@ -72,3 +72,43 @@ struct ExceptionHashFunction { }; %} +// Test 4 for tp_dealloc (which is handled differently to other slots in the SWIG source) +#if defined(SWIGPYTHON_BUILTIN) +%feature("python:tp_dealloc") Dealloc1 "Dealloc1Destroyer" +%feature("python:tp_dealloc") Dealloc2 "Dealloc2Destroyer" +%feature("python:slot", "tp_dealloc", functype="destructor") Dealloc3::Destroyer; +#endif + +%inline %{ +static int Dealloc1CalledCount = 0; +static int Dealloc2CalledCount = 0; +static int Dealloc3CalledCount = 0; + +struct Dealloc1 { +}; +struct Dealloc2 { + ~Dealloc2() {} +}; +struct Dealloc3 { + void Destroyer() { + Dealloc3CalledCount++; + delete this; + } +}; +%} + +%{ +void Dealloc1Destroyer(PyObject *v) { + SwigPyObject *sobj = (SwigPyObject *) v; + Dealloc1 *p = (Dealloc1 *)sobj->ptr; + delete p; + Dealloc1CalledCount++; +} +void Dealloc2Destroyer(PyObject *v) { + SwigPyObject *sobj = (SwigPyObject *) v; + Dealloc2 *p = (Dealloc2 *)sobj->ptr; + delete p; + Dealloc2CalledCount++; +} +%} + From 239785ce7d2153383ac72e5f754f357b7e649ea1 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 19 Aug 2016 19:47:09 +0100 Subject: [PATCH 19/63] Additional Python builtin slot overrides and slightly better formatted Python generated code The following slots can now be overidden by users if they know what they are doing: - tp_dictoffset - tp_init - tp_new - tp_as_number - tp_as_sequence - tp_as_mapping - tp_as_buffer --- Source/Modules/python.cxx | 41 +++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index fb71a7299..81a534e7c 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -173,13 +173,13 @@ static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_s return val ? val : default_slot ? default_slot : zero; } -static void printSlot(File *f, const String *slotval, const char *slotname, const char *functype = NULL) { - String *slotval_override = functype ? NewStringf("(%s) %s", functype, slotval) : 0; - if (slotval_override) - slotval = slotval_override; +static void printSlot(File *f, String *slotval, const char *slotname, const char *functype = NULL) { + String *slotval_override = 0; + if (functype) + slotval = slotval_override = NewStringf("(%s) %s", functype, slotval); int len = Len(slotval); - int fieldwidth = len > 40 ? 0 : 40 - len; - Printf(f, " %s, %*s/* %s */\n", slotval, fieldwidth, "", slotname); + int fieldwidth = len > 41 ? (len > 61 ? 0 : 61 - len) : 41 - len; + Printf(f, " %s,%*s/* %s */\n", slotval, fieldwidth, "", slotname); Delete(slotval_override); } @@ -4051,10 +4051,16 @@ public: quoted_symname = NewStringf("\"%s\"", symname); } String *quoted_tp_doc_str = NewStringf("\"%s\"", getSlot(n, "feature:python:tp_doc")); - char const *tp_init = builtin_tp_init ? Char(builtin_tp_init) : Swig_directorclass(n) ? "0" : "SwigPyBuiltin_BadInit"; + String *tp_init = NewString(builtin_tp_init ? Char(builtin_tp_init) : Swig_directorclass(n) ? "0" : "SwigPyBuiltin_BadInit"); String *tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES"); String *py3_tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"); + static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)"); + static String *tp_dictoffset_default = NewString("(Py_ssize_t)offsetof(SwigPyObject, dict)"); + String *tp_as_number = NewStringf("&%s_type.as_number", templ); + String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ); + String *tp_as_mapping = NewStringf("&%s_type.as_mapping", templ); + String *tp_as_buffer = NewStringf("&%s_type.as_buffer", templ); Printf(f, "static PyHeapTypeObject %s_type = {\n", templ); @@ -4067,7 +4073,7 @@ public: printSlot(f, getSlot(), "ob_size"); Printv(f, "#endif\n", NIL); printSlot(f, quoted_symname, "tp_name"); - printSlot(f, "sizeof(SwigPyObject)", "tp_basicsize"); + printSlot(f, tp_basicsize, "tp_basicsize"); printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize"); printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor"); printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc"); @@ -4079,15 +4085,15 @@ public: printSlot(f, getSlot(n, "feature:python:tp_compare"), "tp_compare", "cmpfunc"); Printv(f, "#endif\n", NIL); printSlot(f, getSlot(n, "feature:python:tp_repr"), "tp_repr", "reprfunc"); - Printf(f, " &%s_type.as_number, /* tp_as_number */\n", templ); - Printf(f, " &%s_type.as_sequence, /* tp_as_sequence */\n", templ); - Printf(f, " &%s_type.as_mapping, /* tp_as_mapping */\n", templ); + printSlot(f, getSlot(n, "feature:python:tp_as_number", tp_as_number), "tp_as_number"); + printSlot(f, getSlot(n, "feature:python:tp_as_sequence", tp_as_sequence), "tp_as_sequence"); + printSlot(f, getSlot(n, "feature:python:tp_as_mapping", tp_as_mapping), "tp_as_mapping"); printSlot(f, getSlot(n, "feature:python:tp_hash"), "tp_hash", "hashfunc"); printSlot(f, getSlot(n, "feature:python:tp_call"), "tp_call", "ternaryfunc"); printSlot(f, getSlot(n, "feature:python:tp_str"), "tp_str", "reprfunc"); printSlot(f, getSlot(n, "feature:python:tp_getattro"), "tp_getattro", "getattrofunc"); printSlot(f, getSlot(n, "feature:python:tp_setattro"), "tp_setattro", "setattrofunc"); - Printf(f, " &%s_type.as_buffer, /* tp_as_buffer */\n", templ); + printSlot(f, getSlot(n, "feature:python:tp_as_buffer", tp_as_buffer), "tp_as_buffer"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); printSlot(f, py3_tp_flags, "tp_flags"); Printv(f, "#else\n", NIL); @@ -4107,10 +4113,10 @@ public: printSlot(f, getSlot(n, "feature:python:tp_dict"), "tp_dict"); printSlot(f, getSlot(n, "feature:python:tp_descr_get"), "tp_descr_get", "descrgetfunc"); printSlot(f, getSlot(n, "feature:python:tp_descr_set"), "tp_descr_set", "descrsetfunc"); - Printf(f, " (Py_ssize_t)offsetof(SwigPyObject, dict), /* tp_dictoffset */\n"); - printSlot(f, tp_init, "tp_init", "initproc"); + printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset"); + printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc"); printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc"); - printSlot(f, "0", "tp_new", "newfunc"); + printSlot(f, getSlot(n, "feature:python:tp_new"), "tp_new", "newfunc"); printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc"); printSlot(f, getSlot(), "tp_is_gc", "inquiry"); printSlot(f, getSlot(), "tp_bases", "PyObject*"); @@ -4302,8 +4308,13 @@ public: Delete(templ); Delete(tp_flags); Delete(py3_tp_flags); + Delete(tp_as_buffer); + Delete(tp_as_mapping); + Delete(tp_as_sequence); + Delete(tp_as_number); Delete(quoted_symname); Delete(quoted_tp_doc_str); + Delete(tp_init); Delete(clientdata_klass); Delete(richcompare_func); Delete(getset_name); From 3744c45082dec123b96c0559d50569ef5be7efa7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 19 Aug 2016 23:46:50 +0100 Subject: [PATCH 20/63] Customize slots tp_basicsize tp_methods tp_getset --- Source/Modules/python.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 81a534e7c..d86931673 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4073,7 +4073,7 @@ public: printSlot(f, getSlot(), "ob_size"); Printv(f, "#endif\n", NIL); printSlot(f, quoted_symname, "tp_name"); - printSlot(f, tp_basicsize, "tp_basicsize"); + printSlot(f, getSlot(n, "feature:python:tp_basicsize", tp_basicsize), "tp_basicsize"); printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize"); printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor"); printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc"); @@ -4106,9 +4106,9 @@ public: printSlot(f, getSlot(n, "feature:python:tp_weaklistoffset"), "tp_weaklistoffset"); printSlot(f, getSlot(n, "feature:python:tp_iter"), "tp_iter", "getiterfunc"); printSlot(f, getSlot(n, "feature:python:tp_iternext"), "tp_iternext", "iternextfunc"); - printSlot(f, methods_name, "tp_methods"); + printSlot(f, getSlot(n, "feature:python:tp_methods", methods_name), "tp_methods"); printSlot(f, getSlot(n, "feature:python:tp_members"), "tp_members"); - printSlot(f, getset_name, "tp_getset"); + printSlot(f, getSlot(n, "feature:python:tp_getset", getset_name), "tp_getset"); printSlot(f, getSlot(n, "feature:python:tp_base"), "tp_base"); printSlot(f, getSlot(n, "feature:python:tp_dict"), "tp_dict"); printSlot(f, getSlot(n, "feature:python:tp_descr_get"), "tp_descr_get", "descrgetfunc"); From 3b6f4af15cd65b47900a267bf99617bd69ed439c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 21 Aug 2016 14:29:27 +0100 Subject: [PATCH 21/63] Set tp_new statically rather than during initialisation --- Source/Modules/python.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index d86931673..31889a83c 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -3919,7 +3919,6 @@ public: int funpack = modernargs && fastunpack; Printv(f_init, " SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL); - Printf(f_init, " builtin_pytype->tp_new = PyType_GenericNew;\n"); Printv(f_init, " builtin_base_count = 0;\n", NIL); List *baselist = Getattr(n, "bases"); if (baselist) { @@ -4057,6 +4056,7 @@ public: static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)"); static String *tp_dictoffset_default = NewString("(Py_ssize_t)offsetof(SwigPyObject, dict)"); + static String *tp_new = NewString("PyType_GenericNew"); String *tp_as_number = NewStringf("&%s_type.as_number", templ); String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ); String *tp_as_mapping = NewStringf("&%s_type.as_mapping", templ); @@ -4102,7 +4102,7 @@ public: printSlot(f, quoted_tp_doc_str, "tp_doc"); printSlot(f, getSlot(n, "feature:python:tp_traverse"), "tp_traverse", "traverseproc"); printSlot(f, getSlot(n, "feature:python:tp_clear"), "tp_clear", "inquiry"); - printSlot(f, richcompare_func, "feature:python:tp_richcompare", "richcmpfunc"); + printSlot(f, getSlot(n, "feature:python:tp_richcompare", richcompare_func), "tp_richcompare", "richcmpfunc"); printSlot(f, getSlot(n, "feature:python:tp_weaklistoffset"), "tp_weaklistoffset"); printSlot(f, getSlot(n, "feature:python:tp_iter"), "tp_iter", "getiterfunc"); printSlot(f, getSlot(n, "feature:python:tp_iternext"), "tp_iternext", "iternextfunc"); @@ -4116,7 +4116,7 @@ public: printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset"); printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc"); printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc"); - printSlot(f, getSlot(n, "feature:python:tp_new"), "tp_new", "newfunc"); + printSlot(f, getSlot(n, "feature:python:tp_new", tp_new), "tp_new", "newfunc"); printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc"); printSlot(f, getSlot(), "tp_is_gc", "inquiry"); printSlot(f, getSlot(), "tp_bases", "PyObject*"); From 4f777b181cc7be7bb88d438bc308c2815615b914 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 22 Aug 2016 07:22:40 +0100 Subject: [PATCH 22/63] Correct notes on customising Python builtin comparison operators Also add example for python:compare feature --- .../test-suite/python/python_builtin_runme.py | 23 +++++++++++++++++ Examples/test-suite/python_builtin.i | 16 ++++++++++++ Lib/python/pyopers.swg | 25 ++++++++++--------- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/Examples/test-suite/python/python_builtin_runme.py b/Examples/test-suite/python/python_builtin_runme.py index 89d2b6b64..c41dfc0b1 100644 --- a/Examples/test-suite/python/python_builtin_runme.py +++ b/Examples/test-suite/python/python_builtin_runme.py @@ -45,3 +45,26 @@ if is_python_builtin(): del d if cvar.Dealloc3CalledCount != 1: raise RuntimeError("count should be 1") + + # Test 5 for python:compare feature + m10 = MyClass(10) + m20 = MyClass(20) + m15 = MyClass(15) + + if not m10 < m15: + raise RuntimeError("m10 < m15") + if not m10 < m20: + raise RuntimeError("m10 < m20") + if not m15 < m20: + raise RuntimeError("m15 < m20") + + if m10 > m15: + raise RuntimeError("m10 > m15") + if m10 > m20: + raise RuntimeError("m10 > m20") + if m15 > m20: + raise RuntimeError("m15 > m20") + + if MyClass.less_than_counts != 6: + raise RuntimeError("python:compare feature not working") + diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i index db4c94a52..ac1ad9c2d 100644 --- a/Examples/test-suite/python_builtin.i +++ b/Examples/test-suite/python_builtin.i @@ -112,3 +112,19 @@ void Dealloc2Destroyer(PyObject *v) { } %} +// Test 5 for python:compare feature +%feature("python:compare", "Py_LT") MyClass::lessThan; + +%inline %{ + class MyClass { + public: + MyClass(int val = 0) : val(val) {} + bool lessThan(const MyClass& other) const { + less_than_counts++; + return val < other.val; + } + int val; + static int less_than_counts; + }; + int MyClass::less_than_counts = 0; +%} diff --git a/Lib/python/pyopers.swg b/Lib/python/pyopers.swg index 9e3d2a125..5fb22354b 100644 --- a/Lib/python/pyopers.swg +++ b/Lib/python/pyopers.swg @@ -18,6 +18,13 @@ where is the name of a field in a PyTypeObject, PyNumberMethods, PyMappingMethods, PySequenceMethods, or PyBufferProcs. For example: + %feature("python:tp_hash") MyClass "myHashFunc"; + + class MyClass { + public: + ... + }; + %{ // Note: Py_hash_t was introduced in Python 3.2 static Py_hash_t myHashFunc(PyObject *pyobj) { @@ -27,13 +34,6 @@ } %} - %feature("python:tp_hash") MyClass "myHashFunc"; - - class MyClass { - public: - ... - }; - NOTE: It is the responsibility of the programmer (that's you) to ensure that a statically defined slot function has the correct signature. @@ -62,20 +62,21 @@ operator overloads for comparison (operator==, operator<, etc.), they will be called from the generated rich compare function. If you want to explicitly choose a method to handle a certain comparison - operation, you may use %feature("python:slot") like this: + operation, you may use a different feature, %feature("python:compare") + like this: + + %feature("python:compare", "Py_LT") MyClass::lessThan; class MyClass { public: - bool lessThan (const MyClass& x) const; + bool lessThan(const MyClass& other) const; ... }; - %feature("python:slot", "Py_LT") MyClass::lessThan; - ... where "Py_LT" is one of the rich comparison opcodes defined in the python header file object.h. - If there's no method defined to handle a particular comparsion operation, + If there's no method defined to handle a particular comparison operation, the default behavior is to compare pointer values of the wrapped C++ objects. From e5a09c4141b5a055438a2682449a3af1ad478453 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 22 Aug 2016 07:51:42 +0100 Subject: [PATCH 23/63] Add additional Python builtin slots as features for user customization Added: - tp_is_gc - tp_bases - tp_mro - tp_cache - tp_subclasses - tp_weaklist - tp_del - tp_allocs - tp_frees - tp_maxalloc - tp_prev - tp_next --- Source/Modules/python.cxx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 31889a83c..6f1582619 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4118,13 +4118,13 @@ public: printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc"); printSlot(f, getSlot(n, "feature:python:tp_new", tp_new), "tp_new", "newfunc"); printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc"); - printSlot(f, getSlot(), "tp_is_gc", "inquiry"); - printSlot(f, getSlot(), "tp_bases", "PyObject*"); - printSlot(f, getSlot(), "tp_mro", "PyObject*"); - printSlot(f, getSlot(), "tp_cache", "PyObject*"); - printSlot(f, getSlot(), "tp_subclasses", "PyObject*"); - printSlot(f, getSlot(), "tp_weaklist", "PyObject*"); - printSlot(f, getSlot(), "tp_del", "destructor"); + printSlot(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry"); + printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:tp_mro"), "tp_mro", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:tp_cache"), "tp_cache", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:tp_subclasses"), "tp_subclasses", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:tp_weaklist"), "tp_weaklist", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:tp_del"), "tp_del", "destructor"); Printv(f, "#if PY_VERSION_HEX >= 0x02060000\n", NIL); printSlot(f, getSlot(n, "feature:python:tp_version_tag"), "tp_version_tag", "int"); Printv(f, "#endif\n", NIL); @@ -4132,13 +4132,13 @@ public: printSlot(f, getSlot(n, "feature:python:tp_finalize"), "tp_finalize", "destructor"); Printv(f, "#endif\n", NIL); Printv(f, "#ifdef COUNT_ALLOCS\n", NIL); - printSlot(f, getSlot(), "tp_allocs", "Py_ssize_t"); - printSlot(f, getSlot(), "tp_frees", "Py_ssize_t"); - printSlot(f, getSlot(), "tp_maxalloc", "Py_ssize_t"); + printSlot(f, getSlot(n, "feature:python:tp_allocs"), "tp_allocs", "Py_ssize_t"); + printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t"); + printSlot(f, getSlot(n, "feature:python:tp_maxalloc"), "tp_maxalloc", "Py_ssize_t"); Printv(f, "#if PY_VERSION_HEX >= 0x02050000\n", NIL); - printSlot(f, getSlot(), "tp_prev", "struct _typeobject*"); + printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev", "struct _typeobject*"); Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(), "tp_next", "struct _typeobject*"); + printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next", "struct _typeobject*"); Printv(f, "#endif\n", NIL); Printf(f, " },\n"); From bf4174d121bd4b51747d9114ac86568be2f30595 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 22 Aug 2016 08:39:24 +0100 Subject: [PATCH 24/63] Further additional Python builtin slots as features for user customization Added: - tp_flags - was_sq_slice - was_sq_ass_slice --- Source/Modules/python.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 6f1582619..8ac721404 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4052,7 +4052,7 @@ public: String *quoted_tp_doc_str = NewStringf("\"%s\"", getSlot(n, "feature:python:tp_doc")); String *tp_init = NewString(builtin_tp_init ? Char(builtin_tp_init) : Swig_directorclass(n) ? "0" : "SwigPyBuiltin_BadInit"); String *tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES"); - String *py3_tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"); + String *tp_flags_py3 = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"); static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)"); static String *tp_dictoffset_default = NewString("(Py_ssize_t)offsetof(SwigPyObject, dict)"); @@ -4095,9 +4095,9 @@ public: printSlot(f, getSlot(n, "feature:python:tp_setattro"), "tp_setattro", "setattrofunc"); printSlot(f, getSlot(n, "feature:python:tp_as_buffer", tp_as_buffer), "tp_as_buffer"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, py3_tp_flags, "tp_flags"); + printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags_py3), "tp_flags"); Printv(f, "#else\n", NIL); - printSlot(f, tp_flags, "tp_flags"); + printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags), "tp_flags"); Printv(f, "#endif\n", NIL); printSlot(f, quoted_tp_doc_str, "tp_doc"); printSlot(f, getSlot(n, "feature:python:tp_traverse"), "tp_traverse", "traverseproc"); @@ -4226,13 +4226,13 @@ public: printSlot(f, getSlot(n, "feature:python:sq_repeat"), "sq_repeat", "ssizeargfunc"); printSlot(f, getSlot(n, "feature:python:sq_item"), "sq_item", "ssizeargfunc"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:was_sq_slice"), "was_sq_slice", "void*"); + printSlot(f, getSlot(n, "feature:python:was_sq_slice"), "was_sq_slice", "void*"); Printv(f, "#else\n", NIL); printSlot(f, getSlot(n, "feature:python:sq_slice"), "sq_slice", "ssizessizeargfunc"); Printv(f, "#endif\n", NIL); printSlot(f, getSlot(n, "feature:python:sq_ass_item"), "sq_ass_item", "ssizeobjargproc"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:was_sq_ass_slice"), "was_sq_ass_slice", "void*"); + printSlot(f, getSlot(n, "feature:python:was_sq_ass_slice"), "was_sq_ass_slice", "void*"); Printv(f, "#else\n", NIL); printSlot(f, getSlot(n, "feature:python:sq_ass_slice"), "sq_ass_slice", "ssizessizeobjargproc"); Printv(f, "#endif\n", NIL); @@ -4307,7 +4307,7 @@ public: Delete(pmname); Delete(templ); Delete(tp_flags); - Delete(py3_tp_flags); + Delete(tp_flags_py3); Delete(tp_as_buffer); Delete(tp_as_mapping); Delete(tp_as_sequence); From ad452edf3eaeee426dc45a431a1a4217e46de64a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 22 Aug 2016 08:48:04 +0100 Subject: [PATCH 25/63] Cosmetic code formatting corrections --- Source/Modules/python.cxx | 86 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 8ac721404..72da66f66 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -2037,7 +2037,7 @@ public: // Disregard optional "f" suffix, it can be just dropped in Python as it // uses doubles for everything anyhow. - for (char* p = end; *p != '\0'; ++p) { + for (char * p = end; *p != '\0'; ++p) { switch (*p) { case 'f': case 'F': @@ -2083,7 +2083,7 @@ public: // combination of "l" and "u", but not anything else (again, stuff like // "LL" could be handled, but we don't bother to do it currently). bool seen_long = false; - for (char* p = end; *p != '\0'; ++p) { + for (char * p = end; *p != '\0'; ++p) { switch (*p) { case 'l': case 'L': @@ -3392,7 +3392,7 @@ public: Python dictionary. */ if (!have_globals) { - Printf(f_init, "\t PyDict_SetItemString(md,(char*)\"%s\", SWIG_globals());\n", global_name); + Printf(f_init, "\t PyDict_SetItemString(md,(char *)\"%s\", SWIG_globals());\n", global_name); if (builtin) Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name); have_globals = 1; @@ -3480,9 +3480,9 @@ public: Wrapper_print(getf, f_wrappers); /* Now add this to the variable linking mechanism */ - Printf(f_init, "\t SWIG_addvarlink(SWIG_globals(),(char*)\"%s\",%s, %s);\n", iname, vargetname, varsetname); + Printf(f_init, "\t SWIG_addvarlink(SWIG_globals(),(char *)\"%s\",%s, %s);\n", iname, vargetname, varsetname); if (builtin && shadow && !assignable && !in_class) { - Printf(f_init, "\t PyDict_SetItemString(md, (char*)\"%s\", PyObject_GetAttrString(SWIG_globals(), \"%s\"));\n", iname, iname); + Printf(f_init, "\t PyDict_SetItemString(md, (char *)\"%s\", PyObject_GetAttrString(SWIG_globals(), \"%s\"));\n", iname, iname); Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", iname); } Delete(vargetname); @@ -3499,7 +3499,7 @@ public: * ------------------------------------------------------------ */ /* Determine if the node requires the _swigconstant code to be generated */ - bool needs_swigconstant(Node* n) { + bool needs_swigconstant(Node *n) { SwigType *type = Getattr(n, "type"); SwigType *qtype = SwigType_typedef_resolve_all(type); SwigType *uqtype = SwigType_strip_qualifiers(qtype); @@ -3576,12 +3576,12 @@ public: Printf(f_wrappers, tab2 "PyObject *d;\n"); if (modernargs) { if (fastunpack) { - Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args,(char*)\"swigconstant\", 1, 1,&module)) return NULL;\n"); + Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args,(char *)\"swigconstant\", 1, 1,&module)) return NULL;\n"); } else { - Printf(f_wrappers, tab2 "if (!PyArg_UnpackTuple(args,(char*)\"swigconstant\", 1, 1,&module)) return NULL;\n"); + Printf(f_wrappers, tab2 "if (!PyArg_UnpackTuple(args,(char *)\"swigconstant\", 1, 1,&module)) return NULL;\n"); } } else { - Printf(f_wrappers, tab2 "if (!PyArg_ParseTuple(args,(char*)\"O:swigconstant\", &module)) return NULL;\n"); + Printf(f_wrappers, tab2 "if (!PyArg_ParseTuple(args,(char *)\"O:swigconstant\", &module)) return NULL;\n"); } Printf(f_wrappers, tab2 "d = PyModule_GetDict(module);\n"); Printf(f_wrappers, tab2 "if (!d) return NULL;\n"); @@ -3737,13 +3737,13 @@ public: Node *parent = Swig_methodclass(n); String *basetype = Getattr(parent, "classtype"); Wrapper *w = NewWrapper(); - Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject* self) : Swig::Director(self) { \n", classname, classname); + Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject *self) : Swig::Director(self) { \n", classname, classname); Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype); Append(w->def, "}\n"); Wrapper_print(w, f_directors); DelWrapper(w); } - Printf(f_directors_h, " SwigDirector_%s(PyObject* self);\n", classname); + Printf(f_directors_h, " SwigDirector_%s(PyObject *self);\n", classname); Delete(classname); return Language::classDirectorDefaultConstructor(n); } @@ -3932,8 +3932,8 @@ public: SwigType_add_pointer(base_name); String *base_mname = SwigType_manglestr(base_name); Printf(f_init, " builtin_basetype = SWIG_MangledTypeQuery(\"%s\");\n", base_mname); - Printv(f_init, " if (builtin_basetype && builtin_basetype->clientdata && ((SwigPyClientData*) builtin_basetype->clientdata)->pytype) {\n", NIL); - Printv(f_init, " builtin_bases[builtin_base_count++] = ((SwigPyClientData*) builtin_basetype->clientdata)->pytype;\n", NIL); + Printv(f_init, " if (builtin_basetype && builtin_basetype->clientdata && ((SwigPyClientData *) builtin_basetype->clientdata)->pytype) {\n", NIL); + Printv(f_init, " builtin_bases[builtin_base_count++] = ((SwigPyClientData *) builtin_basetype->clientdata)->pytype;\n", NIL); Printv(f_init, " } else {\n", NIL); Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s' as base '%s' has not been initialized.\\n\");\n", symname, bname); Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); @@ -3977,12 +3977,12 @@ public: String *gspair = NewStringf("%s_%s_getset", symname, memname); Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0"); String *entry = - NewStringf("{ (char*) \"%s\", (getter) %s, (setter) %s, (char*)\"%s.%s\", (void*) &%s }\n", memname, getter_closure, + NewStringf("{ (char *) \"%s\", (getter) %s, (setter) %s, (char *)\"%s.%s\", (void *) &%s }\n", memname, getter_closure, setter_closure, name, memname, gspair); if (GetFlag(mgetset, "static")) { Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry); Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair); - Printf(f_init, "PyDict_SetItemString(d, static_getset->d_getset->name, (PyObject*) static_getset);\n", memname); + Printf(f_init, "PyDict_SetItemString(d, static_getset->d_getset->name, (PyObject *) static_getset);\n", memname); Printf(f_init, "Py_DECREF(static_getset);\n"); } else { Printf(getset_def, " %s,\n", entry); @@ -4119,11 +4119,11 @@ public: printSlot(f, getSlot(n, "feature:python:tp_new", tp_new), "tp_new", "newfunc"); printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc"); printSlot(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry"); - printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject*"); - printSlot(f, getSlot(n, "feature:python:tp_mro"), "tp_mro", "PyObject*"); - printSlot(f, getSlot(n, "feature:python:tp_cache"), "tp_cache", "PyObject*"); - printSlot(f, getSlot(n, "feature:python:tp_subclasses"), "tp_subclasses", "PyObject*"); - printSlot(f, getSlot(n, "feature:python:tp_weaklist"), "tp_weaklist", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject *"); + printSlot(f, getSlot(n, "feature:python:tp_mro"), "tp_mro", "PyObject *"); + printSlot(f, getSlot(n, "feature:python:tp_cache"), "tp_cache", "PyObject *"); + printSlot(f, getSlot(n, "feature:python:tp_subclasses"), "tp_subclasses", "PyObject *"); + printSlot(f, getSlot(n, "feature:python:tp_weaklist"), "tp_weaklist", "PyObject *"); printSlot(f, getSlot(n, "feature:python:tp_del"), "tp_del", "destructor"); Printv(f, "#if PY_VERSION_HEX >= 0x02060000\n", NIL); printSlot(f, getSlot(n, "feature:python:tp_version_tag"), "tp_version_tag", "int"); @@ -4136,9 +4136,9 @@ public: printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t"); printSlot(f, getSlot(n, "feature:python:tp_maxalloc"), "tp_maxalloc", "Py_ssize_t"); Printv(f, "#if PY_VERSION_HEX >= 0x02050000\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev", "struct _typeobject*"); + printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev", "struct _typeobject *"); Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next", "struct _typeobject*"); + printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next", "struct _typeobject *"); Printv(f, "#endif\n", NIL); Printf(f, " },\n"); @@ -4177,7 +4177,7 @@ public: Printv(f, "#endif\n", NIL); printSlot(f, getSlot(n, "feature:python:nb_int"), "nb_int", "unaryfunc"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_reserved"), "nb_reserved", "void*"); + printSlot(f, getSlot(n, "feature:python:nb_reserved"), "nb_reserved", "void *"); Printv(f, "#else\n", NIL); printSlot(f, getSlot(n, "feature:python:nb_long"), "nb_long", "unaryfunc"); Printv(f, "#endif\n", NIL); @@ -4226,13 +4226,13 @@ public: printSlot(f, getSlot(n, "feature:python:sq_repeat"), "sq_repeat", "ssizeargfunc"); printSlot(f, getSlot(n, "feature:python:sq_item"), "sq_item", "ssizeargfunc"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:was_sq_slice"), "was_sq_slice", "void*"); + printSlot(f, getSlot(n, "feature:python:was_sq_slice"), "was_sq_slice", "void *"); Printv(f, "#else\n", NIL); printSlot(f, getSlot(n, "feature:python:sq_slice"), "sq_slice", "ssizessizeargfunc"); Printv(f, "#endif\n", NIL); printSlot(f, getSlot(n, "feature:python:sq_ass_item"), "sq_ass_item", "ssizeobjargproc"); Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:was_sq_ass_slice"), "was_sq_ass_slice", "void*"); + printSlot(f, getSlot(n, "feature:python:was_sq_ass_slice"), "was_sq_ass_slice", "void *"); Printv(f, "#else\n", NIL); printSlot(f, getSlot(n, "feature:python:sq_ass_slice"), "sq_ass_slice", "ssizessizeobjargproc"); Printv(f, "#endif\n", NIL); @@ -4256,13 +4256,13 @@ public: Printf(f, " },\n"); // PyObject *ht_name, *ht_slots, *ht_qualname; - printSlot(f, getSlot(n, "feature:python:ht_name"), "ht_name", "PyObject*"); - printSlot(f, getSlot(n, "feature:python:ht_slots"), "ht_slots", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:ht_name"), "ht_name", "PyObject *"); + printSlot(f, getSlot(n, "feature:python:ht_slots"), "ht_slots", "PyObject *"); Printv(f, "#if PY_VERSION_HEX >= 0x03030000\n", NIL); - printSlot(f, getSlot(n, "feature:python:ht_qualname"), "ht_qualname", "PyObject*"); + printSlot(f, getSlot(n, "feature:python:ht_qualname"), "ht_qualname", "PyObject *"); // struct _dictkeysobject *ht_cached_keys; - printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys", "struct _dictkeysobject*"); + printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys", "struct _dictkeysobject *"); Printv(f, "#endif\n", NIL); Printf(f, "};\n\n"); @@ -4281,7 +4281,7 @@ public: String *clientdata_klass = NewString("0"); if (GetFlag(n, "feature:implicitconv")) { Clear(clientdata_klass); - Printf(clientdata_klass, "(PyObject*) &%s_type", templ); + Printf(clientdata_klass, "(PyObject *) &%s_type", templ); } Printf(f, "SWIGINTERN SwigPyClientData %s_clientdata = {%s, 0, 0, 0, 0, 0, (PyTypeObject *)&%s_type};\n\n", templ, clientdata_klass, templ); @@ -4295,7 +4295,7 @@ public: Printv(f_init, "#endif\n", NIL); Printv(f_init, " }\n", NIL); Printv(f_init, " Py_INCREF(builtin_pytype);\n", NIL); - Printf(f_init, " PyModule_AddObject(m, \"%s\", (PyObject*) builtin_pytype);\n", symname); + Printf(f_init, " PyModule_AddObject(m, \"%s\", (PyObject *)builtin_pytype);\n", symname); Printf(f_init, " SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", symname); Printv(f_init, " d = md;\n", NIL); @@ -4487,7 +4487,7 @@ public: SwigType_add_pointer(p_real_classname); String *mangle = SwigType_manglestr(p_real_classname); String *descriptor = NewStringf("SWIGTYPE%s", mangle); - Printv(none_comparison, "self->ob_type != ((SwigPyClientData*) (", descriptor, ")->clientdata)->pytype", NIL); + Printv(none_comparison, "self->ob_type != ((SwigPyClientData *)(", descriptor, ")->clientdata)->pytype", NIL); Delete(descriptor); Delete(mangle); Delete(p_real_classname); @@ -4514,12 +4514,12 @@ public: Printv(f_wrappers, " PyObject *obj;\n", NIL); if (modernargs) { if (fastunpack) { - Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args,(char*)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL); + Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args,(char *)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL); } else { - Printv(f_wrappers, " if (!PyArg_UnpackTuple(args,(char*)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL); + Printv(f_wrappers, " if (!PyArg_UnpackTuple(args,(char *)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL); } } else { - Printv(f_wrappers, " if (!PyArg_ParseTuple(args,(char*)\"O:swigregister\", &obj)) return NULL;\n", NIL); + Printv(f_wrappers, " if (!PyArg_ParseTuple(args,(char *)\"O:swigregister\", &obj)) return NULL;\n", NIL); } Printv(f_wrappers, @@ -4662,13 +4662,13 @@ public: int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2; String *ds = have_docstring(n) ? cdocstring(n, AUTODOC_FUNC) : NewString(""); if (check_kwargs(n)) { - Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS|METH_KEYWORDS, (char*) \"%s\" },\n", symname, wname, ds); + Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS|METH_KEYWORDS, (char *) \"%s\" },\n", symname, wname, ds); } else if (argcount == 0) { - Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_NOARGS, (char*) \"%s\" },\n", symname, wname, ds); + Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_NOARGS, (char *) \"%s\" },\n", symname, wname, ds); } else if (argcount == 1) { - Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_O, (char*) \"%s\" },\n", symname, wname, ds); + Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_O, (char *) \"%s\" },\n", symname, wname, ds); } else { - Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS, (char*) \"%s\" },\n", symname, wname, ds); + Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS, (char *) \"%s\" },\n", symname, wname, ds); } Delete(fullname); Delete(wname); @@ -4769,7 +4769,7 @@ public: Append(pyflags, "METH_VARARGS"); if (have_docstring(n)) { String *ds = cdocstring(n, AUTODOC_STATICFUNC); - Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, %s, (char*) \"%s\" },\n", symname, wname, pyflags, ds); + Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, %s, (char *) \"%s\" },\n", symname, wname, pyflags, ds); Delete(ds); } else { Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, %s, \"\" },\n", symname, wname, pyflags); @@ -5554,9 +5554,9 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { Append(w->code, "}\n"); Append(w->code, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n"); Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++); - Printf(w->code, "const char * const swig_method_name = \"%s\";\n", pyname); + Printf(w->code, "const char *const swig_method_name = \"%s\";\n", pyname); - Append(w->code, "PyObject* method = swig_get_method(swig_method_index, swig_method_name);\n"); + Append(w->code, "PyObject *method = swig_get_method(swig_method_index, swig_method_name);\n"); if (Len(parse_args) > 0) { if (use_parse || !modernargs) { Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", Swig_cresult_name(), parse_args, arglist); @@ -5566,7 +5566,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { } else { if (modernargs) { Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n"); - Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject*) args, NULL);\n", Swig_cresult_name()); + Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject *) args, NULL);\n", Swig_cresult_name()); } else { Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, NULL, NULL);\n", Swig_cresult_name()); } From ae32fb4f9acba9d285ca6c98bd4492a337e52f1d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 22 Aug 2016 19:27:39 +0100 Subject: [PATCH 26/63] Python builtin minor tweaks Remove internal Python struct names from generated code Cosmetic code formatting --- Lib/python/builtin.swg | 9 ++++----- Lib/python/pyinit.swg | 1 - Lib/python/pyrun.swg | 8 +++----- Source/Modules/python.cxx | 10 +++++----- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index abf5f71cb..6085980d4 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -389,16 +389,15 @@ SwigPyStaticVar_Type(void) { static int type_init = 0; if (!type_init) { const PyTypeObject tmp = { - /* PyObject header changed in Python 3 */ #if PY_VERSION_HEX >= 0x03000000 PyVarObject_HEAD_INIT(&PyType_Type, 0) #else PyObject_HEAD_INIT(&PyType_Type) - 0, + 0, /* ob_size */ #endif - "swig_static_var_getset_descriptor", - sizeof(PyGetSetDescrObject), - 0, + "swig_static_var_getset_descriptor", /* tp_name */ + sizeof(PyGetSetDescrObject), /* tp_basicsize */ + 0, /* tp_itemsize */ (destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg index 2e21b8265..e671731ac 100644 --- a/Lib/python/pyinit.swg +++ b/Lib/python/pyinit.swg @@ -145,7 +145,6 @@ swig_varlink_type(void) { static int type_init = 0; if (!type_init) { const PyTypeObject tmp = { - /* PyObject header changed in Python 3 */ #if PY_VERSION_HEX >= 0x03000000 PyVarObject_HEAD_INIT(NULL, 0) #else diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index 08f0848d4..ab1237f62 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -758,7 +758,6 @@ SwigPyObject_TypeOnce(void) { static int type_init = 0; if (!type_init) { const PyTypeObject tmp = { - /* PyObject header changed in Python 3 */ #if PY_VERSION_HEX >= 0x03000000 PyVarObject_HEAD_INIT(NULL, 0) #else @@ -769,7 +768,7 @@ SwigPyObject_TypeOnce(void) { sizeof(SwigPyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)SwigPyObject_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_print */ #if PY_VERSION_HEX < 0x02020000 (getattrfunc)SwigPyObject_getattr, /* tp_getattr */ #else @@ -777,7 +776,7 @@ SwigPyObject_TypeOnce(void) { #endif (setattrfunc)0, /* tp_setattr */ #if PY_VERSION_HEX >= 0x03000000 - 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ + 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ #else (cmpfunc)SwigPyObject_compare, /* tp_compare */ #endif @@ -787,7 +786,7 @@ SwigPyObject_TypeOnce(void) { 0, /* tp_as_mapping */ (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ - 0, /* tp_str */ + 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ @@ -950,7 +949,6 @@ SwigPyPacked_TypeOnce(void) { static int type_init = 0; if (!type_init) { const PyTypeObject tmp = { - /* PyObject header changed in Python 3 */ #if PY_VERSION_HEX>=0x03000000 PyVarObject_HEAD_INIT(NULL, 0) #else diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 72da66f66..d31554071 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4055,7 +4055,7 @@ public: String *tp_flags_py3 = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"); static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)"); - static String *tp_dictoffset_default = NewString("(Py_ssize_t)offsetof(SwigPyObject, dict)"); + static String *tp_dictoffset_default = NewString("offsetof(SwigPyObject, dict)"); static String *tp_new = NewString("PyType_GenericNew"); String *tp_as_number = NewStringf("&%s_type.as_number", templ); String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ); @@ -4113,7 +4113,7 @@ public: printSlot(f, getSlot(n, "feature:python:tp_dict"), "tp_dict"); printSlot(f, getSlot(n, "feature:python:tp_descr_get"), "tp_descr_get", "descrgetfunc"); printSlot(f, getSlot(n, "feature:python:tp_descr_set"), "tp_descr_set", "descrsetfunc"); - printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset"); + printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset", "Py_ssize_t"); printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc"); printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc"); printSlot(f, getSlot(n, "feature:python:tp_new", tp_new), "tp_new", "newfunc"); @@ -4136,9 +4136,9 @@ public: printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t"); printSlot(f, getSlot(n, "feature:python:tp_maxalloc"), "tp_maxalloc", "Py_ssize_t"); Printv(f, "#if PY_VERSION_HEX >= 0x02050000\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev", "struct _typeobject *"); + printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev"); Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next", "struct _typeobject *"); + printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next"); Printv(f, "#endif\n", NIL); Printf(f, " },\n"); @@ -4262,7 +4262,7 @@ public: printSlot(f, getSlot(n, "feature:python:ht_qualname"), "ht_qualname", "PyObject *"); // struct _dictkeysobject *ht_cached_keys; - printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys", "struct _dictkeysobject *"); + printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys"); Printv(f, "#endif\n", NIL); Printf(f, "};\n\n"); From 17d68afedd185b06decaac42bd4a2b983b346d6b Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 22 Aug 2016 19:52:41 +0100 Subject: [PATCH 27/63] changes file updates --- CHANGES.current | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 36780b440..3c07efc8c 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,36 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-08-22: wsfulton + [Python] The following builtin slots can be customized like other slots via the + "python:" and "python:slot" features where is the appropriate slot name: + tp_allocs + tp_bases + tp_basicsize + tp_cache + tp_del + tp_dealloc + tp_flags + tp_frees + tp_getset + tp_is_gc + tp_maxalloc + tp_methods + tp_mro + tp_new + tp_next + tp_prev + tp_richcompare + tp_subclasses + tp_weaklist + was_sq_ass_slice + was_sq_slice + + A few documentation improvements for slot customization. + +2016-08-09: joequant + [R] Patch #765 Fix extern "C" header includes for C++ code. + 2016-08-05: olly [xml] Fix how the output filename is built to avoid problems when it contains the embedded strings ".c", ".cpp" or ".cxx". From 253a39fdffc9b3c270ba815d6e60f416a4ee46a7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 23 Aug 2016 18:46:28 +0100 Subject: [PATCH 28/63] Fix hash function type checking for older versions of Python Python 2.6 was asserting instead of throwing a Python TypeError. --- Lib/python/builtin.swg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index 6085980d4..3dd5bbf95 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -194,7 +194,10 @@ wrapper##_closure(PyObject *a) { \ pyresult = wrapper(a, NULL); \ if (!pyresult) \ return -1; \ - result = PyLong_AsLong(pyresult); \ + if (!PyLong_Check(pyresult)) \ + PyErr_Format(PyExc_TypeError, "Wrong type for hash function");\ + else \ + result = PyLong_AsLong(pyresult); \ if (PyErr_Occurred()) \ result = -1; \ Py_DECREF(pyresult); \ From 5b7c08c21449c407019f4484c91819a441e8bd9c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 23 Aug 2016 18:15:35 +0100 Subject: [PATCH 29/63] Make Python builtin types hashable by default Default hash is the underlying C/C++ pointer. This matches up with testing for equivalence (Py_EQ in SwigPyObject_richcompare) which compares the pointers. --- .../test-suite/python/python_builtin_runme.py | 11 +++++ Examples/test-suite/python_builtin.i | 14 +++++-- Lib/python/builtin.swg | 40 +++++++++++++------ Lib/python/pyhead.swg | 1 + Source/Modules/python.cxx | 3 +- 5 files changed, 53 insertions(+), 16 deletions(-) diff --git a/Examples/test-suite/python/python_builtin_runme.py b/Examples/test-suite/python/python_builtin_runme.py index c41dfc0b1..70990cbfd 100644 --- a/Examples/test-suite/python/python_builtin_runme.py +++ b/Examples/test-suite/python/python_builtin_runme.py @@ -1,6 +1,17 @@ from python_builtin import * if is_python_builtin(): + # Test 0 for default tp_hash + vs = ValueStruct(1234) + h = hash(vs) + d = dict() + d[h] = "hi" + if h not in d: + raise RuntimeError("h should be in d") + h2 = hash(ValueStruct.inout(vs)) + if h != h2: + raise RuntimeError("default tp_hash not working") + # Test 1 for tp_hash if hash(SimpleValue(222)) != 222: raise RuntimeError("tp_hash not working") diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i index ac1ad9c2d..e2c453d54 100644 --- a/Examples/test-suite/python_builtin.i +++ b/Examples/test-suite/python_builtin.i @@ -10,6 +10,17 @@ bool is_python_builtin() { return false; } #endif %} +// Test 0 for default tp_hash +%inline %{ +struct ValueStruct { + int value; + ValueStruct(int value) : value(value) {} + static ValueStruct *inout(ValueStruct *v) { + return v; + } +}; +%} + // Test 1 for tp_hash #if defined(SWIGPYTHON_BUILTIN) %feature("python:tp_hash") SimpleValue "SimpleValueHashFunction" @@ -19,9 +30,6 @@ bool is_python_builtin() { return false; } struct SimpleValue { int value; SimpleValue(int value) : value(value) {} - static SimpleValue *inout(SimpleValue *sv) { - return sv; - } }; %} diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index 3dd5bbf95..1244dbbcc 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -187,19 +187,14 @@ wrapper##_closure(PyObject *a) { \ } #define SWIGPY_HASHFUNC_CLOSURE(wrapper) \ -SWIGINTERN long \ +SWIGINTERN Py_hash_t \ wrapper##_closure(PyObject *a) { \ PyObject *pyresult; \ - long result; \ + Py_hash_t result; \ pyresult = wrapper(a, NULL); \ if (!pyresult) \ return -1; \ - if (!PyLong_Check(pyresult)) \ - PyErr_Format(PyExc_TypeError, "Wrong type for hash function");\ - else \ - result = PyLong_AsLong(pyresult); \ - if (PyErr_Occurred()) \ - result = -1; \ + result = SWIG_PyNumber_AsPyHash(pyresult); \ Py_DECREF(pyresult); \ return result; \ } @@ -227,14 +222,35 @@ SwigPyBuiltin_BadInit(PyObject *self, PyObject *SWIGUNUSEDPARM(args), PyObject * } SWIGINTERN void -SwigPyBuiltin_BadDealloc(PyObject *pyobj) { - SwigPyObject *sobj; - sobj = (SwigPyObject *)pyobj; +SwigPyBuiltin_BadDealloc(PyObject *obj) { + SwigPyObject *sobj = (SwigPyObject *)obj; if (sobj->own) { - PyErr_Format(PyExc_TypeError, "Swig detected a memory leak in type '%.300s': no callable destructor found.", pyobj->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "Swig detected a memory leak in type '%.300s': no callable destructor found.", obj->ob_type->tp_name); } } +SWIGINTERN Py_hash_t +SwigPyObject_hash(PyObject *obj) { + SwigPyObject *sobj = (SwigPyObject *)obj; + void *ptr = sobj->ptr; + return (Py_hash_t)ptr; +} + +SWIGINTERN Py_hash_t +SWIG_PyNumber_AsPyHash(PyObject *obj) { + Py_hash_t result = -1; +#if PY_VERSION_HEX < 0x03020000 + if (PyLong_Check(obj)) + result = PyLong_AsLong(obj); +#else + if (PyNumber_Check(obj)) + result = PyNumber_AsSsize_t(obj, NULL); +#endif + else + PyErr_Format(PyExc_TypeError, "Wrong type for hash function"); + return result; +} + typedef struct { PyCFunction get; PyCFunction set; diff --git a/Lib/python/pyhead.swg b/Lib/python/pyhead.swg index 63df684b6..55eb95a6d 100644 --- a/Lib/python/pyhead.swg +++ b/Lib/python/pyhead.swg @@ -211,4 +211,5 @@ typedef destructor freefunc; #if PY_VERSION_HEX < 0x03020000 #define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) #define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) +#define Py_hash_t long #endif diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index d31554071..40d3d9a8a 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4057,6 +4057,7 @@ public: static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)"); static String *tp_dictoffset_default = NewString("offsetof(SwigPyObject, dict)"); static String *tp_new = NewString("PyType_GenericNew"); + static String *tp_hash = NewString("SwigPyObject_hash"); String *tp_as_number = NewStringf("&%s_type.as_number", templ); String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ); String *tp_as_mapping = NewStringf("&%s_type.as_mapping", templ); @@ -4088,7 +4089,7 @@ public: printSlot(f, getSlot(n, "feature:python:tp_as_number", tp_as_number), "tp_as_number"); printSlot(f, getSlot(n, "feature:python:tp_as_sequence", tp_as_sequence), "tp_as_sequence"); printSlot(f, getSlot(n, "feature:python:tp_as_mapping", tp_as_mapping), "tp_as_mapping"); - printSlot(f, getSlot(n, "feature:python:tp_hash"), "tp_hash", "hashfunc"); + printSlot(f, getSlot(n, "feature:python:tp_hash", tp_hash), "tp_hash", "hashfunc"); printSlot(f, getSlot(n, "feature:python:tp_call"), "tp_call", "ternaryfunc"); printSlot(f, getSlot(n, "feature:python:tp_str"), "tp_str", "reprfunc"); printSlot(f, getSlot(n, "feature:python:tp_getattro"), "tp_getattro", "getattrofunc"); From 5839d9cce00e7f14a7df2e4ef0ecaef79fbe7ec1 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Sat, 27 Aug 2016 11:12:16 +1200 Subject: [PATCH 30/63] Use relative link to another manual chapter Explicitly linking to the copy on the website breaks the link for those browsing installed documentation offline. --- Doc/Manual/Scilab.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Manual/Scilab.html b/Doc/Manual/Scilab.html index 0ac4c059f..0eaa61423 100644 --- a/Doc/Manual/Scilab.html +++ b/Doc/Manual/Scilab.html @@ -1123,7 +1123,7 @@ But we can use either use the get_perimeter() function of the parent cl

    -As explained in 6.15 SWIG provides support for overloaded functions and constructors. +As explained in 6.15 SWIG provides support for overloaded functions and constructors.

    As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function magnify overloaded for the previous classes Shape and Circle: From 3a8f734221533c10ba5a9e66a0777cc3d813cd19 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 30 Aug 2016 11:16:49 +1200 Subject: [PATCH 31/63] Remove unused SWIG_landfill It's not been used in any version of SWIG in the repository, isn't documented, and I can find no trace of user code using it. --- Lib/php/phprun.swg | 3 --- 1 file changed, 3 deletions(-) diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index 3f0aa7ac6..0021a90e8 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -93,9 +93,6 @@ typedef struct { int newobject; } swig_object_wrapper; -/* empty zend destructor for types without one */ -static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) { (void)rsrc; } - #define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d TSRMLS_CC) #define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) From 5e63738f755d49705e0ab9e7ca67cc249bb8bdd4 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 30 Aug 2016 14:38:17 +1200 Subject: [PATCH 32/63] Remove ancient debian directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not been touched since 2006, won't work with modern versions of the debian packaging tools, and relies on a script which isn't in git. Debian packaging is maintained in a separate VCS by the Debian maintainer. Fixes #774, reported by Nico Schlömer. --- Tools/mkdist.py | 4 --- debian/README | 20 ------------ debian/changelog | 66 -------------------------------------- debian/control | 18 ----------- debian/copyright | 83 ------------------------------------------------ debian/dirs | 4 --- debian/docs | 47 --------------------------- debian/postinst | 45 -------------------------- debian/rules | 76 -------------------------------------------- debian/substvars | 1 - 10 files changed, 364 deletions(-) delete mode 100644 debian/README delete mode 100644 debian/changelog delete mode 100644 debian/control delete mode 100644 debian/copyright delete mode 100644 debian/dirs delete mode 100644 debian/docs delete mode 100644 debian/postinst delete mode 100755 debian/rules delete mode 100644 debian/substvars diff --git a/Tools/mkdist.py b/Tools/mkdist.py index 98f9912a4..11a0dd6cd 100755 --- a/Tools/mkdist.py +++ b/Tools/mkdist.py @@ -78,10 +78,6 @@ outdir = os.path.basename(os.getcwd()) + "/" + dirname + "/" print "Grabbing tagged release git repository using 'git archive' into " + outdir os.system("(cd .. && git archive --prefix=" + outdir + " " + tag + " . | tar -xf -)") == 0 or failed() -# Remove the debian directory -- it's not official - -os.system("rm -Rf "+dirname+"/debian") == 0 or failed() - # Go build the system print "Building system" diff --git a/debian/README b/debian/README deleted file mode 100644 index 9cbe96a3c..000000000 --- a/debian/README +++ /dev/null @@ -1,20 +0,0 @@ -The Debian Package swig1.3 --------------------------- - -This is SWIG 1.3 (Simplified Wrapper and Interface Generator) -packaged for Debian GNU/Linux. - -SWIG 1.3 is not fully compatible with SWIG 1.1. It is a re-development -effort of SWIG 1.1 (which was written in C++) in ANSI C. The 1.3 -series is in "alpha" state. Release 1.3a5 was rather stable, and it -should be used for new projects rather than the ancient release -1.1p5. See the file `NEW' for information on the new features of the -1.3 series. - -This Debian package derives from the release 1.3a5 and corresponds to -the "mkoeppe-1-3-a5-patches" branch of the SWIG CVS repository. It -fixes several bugs and enhances several language backends. See the -top of the file `CHANGES' for details. - - -Matthias Koeppe , Mon, 28 May 2001 15:08:55 +0200 diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index da43b40e9..000000000 --- a/debian/changelog +++ /dev/null @@ -1,66 +0,0 @@ -swig1.3 (1.3.pnet) unstable; urgency=low - - * Support for dotgnu pnet under debian - - -- James Michael DuPont Wed, 12 Mar 2003 20:55:53 +0200 - -swig1.3 (1.3.a5+patches-9) unstable; urgency=low - - * New upstream version - - -- Matthias Koeppe Wed, 6 Jun 2001 16:11:41 +0200 - -swig1.3 (1.3.a5+patches-8) unstable; urgency=low - - * New upstream version - - -- Matthias Koeppe Wed, 6 Jun 2001 14:06:51 +0200 - -swig1.3 (1.3.a5+patches-7) unstable; urgency=low - - * New upstream version - - -- Matthias Koeppe Wed, 6 Jun 2001 13:34:44 +0200 - -swig1.3 (1.3.a5+patches-6) unstable; urgency=low - - * New upstream version - - -- Matthias Koeppe Tue, 5 Jun 2001 14:11:52 +0200 - -swig1.3 (1.3.a5+patches-5) unstable; urgency=low - - * New upstream version. - - -- Matthias Koeppe Fri, 1 Jun 2001 18:48:59 +0200 - -swig1.3 (1.3.a5+patches-4) unstable; urgency=low - - * Fix hard-coded location of swig library. Added build-dependency on - tcl-dev. - - -- Matthias Koeppe Fri, 1 Jun 2001 13:32:34 +0200 - -swig1.3 (1.3.a5+patches-3) unstable; urgency=low - - * New upstream version - - -- Matthias Koeppe Thu, 31 May 2001 13:15:20 +0200 - -swig1.3 (1.3.a5+patches-2) unstable; urgency=low - - * Binary and manpage now include version number, to improve - cooperation with the "swig" package. - - -- Matthias Koeppe Tue, 29 May 2001 15:15:07 +0200 - -swig1.3 (1.3.a5+patches-1) unstable; urgency=low - - * First release. - - -- Matthias Koeppe Sat, 20 Nov 1999 01:09:11 +0100 - -Local variables: -mode: debian-changelog -add-log-mailing-address: "mkoeppe@mail.math.uni-magdeburg.de" -End: \ No newline at end of file diff --git a/debian/control b/debian/control deleted file mode 100644 index 80e0a7017..000000000 --- a/debian/control +++ /dev/null @@ -1,18 +0,0 @@ -Source: swig1.3 -Section: interpreters -Priority: optional -Maintainer: Matthias Koeppe -Build-Depends: debhelper (>> 3.0.0), libguile-dev, python-dev, perl, - ruby-dev, ruby, tcl8.0-dev -Standards-Version: 3.5.2 - -Package: swig1.3 -Architecture: any -Depends: ${shlibs:Depends} -Description: Generate scripting interfaces to C/C++ code - SWIG (Simplified Wrapper and Interface Generator) is a system for - automatically generating wrapper/glue code for several languages - (Tcl, Python, Perl, Ruby, MzScheme, Guile, Java) from annotated C or - C++ header files. - This package represents some point in the SWIG 1.3 development - series. It is not fully compatible with the SWIG 1.1 release. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 8cb86922e..000000000 --- a/debian/copyright +++ /dev/null @@ -1,83 +0,0 @@ -This is SWIG, written and maintained by: - - Dave Beazley (beazley@cs.uchicago.edu) (SWIG core) - Loic Dachary (loic@ceic.com) (Perl5) - Harco de Hilster (Harco.de.Hilster@ATComputing.nl) (Java) - Thien-Thi Nguyen (ttn@glug.org) (Testing/Misc) - Masaki Fukushima (fukusima@goto.info.waseda.ac.jp) (Ruby) - Matthias Koeppe (mkoeppe@mail.math.uni-magdeburg.de) (Guile/MzScheme) - -Past contributors: - - Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran Kovuk, Gary Holt, - David Fletcher, Oleg Tolmatcev. - -SWIG can be obtained by anonymous CVS: - - cvs -d :pserver:cvs@swig.cs.uchicago.edu:/cvsroot co SWIG - -SWIG is distributed under the following terms: - -I. - -Copyright (C) 1998-2000 -The University of Chicago - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that -(1) The above copyright notice and the following two paragraphs -appear in all copies of the source code and (2) redistributions -including binaries reproduces these notices in the supporting -documentation. Substantial modifications to this software may be -copyrighted by their authors and need not follow the licensing terms -described here, provided that the new terms are clearly indicated in -all files where they apply. - -IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CHICAGO, OR -DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, -INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF -THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR -ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -THE AUTHOR AND THE UNIVERSITY OF CHICAGO SPECIFICALLY DISCLAIM ANY -WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE -PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND -DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, -UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - -II. - -Copyright (c) 1995-1998 -The University of Utah and the Regents of the University of California -All Rights Reserved - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that -(1) The above copyright notice and the following two paragraphs -appear in all copies of the source code and (2) redistributions -including binaries reproduces these notices in the supporting -documentation. Substantial modifications to this software may be -copyrighted by their authors and need not follow the licensing terms -described here, provided that the new terms are clearly indicated in -all files where they apply. - -IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE -UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY -PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. - -THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH -SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND -THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, -SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - diff --git a/debian/dirs b/debian/dirs deleted file mode 100644 index 587d58405..000000000 --- a/debian/dirs +++ /dev/null @@ -1,4 +0,0 @@ -usr/bin -usr/lib -#usr/share/swig1.3-pnet -#usr/share/doc/swig1.3-pnet diff --git a/debian/docs b/debian/docs deleted file mode 100644 index 9e310ea30..000000000 --- a/debian/docs +++ /dev/null @@ -1,47 +0,0 @@ -README -TODO -ANNOUNCE -CHANGES -NEW -Doc/Devel/engineering.html -Doc/Devel/index.html -Doc/Devel/internals.html -Doc/Devel/migrate.txt -Doc/README -Doc/Manual/About.html -Doc/Manual/Advanced.html -Doc/Manual/Arguments.html -Doc/Manual/Chicken.html -Doc/Manual/Contents.html -Doc/Manual/Copyright.html -Doc/Manual/Customization.html -Doc/Manual/Documentation.html -Doc/Manual/Extending.html -Doc/Manual/Guile.html -Doc/Manual/Introduction.html -Doc/Manual/Java.html -Doc/Manual/Library.html -Doc/Manual/Ocaml.html -Doc/Manual/Perl5.html -Doc/Manual/Php.html -Doc/Manual/Preface.html -Doc/Manual/Preprocessor.html -Doc/Manual/Python.html -Doc/Manual/README -Doc/Manual/Ruby.html -Doc/Manual/SWIG.html -Doc/Manual/SWIGPlus.html -Doc/Manual/Scripting.html -Doc/Manual/Tcl.html -Doc/Manual/Typemaps.html -Doc/Manual/Varargs.html -Doc/Manual/Warnings.html -Doc/Manual/Windows.html -Doc/Manual/ch11.1.png -Doc/Manual/ch11.2.png -Doc/Manual/ch11.3.png -Doc/Manual/ch12.1.png -Doc/Manual/ch2.1.png -Doc/Manual/ch9.table.2.png -Doc/Manual/chapters -Doc/Manual/index.html diff --git a/debian/postinst b/debian/postinst deleted file mode 100644 index 164b5ff1a..000000000 --- a/debian/postinst +++ /dev/null @@ -1,45 +0,0 @@ -#! /bin/sh -# postinst script for swig1.3 -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `configure' -# * `abort-upgrade' -# * `abort-remove' `in-favour' -# -# * `abort-deconfigure' `in-favour' -# `removing' -# -# for details, see /usr/share/doc/packaging-manual/ -# -# quoting from the policy: -# Any necessary prompting should almost always be confined to the -# post-installation script, and should be protected with a conditional -# so that unnecessary prompting doesn't happen if a package's -# installation fails and the `postinst' is called with `abort-upgrade', -# `abort-remove' or `abort-deconfigure'. - -case "$1" in - configure) - - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 0 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 1fafed902..000000000 --- a/debian/rules +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/make -f -# Sample debian/rules that uses debhelper. -# GNU copyright 1997 to 1999 by Joey Hess. - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -# This is the debhelper compatability version to use. -export DH_COMPAT=3 - -configure: configure-stamp -configure-stamp: - dh_testdir - ./autogen-debian.sh - ./configure --prefix=/usr --mandir=/usr/share/man --with-swiglibdir=/usr/share/swig1.3 --program-suffix=-1.3 - touch configure-stamp - -build: configure-stamp build-stamp -build-stamp: - dh_testdir - $(MAKE) - $(MAKE) runtime - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp configure-stamp - - -$(MAKE) clean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - $(MAKE) install DESTDIR=$(CURDIR)/debian/swig1.3 - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot -# dh_installdebconf - dh_installdocs - dh_installexamples - dh_installmenu -# dh_installlogrotate -# dh_installemacsen -# dh_installpam -# dh_installmime -# dh_installinit -# dh_installcron - dh_installman - dh_installinfo - dh_undocumented swig-1.3.1 -# dh_installchangelogs CHANGES - dh_link - dh_strip - dh_compress - dh_fixperms - dh_makeshlibs - dh_installdeb -# dh_perl - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/debian/substvars b/debian/substvars deleted file mode 100644 index c9df68ba1..000000000 --- a/debian/substvars +++ /dev/null @@ -1 +0,0 @@ -shlibs:Depends=libc6 (>= 2.2.3-1), libstdc++2.10-glibc2.2 From 888e9c6fec2c7496d5483e1987c549c4af88774f Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Wed, 31 Aug 2016 16:36:13 +1200 Subject: [PATCH 33/63] Use preg_match() in PHP test harness code ereg() and eregi() were deprecated in PHP 5.3.0 and removed in PHP 7.0.0, and preg_match() has been available since PHP4. --- Examples/test-suite/php/tests.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php index 57c5c4788..d3fd66868 100644 --- a/Examples/test-suite/php/tests.php +++ b/Examples/test-suite/php/tests.php @@ -35,8 +35,9 @@ class check { foreach($_original_functions[internal] as $func) unset($df[$func]); // Now chop out any get/set accessors foreach(array_keys($df) as $func) - if ((GETSET && ereg('_[gs]et$',$func)) || ereg('^new_', $func) - || ereg('_(alter|get)_newobject$', $func)) + if ((GETSET && preg_match('/_[gs]et$/', $func)) || + preg_match('/^new_/', $func) || + preg_match('/_(alter|get)_newobject$/', $func)) $extrags[]=$func; else $extra[]=$func; // $extra=array_keys($df); @@ -52,7 +53,8 @@ class check { if (GETSET) { $_extra=array(); foreach(check::get_extra_functions(false,1) as $global) { - if (ereg('^(.*)_[sg]et$',$global,$match)) $_extra[$match[1]]=1; + if (preg_match('/^(.*)_[sg]et$/', $global, $match)) + $_extra[$match[1]] = 1; } $extra=array_keys($_extra); } else { @@ -61,7 +63,8 @@ class check { $df=array_flip(array_keys($GLOBALS)); foreach($_original_globals as $func) unset($df[$func]); // MASK xxxx_LOADED__ variables - foreach(array_keys($df) as $func) if (ereg('_LOADED__$',$func)) unset($df[$func]); + foreach(array_keys($df) as $func) + if (preg_match('/_LOADED__$/', $func)) unset($df[$func]); $extra=array_keys($df); } } @@ -185,7 +188,8 @@ class check { } function functionref($a,$type,$message) { - if (! eregi("^_[a-f0-9]+$type$",$a)) return check::fail($message); + if (! preg_match("/^_[a-f0-9]+$type$/i", $a)) + return check::fail($message); return TRUE; } @@ -196,7 +200,8 @@ class check { function resource($a,$b,$message) { $resource=trim(check::var_dump($a)); - if (! eregi("^resource\([0-9]+\) of type \($b\)",$resource)) return check::fail($message); + if (! preg_match("/^resource\([0-9]+\) of type \($b\)/i", $resource)) + return check::fail($message); return TRUE; } From a4015acacabcbb0e9d7698a1c2b370a784a0ba2f Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 2 Sep 2016 09:51:18 +1200 Subject: [PATCH 34/63] [PHP] Fix out typemap for member function pointers The existing typemap was just broken - it correctly created the resource and then did nothing with it, and instead tried to register the member pointer as a normal pointer, which is never going to work as it's larger than a normal pointer. Add cpp_basic_runme.php as a regression test for this. --- CHANGES.current | 3 +++ Examples/test-suite/php/cpp_basic_runme.php | 20 ++++++++++++++++++++ Lib/php/php.swg | 6 +----- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 Examples/test-suite/php/cpp_basic_runme.php diff --git a/CHANGES.current b/CHANGES.current index 3c07efc8c..d5dc669ef 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-02: olly + [PHP] Fix out typemap for member function pointers. + 2016-08-22: wsfulton [Python] The following builtin slots can be customized like other slots via the "python:" and "python:slot" features where is the appropriate slot name: diff --git a/Examples/test-suite/php/cpp_basic_runme.php b/Examples/test-suite/php/cpp_basic_runme.php new file mode 100644 index 000000000..6a8522e3e --- /dev/null +++ b/Examples/test-suite/php/cpp_basic_runme.php @@ -0,0 +1,20 @@ +func_ptr = get_func1_ptr(); +check::equal(test_func_ptr($f, 7), 2*7*3, "get_func1_ptr() didn't work"); +$f->func_ptr = get_func2_ptr(); +check::equal(test_func_ptr($f, 7), -7*3, "get_func2_ptr() didn't work"); + +check::done(); +?> diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 45dfb0b0d..535c7d347 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -393,11 +393,7 @@ { void * p = emalloc(sizeof($1)); memcpy(p, &$1, sizeof($1)); - zval * resource; - MAKE_STD_ZVAL(resource); - ZEND_REGISTER_RESOURCE(resource, p, swig_member_ptr); - - SWIG_SetPointerZval(return_value, (void *)&$1, $1_descriptor, $owner); + ZEND_REGISTER_RESOURCE(return_value, p, swig_member_ptr); } %typemap(in, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*) From 5ebf1cfa5d99804a41d09b48d7b648350e1e3bec Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 Sep 2016 08:38:31 +0100 Subject: [PATCH 35/63] Slight simplification of Python slicing --- Lib/python/pycontainer.swg | 82 ++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg index 4621c1b34..3d10b9bb8 100644 --- a/Lib/python/pycontainer.swg +++ b/Lib/python/pycontainer.swg @@ -206,7 +206,7 @@ namespace swig { if (step == 0) { throw std::invalid_argument("slice step cannot be zero"); } else if (step > 0) { - // Required range: 0 <= i < size, 0 <= j < size + // Required range: 0 <= i < size, 0 <= j < size, i <= j if (i < 0) { ii = 0; } else if (i < (Difference)size) { @@ -214,13 +214,15 @@ namespace swig { } else if (insert && (i >= (Difference)size)) { ii = (Difference)size; } - if ( j < 0 ) { + if (j < 0) { jj = 0; } else { jj = (j < (Difference)size) ? j : (Difference)size; } + if (jj < ii) + jj = ii; } else { - // Required range: -1 <= i < size-1, -1 <= j < size-1 + // Required range: -1 <= i < size-1, -1 <= j < size-1, i >= j if (i < -1) { ii = -1; } else if (i < (Difference) size) { @@ -233,6 +235,8 @@ namespace swig { } else { jj = (j < (Difference)size ) ? j : (Difference)(size-1); } + if (ii < jj) + ii = jj; } } @@ -285,17 +289,15 @@ namespace swig { } } else { Sequence *sequence = new Sequence(); - if (ii > jj) { - typename Sequence::const_reverse_iterator sb = self->rbegin(); - typename Sequence::const_reverse_iterator se = self->rbegin(); - std::advance(sb,size-ii-1); - std::advance(se,size-jj-1); - typename Sequence::const_reverse_iterator it = sb; - while (it!=se) { - sequence->push_back(*it); - for (Py_ssize_t c=0; c<-step && it!=se; ++c) - it++; - } + typename Sequence::const_reverse_iterator sb = self->rbegin(); + typename Sequence::const_reverse_iterator se = self->rbegin(); + std::advance(sb,size-ii-1); + std::advance(se,size-jj-1); + typename Sequence::const_reverse_iterator it = sb; + while (it!=se) { + sequence->push_back(*it); + for (Py_ssize_t c=0; c<-step && it!=se; ++c) + it++; } return sequence; } @@ -309,8 +311,6 @@ namespace swig { Difference jj = 0; swig::slice_adjust(i, j, step, size, ii, jj, true); if (step > 0) { - if (jj < ii) - jj = ii; if (step == 1) { size_t ssize = jj - ii; if (ssize <= is.size()) { @@ -348,8 +348,6 @@ namespace swig { } } } else { - if (jj > ii) - jj = ii; size_t replacecount = (ii - jj - step - 1) / -step; if (is.size() != replacecount) { char msg[1024]; @@ -375,37 +373,33 @@ namespace swig { Difference jj = 0; swig::slice_adjust(i, j, step, size, ii, jj, true); if (step > 0) { - if (jj > ii) { - typename Sequence::iterator sb = self->begin(); - std::advance(sb,ii); - if (step == 1) { - typename Sequence::iterator se = self->begin(); - std::advance(se,jj); - self->erase(sb,se); - } else { - typename Sequence::iterator it = sb; - size_t delcount = (jj - ii + step - 1) / step; - while (delcount) { - it = self->erase(it); - for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c) - it++; - delcount--; - } - } - } - } else { - if (ii > jj) { - typename Sequence::reverse_iterator sb = self->rbegin(); - std::advance(sb,size-ii-1); - typename Sequence::reverse_iterator it = sb; - size_t delcount = (ii - jj - step - 1) / -step; + typename Sequence::iterator sb = self->begin(); + std::advance(sb,ii); + if (step == 1) { + typename Sequence::iterator se = self->begin(); + std::advance(se,jj); + self->erase(sb,se); + } else { + typename Sequence::iterator it = sb; + size_t delcount = (jj - ii + step - 1) / step; while (delcount) { - it = typename Sequence::reverse_iterator(self->erase((++it).base())); - for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c) + it = self->erase(it); + for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c) it++; delcount--; } } + } else { + typename Sequence::reverse_iterator sb = self->rbegin(); + std::advance(sb,size-ii-1); + typename Sequence::reverse_iterator it = sb; + size_t delcount = (ii - jj - step - 1) / -step; + while (delcount) { + it = typename Sequence::reverse_iterator(self->erase((++it).base())); + for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c) + it++; + delcount--; + } } } } From 5abb3e800886f9dc8c73d9039f997d1ee36c19f3 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 Sep 2016 19:21:09 +0100 Subject: [PATCH 36/63] More efficient Python slicing Call reserve for container types that support it to avoid repeated memory reallocations for new slices or slices that grow in size. --- Lib/python/pycontainer.swg | 10 ++++++++++ Lib/python/std_unordered_map.i | 7 +++++++ Lib/python/std_unordered_multimap.i | 7 +++++++ Lib/python/std_unordered_multiset.i | 7 +++++++ Lib/python/std_unordered_set.i | 7 +++++++ Lib/python/std_vector.i | 7 +++++++ 6 files changed, 45 insertions(+) diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg index 3d10b9bb8..8463e28f8 100644 --- a/Lib/python/pycontainer.swg +++ b/Lib/python/pycontainer.swg @@ -262,6 +262,13 @@ namespace swig { seq->erase(position); } + template + struct traits_reserve { + static void reserve(Sequence & /*seq*/, typename Sequence::size_type /*n*/) { + // This should be specialized for types that support reserve + } + }; + template inline Sequence* getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) { @@ -279,6 +286,7 @@ namespace swig { return new Sequence(sb, se); } else { Sequence *sequence = new Sequence(); + swig::traits_reserve::reserve(*sequence, (jj - ii + step - 1) / step); typename Sequence::const_iterator it = sb; while (it!=se) { sequence->push_back(*it); @@ -289,6 +297,7 @@ namespace swig { } } else { Sequence *sequence = new Sequence(); + swig::traits_reserve::reserve(*sequence, (ii - jj - step - 1) / -step); typename Sequence::const_reverse_iterator sb = self->rbegin(); typename Sequence::const_reverse_iterator se = self->rbegin(); std::advance(sb,size-ii-1); @@ -315,6 +324,7 @@ namespace swig { size_t ssize = jj - ii; if (ssize <= is.size()) { // expanding/staying the same size + swig::traits_reserve::reserve(*self, self->size() - ssize + is.size()); typename Sequence::iterator sb = self->begin(); typename InputSeq::const_iterator isit = is.begin(); std::advance(sb,ii); diff --git a/Lib/python/std_unordered_map.i b/Lib/python/std_unordered_map.i index 97b48af70..894840c6c 100644 --- a/Lib/python/std_unordered_map.i +++ b/Lib/python/std_unordered_map.i @@ -15,6 +15,13 @@ } } + template + struct traits_reserve > { + static void reserve(std::unordered_map &seq, typename std::unordered_map::size_type n) { + seq.reserve(n); + } + }; + template struct traits_asptr > { typedef std::unordered_map unordered_map_type; diff --git a/Lib/python/std_unordered_multimap.i b/Lib/python/std_unordered_multimap.i index aadd15515..2410aa52b 100644 --- a/Lib/python/std_unordered_multimap.i +++ b/Lib/python/std_unordered_multimap.i @@ -16,6 +16,13 @@ } } + template + struct traits_reserve > { + static void reserve(std::unordered_multimap &seq, typename std::unordered_multimap::size_type n) { + seq.reserve(n); + } + }; + template struct traits_asptr > { typedef std::unordered_multimap unordered_multimap_type; diff --git a/Lib/python/std_unordered_multiset.i b/Lib/python/std_unordered_multiset.i index d5b9ff61c..0d9f3d9c6 100644 --- a/Lib/python/std_unordered_multiset.i +++ b/Lib/python/std_unordered_multiset.i @@ -18,6 +18,13 @@ } } + template + struct traits_reserve > { + static void reserve(std::unordered_multiset &seq, typename std::unordered_multiset::size_type n) { + seq.reserve(n); + } + }; + template struct traits_asptr > { static int asptr(PyObject *obj, std::unordered_multiset **m) { diff --git a/Lib/python/std_unordered_set.i b/Lib/python/std_unordered_set.i index a021cb4ed..855a28da5 100644 --- a/Lib/python/std_unordered_set.i +++ b/Lib/python/std_unordered_set.i @@ -16,6 +16,13 @@ } } + template + struct traits_reserve > { + static void reserve(std::unordered_set &seq, typename std::unordered_set::size_type n) { + seq.reserve(n); + } + }; + template struct traits_asptr > { static int asptr(PyObject *obj, std::unordered_set **s) { diff --git a/Lib/python/std_vector.i b/Lib/python/std_vector.i index 3f04a30c7..2ac41a54d 100644 --- a/Lib/python/std_vector.i +++ b/Lib/python/std_vector.i @@ -5,6 +5,13 @@ %fragment("StdVectorTraits","header",fragment="StdSequenceTraits") %{ namespace swig { + template + struct traits_reserve > { + static void reserve(std::vector &seq, typename std::vector::size_type n) { + seq.reserve(n); + } + }; + template struct traits_asptr > { static int asptr(PyObject *obj, std::vector **vec) { From 50acc519f612726d1903e711919098b2999ea108 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 Sep 2016 23:54:24 +0100 Subject: [PATCH 37/63] Update changes file --- CHANGES.current | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index d5dc669ef..3cb19cd5e 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -8,6 +8,16 @@ Version 3.0.11 (in progress) 2016-09-02: olly [PHP] Fix out typemap for member function pointers. +2016-09-01: wsfulton + [Python] More efficient Python slicing. + Call reserve for container types that support it to avoid repeated + memory reallocations for new slices or slices that grow in size. + +2016-09-01: wsfulton + [Python] #771 - Make builtin types hashable by default. + Default hash is the underlying C/C++ pointer. This matches up with testing for + equivalence (Py_EQ in SwigPyObject_richcompare) which compares the pointers. + 2016-08-22: wsfulton [Python] The following builtin slots can be customized like other slots via the "python:" and "python:slot" features where is the appropriate slot name: From c51ce4995c07ada09827aaa9c062f3910dec231b Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 2 Sep 2016 16:38:58 +1200 Subject: [PATCH 38/63] [PHP] Fix "in" typemap for char INPUT[ANY] --- CHANGES.current | 3 ++- Lib/php/typemaps.i | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 3cb19cd5e..cf72375dc 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -6,7 +6,8 @@ Version 3.0.11 (in progress) ============================ 2016-09-02: olly - [PHP] Fix out typemap for member function pointers. + [PHP] Fix "out" typemap for member function pointers and "in" + typemap for char INPUT[ANY]. 2016-09-01: wsfulton [Python] More efficient Python slicing. diff --git a/Lib/php/typemaps.i b/Lib/php/typemaps.i index 0372884a6..faae0a6ac 100644 --- a/Lib/php/typemaps.i +++ b/Lib/php/typemaps.i @@ -271,7 +271,7 @@ INT_TYPEMAP(unsigned long long); %typemap(in) char INPUT[ANY] ( char temp[$1_dim0] ) %{ convert_to_string_ex($input); - strncpy(temp,Z_LVAL_PP($input),$1_dim0); + strncpy(temp,Z_STRVAL_PP($input),$1_dim0); $1 = temp; %} %typemap(in,numinputs=0) char OUTPUT[ANY] ( char temp[$1_dim0] ) From c252d5cb403e78f6a5e3014ca01229ddebf7b3b8 Mon Sep 17 00:00:00 2001 From: Simon Marchetto Date: Fri, 2 Sep 2016 11:36:02 +0200 Subject: [PATCH 39/63] scilab: pointer is mapped to mlist instead of tlist (for scilab overloading) --- CHANGES.current | 4 ++++ Lib/scilab/scirun.swg | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index cf72375dc..0056e6c55 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-02: smarchetto + [Scilab] Pointers are mapped to mlist instead of tlist + (mlist better for scilab overloading) + 2016-09-02: olly [PHP] Fix "out" typemap for member function pointers and "in" typemap for char INPUT[ANY]. diff --git a/Lib/scilab/scirun.swg b/Lib/scilab/scirun.swg index 5625b5298..58c313df7 100644 --- a/Lib/scilab/scirun.swg +++ b/Lib/scilab/scirun.swg @@ -120,7 +120,7 @@ SwigScilabCheckPtr(void *pvApiCtx, int iVar, swig_type_info *descriptor, char *f return SWIG_ERROR; } - if (iType == sci_tlist) { + if (iType == sci_mlist) { int iItemCount = 0; void *pvTypeinfo = NULL; @@ -171,7 +171,7 @@ SwigScilabPtrToObject(void *pvApiCtx, int iVar, void **pvObj, swig_type_info *de return SWIG_ERROR; } - if (iType == sci_tlist) { + if (iType == sci_mlist) { int iItemCount = 0; void *pvTypeinfo = NULL; @@ -236,30 +236,30 @@ SwigScilabPtrFromObject(void *pvApiCtx, int iVarOut, void *pvObj, swig_type_info SciErr sciErr; if (descriptor) { - int *piTListAddr = NULL; + int *piMListAddr = NULL; const char *pstString; - sciErr = createTList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, 3, &piTListAddr); + sciErr = createMList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, 3, &piMListAddr); if (sciErr.iErr) { printError(&sciErr, 0); return SWIG_ERROR; } pstString = SWIG_TypeName(descriptor); - sciErr = createMatrixOfStringInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piTListAddr, 1, 1, 1, &pstString); + sciErr = createMatrixOfStringInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piMListAddr, 1, 1, 1, &pstString); if (sciErr.iErr) { printError(&sciErr, 0); return SWIG_ERROR; } - sciErr = createPointerInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piTListAddr, 2, descriptor); + sciErr = createPointerInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piMListAddr, 2, descriptor); if (sciErr.iErr) { printError(&sciErr, 0); return SWIG_ERROR; } - sciErr = createPointerInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piTListAddr, 3, pvObj); + sciErr = createPointerInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piMListAddr, 3, pvObj); if (sciErr.iErr) { printError(&sciErr, 0); return SWIG_ERROR; From 073948777e90c5c3b1003398a08266828445d8d0 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 9 Sep 2016 16:28:52 +0200 Subject: [PATCH 40/63] Csharp: CLS compliance - keyword rename SWIG C# can be used to wrap native libraries as common language interface compatible assemblies. If you want to use the assemblies with other languages like Visual Basic these assemblies should comply to the Common Language Specification (CLS). Lib/csharp/csharpkw.swg defines rename rules to avoid collisions with keywords. Unfortunately these rules prepend an underscore. Parameters starting with underscores are not CLS compliant. Hence the rules should be changed to append the underscore instead of prepending it. Tested with make check-csharp-test-suite Signed-off-by: Heinrich Schuchardt Cc: Olly Betts --- Lib/csharp/csharpkw.swg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/csharp/csharpkw.swg b/Lib/csharp/csharpkw.swg index 43ca5993b..824f61874 100644 --- a/Lib/csharp/csharpkw.swg +++ b/Lib/csharp/csharpkw.swg @@ -2,9 +2,9 @@ #define CSHARP_CSHARPKW_SWG_ /* Warnings for C# keywords */ -#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword, renaming to '_" `x` "'",rename="_%s") `x` +#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword, renaming to '" `x` "_'",rename="%s_") `x` -#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes, class renamed to '_" `x` "'",%$isclass,rename="_%s") `x` +#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes, class renamed to '" `x` "_'",%$isclass,rename="%s_") `x` /* from From 849f157efa774e1c93ac94a42dee2bee6c82d410 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Mon, 12 Sep 2016 08:11:47 +1200 Subject: [PATCH 41/63] [Python] Fix import in frozen app for Python 2.6 (#784) Fix import handling for Python 2.6 to work in a frozen application. Fixes #145, reported by Thomas Kluyver. --- CHANGES.current | 4 ++++ Source/Modules/python.cxx | 11 ++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 0056e6c55..9554cf1a9 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-09: olly + [Python] Fix import handling for Python 2.6 to work in a frozen + application. Fixes #145, reported by Thomas Kluyver. + 2016-09-02: smarchetto [Scilab] Pointers are mapped to mlist instead of tlist (mlist better for scilab overloading) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 40d3d9a8a..fbae8f480 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -861,12 +861,13 @@ public: /* At here, the module may already loaded, so simply import it. */ Printf(f_shadow, tab4 tab8 "import %s\n", module); Printf(f_shadow, tab4 tab8 "return %s\n", module); - Printv(f_shadow, tab8 "if fp is not None:\n", NULL); - Printv(f_shadow, tab4 tab8 "try:\n", NULL); - Printf(f_shadow, tab8 tab8 "_mod = imp.load_module('%s', fp, pathname, description)\n", module); - Printv(f_shadow, tab4 tab8, "finally:\n", NULL); + Printv(f_shadow, tab8 "try:\n", NULL); + /* imp.load_module() handles fp being None. */ + Printf(f_shadow, tab4 tab8 "_mod = imp.load_module('%s', fp, pathname, description)\n", module); + Printv(f_shadow, tab8, "finally:\n", NULL); + Printv(f_shadow, tab4 tab8 "if fp is not None:\n", NULL); Printv(f_shadow, tab8 tab8, "fp.close()\n", NULL); - Printv(f_shadow, tab4 tab8, "return _mod\n", NULL); + Printv(f_shadow, tab8, "return _mod\n", NULL); Printf(f_shadow, tab4 "%s = swig_import_helper()\n", module); Printv(f_shadow, tab4, "del swig_import_helper\n", NULL); Printv(f_shadow, "else:\n", NULL); From 0f48af8a0544f0fd9aa0f6db7879831828d58b96 Mon Sep 17 00:00:00 2001 From: brgirgis Date: Sun, 11 Sep 2016 16:21:20 -0500 Subject: [PATCH 42/63] Fix one casting warning on Linux (#787) --- Lib/python/pyprimtypes.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/python/pyprimtypes.swg b/Lib/python/pyprimtypes.swg index 575b6db88..6a01af17c 100644 --- a/Lib/python/pyprimtypes.swg +++ b/Lib/python/pyprimtypes.swg @@ -312,7 +312,7 @@ SWIG_AsVal_dec(double)(PyObject *obj, double *val) return SWIG_OK; %#if PY_VERSION_HEX < 0x03000000 } else if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); + if (val) *val = (double) PyInt_AsLong(obj); return SWIG_OK; %#endif } else if (PyLong_Check(obj)) { From 87f14a96b5eb4b7c2e23b212ef38e20b9601d0b2 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 12 Sep 2016 08:18:51 +0100 Subject: [PATCH 43/63] Add changes entry for C# symbol renaming Closes #532 --- CHANGES.current | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 9554cf1a9..f6fee14ca 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,13 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-12: xypron + [C#] Patch #786 Keyword rename to be CLS compliant by adding an underscore + suffix instead of an underscore suffix to the C symbol name. Please use an explicit + %rename to rename the symbol with a _ prefix if you want the old symbol name. + + *** POTENTIAL INCOMPATIBILITY *** + 2016-09-09: olly [Python] Fix import handling for Python 2.6 to work in a frozen application. Fixes #145, reported by Thomas Kluyver. From 902f5d3f32e7408f0c964362e09515b28771a68a Mon Sep 17 00:00:00 2001 From: Marcin Wojdyr Date: Fri, 16 Sep 2016 02:26:35 +0200 Subject: [PATCH 44/63] cstrings.swg: fix function names inside comments (#790) --- Lib/typemaps/cstrings.swg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/typemaps/cstrings.swg b/Lib/typemaps/cstrings.swg index 7fe6a3f8f..0aca61101 100644 --- a/Lib/typemaps/cstrings.swg +++ b/Lib/typemaps/cstrings.swg @@ -203,7 +203,7 @@ * This macro is used to return Character data along with a size * parameter. * - * %cstring_output_maxsize(Char *outx, int *max) { + * %cstring_output_withsize(Char *outx, int *max) { * void foo(Char *outx, int *max) { * sprintf(outx,"blah blah\n"); * *max = strlen(outx); @@ -236,7 +236,7 @@ * This macro is used to return Character data that was * allocated with new or malloc. * - * %cstring_output_allocated(Char **outx, free($1)); + * %cstring_output_allocate(Char **outx, free($1)); * void foo(Char **outx) { * *outx = (Char *) malloc(512); * sprintf(outx,"blah blah\n"); @@ -263,7 +263,7 @@ * This macro is used to return Character data that was * allocated with new or malloc. * - * %cstring_output_allocated(Char **outx, int *sz, free($1)); + * %cstring_output_allocate_size(Char **outx, int *sz, free($1)); * void foo(Char **outx, int *sz) { * *outx = (Char *) malloc(512); * sprintf(outx,"blah blah\n"); From 26bbc96d58b81293a2357ba3ba7c4419d87417dd Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 9 Dec 2014 09:43:31 +1300 Subject: [PATCH 45/63] Arrange to return after calling zend_throw_exception() Fixes github issue#240. --- CHANGES.current | 4 + Examples/test-suite/common.mk | 1 + .../test-suite/php/swig_exception_runme.php | 33 +++++++ Examples/test-suite/swig_exception.i | 91 +++++++++++++++++++ Lib/exception.i | 2 +- Source/Modules/php.cxx | 3 + 6 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 Examples/test-suite/php/swig_exception_runme.php create mode 100644 Examples/test-suite/swig_exception.i diff --git a/CHANGES.current b/CHANGES.current index f6fee14ca..6d1db7d9f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-16: olly + [PHP] Fix SWIG_exception() macro to return from the current function. + Fixes #240, reported by Sergey Seroshtan. + 2016-09-12: xypron [C#] Patch #786 Keyword rename to be CLS compliant by adding an underscore suffix instead of an underscore suffix to the C symbol name. Please use an explicit diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index c40630b42..c57af4469 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -389,6 +389,7 @@ CPP_TEST_CASES += \ string_constants \ struct_initialization_cpp \ struct_value \ + swig_exception \ symbol_clash \ template_arg_replace \ template_arg_scope \ diff --git a/Examples/test-suite/php/swig_exception_runme.php b/Examples/test-suite/php/swig_exception_runme.php new file mode 100644 index 000000000..76641996e --- /dev/null +++ b/Examples/test-suite/php/swig_exception_runme.php @@ -0,0 +1,33 @@ +throwException(); + check::fail("Exception wasn't thrown"); +} catch (Exception $e) { + if ($e->getMessage() != "OK") { + check::fail("Exception getMessage() should be \"OK\", actually \"".$e->getMessage()."\""); + } +} + +# ----- Delete everything ----- + +$c = NULL; +$s = NULL; +$e = NULL; + +if (Shape::nshapes() != 0) { + check::fail("Shape::nshapes() should be 0, actually ".Shape::nshapes()); +} + +?> diff --git a/Examples/test-suite/swig_exception.i b/Examples/test-suite/swig_exception.i new file mode 100644 index 000000000..3cf8b406c --- /dev/null +++ b/Examples/test-suite/swig_exception.i @@ -0,0 +1,91 @@ +/* File : swig_exception.i + * Test SWIG_exception(). + */ +%module swig_exception + +%include exception.i + +%exception { + try { + $action + } catch (std::exception& e) { + SWIG_exception(SWIG_SystemError, e.what()); + } +} + +%inline %{ +class Value { + int a_; + int b_; +public: + Value(int a, int b) : a_(a), b_(b) {} +}; + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + } + double x, y; + void move(double dx, double dy); + virtual double area() = 0; + virtual double perimeter() = 0; + virtual Value throwException(); + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { } + virtual double area(); + virtual double perimeter(); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { } + virtual double area(); + virtual double perimeter(); +}; +%} + +%{ +#define PI 3.14159265358979323846 + +#include + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +Value Shape::throwException() { + throw std::logic_error("OK"); +} + +int Shape::nshapes = 0; + +double Circle::area() { + return PI*radius*radius; +} + +double Circle::perimeter() { + return 2*PI*radius; +} + +double Square::area() { + return width*width; +} + +double Square::perimeter() { + return 4*width; +} +%} diff --git a/Lib/exception.i b/Lib/exception.i index 437eee6f0..c2c9c47ef 100644 --- a/Lib/exception.i +++ b/Lib/exception.i @@ -15,7 +15,7 @@ #ifdef SWIGPHP %{ #include "zend_exceptions.h" -#define SWIG_exception(code, msg) zend_throw_exception(NULL, (char*)msg, code TSRMLS_CC) +#define SWIG_exception(code, msg) do { zend_throw_exception(NULL, (char*)msg, code TSRMLS_CC); goto thrown; } while (0) %} #endif diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 02bd827f8..d50246e36 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1000,6 +1000,7 @@ public: Delete(tm); } + Printf(f->code, "thrown:\n"); Printf(f->code, "return;\n"); /* Error handling code */ @@ -2356,6 +2357,7 @@ done: Append(f->code, actioncode); Delete(actioncode); + Printf(f->code, "thrown:\n"); Append(f->code, "return;\n"); Append(f->code, "fail:\n"); Append(f->code, "SWIG_FAIL(TSRMLS_C);\n"); @@ -2715,6 +2717,7 @@ done: Delete(outarg); } + Append(w->code, "thrown:\n"); if (!is_void) { if (!(ignored_method && !pure_virtual)) { String *rettype = SwigType_str(returntype, 0); From b138f054e516dcab02db066f5d56e2c7eb93c413 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Sat, 17 Sep 2016 17:29:42 +1200 Subject: [PATCH 46/63] [Javascript] Fix SWIG_exception() macro (#792) Fix SWIG_exception() macro to return from the current function. Fixes #789, reported by Julien Dutriaux. --- CHANGES.current | 4 +++ .../javascript/swig_exception_runme.js | 30 +++++++++++++++++++ Lib/javascript/jsc/javascriptcode.swg | 1 + Lib/javascript/jsc/javascripthelpers.swg | 2 +- Lib/javascript/jsc/javascriptrun.swg | 2 +- Lib/javascript/v8/javascriptcode.swg | 1 + Lib/javascript/v8/javascripthelpers.swg | 1 + Lib/javascript/v8/javascriptrun.swg | 2 +- 8 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 Examples/test-suite/javascript/swig_exception_runme.js diff --git a/CHANGES.current b/CHANGES.current index 6d1db7d9f..60f687a74 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-16: olly + [Javascript] Fix SWIG_exception() macro to return from the current + function. Fixes #789, reported by Julien Dutriaux. + 2016-09-16: olly [PHP] Fix SWIG_exception() macro to return from the current function. Fixes #240, reported by Sergey Seroshtan. diff --git a/Examples/test-suite/javascript/swig_exception_runme.js b/Examples/test-suite/javascript/swig_exception_runme.js new file mode 100644 index 000000000..55435e947 --- /dev/null +++ b/Examples/test-suite/javascript/swig_exception_runme.js @@ -0,0 +1,30 @@ +var swig_exception = require("swig_exception"); + +var c = new swig_exception.Circle(10); +var s = new swig_exception.Square(10); + +if (swig_exception.Shape.nshapes != 2) { + throw "Shape.nshapes should be 2, actually " + swig_exception.Shape.nshapes; +} + +// ----- Throw exception ----- +try { + c.throwException(); + throw "Exception wasn't thrown"; +} catch (e) { + if (e.message != "OK") { + throw "Exception message should be \"OK\", actually \"" + e.message + "\""; + } +} + +// ----- Delete everything ----- + +c = null; +s = null; +e = null; + +/* FIXME: Garbage collection needs to happen before this check will work. +if (swig_exception.Shape.nshapes != 0) { + throw "Shape.nshapes should be 0, actually " + swig_exception.Shape.nshapes; +} +*/ diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index d7f5f5212..4b21c98b2 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -32,6 +32,7 @@ static JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); +fail: return 0; } %} diff --git a/Lib/javascript/jsc/javascripthelpers.swg b/Lib/javascript/jsc/javascripthelpers.swg index 405280161..45765433e 100644 --- a/Lib/javascript/jsc/javascripthelpers.swg +++ b/Lib/javascript/jsc/javascripthelpers.swg @@ -53,7 +53,7 @@ SWIGINTERN bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObjec } else { SWIG_exception(SWIG_ERROR, msg); } - +fail: return false; } diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg index 676a45833..30ee032ed 100644 --- a/Lib/javascript/jsc/javascriptrun.swg +++ b/Lib/javascript/jsc/javascriptrun.swg @@ -4,7 +4,7 @@ * ---------------------------------------------------------------------------*/ #define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) -#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_exception(code, msg) do { SWIG_JSC_exception(context, exception, code, msg); SWIG_fail; } while (0) #define SWIG_fail goto fail SWIGRUNTIME void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 0bcb508f3..fb7d55c2a 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -36,6 +36,7 @@ static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) { SWIGV8_HANDLESCOPE(); SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); +fail: SWIGV8_RETURN(SWIGV8_UNDEFINED()); } %} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index f9901fb02..091467df4 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -83,6 +83,7 @@ SWIGRUNTIME void JS_veto_set_variable(v8::Local property, v8::Local< } else { SWIG_exception(SWIG_ERROR, msg); } +fail: ; } %} // v8_helper_functions diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg index 57c5afcd6..5ac52a51d 100644 --- a/Lib/javascript/v8/javascriptrun.swg +++ b/Lib/javascript/v8/javascriptrun.swg @@ -97,7 +97,7 @@ typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; * ---------------------------------------------------------------------------*/ #define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) -#define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_exception(code, msg) do { SWIGV8_ErrorHandler.error(code, msg); SWIG_fail; } while (0) #define SWIG_fail goto fail #define SWIGV8_OVERLOAD false From 2dc87d7485876d8a7a45d8136014695863e186de Mon Sep 17 00:00:00 2001 From: Daniel Vollmer Date: Sat, 17 Sep 2016 10:26:54 +0200 Subject: [PATCH 47/63] Add std::bad_cast to std_except.i This exception occurs when dynamic_cast fails. Fixes #783. --- Examples/test-suite/csharp/li_std_except_runme.cs | 1 + Examples/test-suite/li_std_except.i | 1 + Lib/csharp/std_except.i | 1 + Lib/d/std_except.i | 1 + Lib/go/std_except.i | 1 + Lib/java/std_except.i | 1 + Lib/lua/std_except.i | 1 + Lib/std/std_except.i | 4 ++++ Lib/std_except.i | 1 + 9 files changed, 12 insertions(+) diff --git a/Examples/test-suite/csharp/li_std_except_runme.cs b/Examples/test-suite/csharp/li_std_except_runme.cs index 86ab44892..c5ff26b6c 100644 --- a/Examples/test-suite/csharp/li_std_except_runme.cs +++ b/Examples/test-suite/csharp/li_std_except_runme.cs @@ -7,6 +7,7 @@ public class li_std_except_runme { public static void Main() { Test test = new Test(); + try { test.throw_bad_cast(); throw new Exception("throw_bad_cast failed"); } catch (InvalidCastException) {} try { test.throw_bad_exception(); throw new Exception("throw_bad_exception failed"); } catch (ApplicationException) {} try { test.throw_domain_error(); throw new Exception("throw_domain_error failed"); } catch (ApplicationException) {} try { test.throw_exception(); throw new Exception("throw_exception failed"); } catch (ApplicationException) {} diff --git a/Examples/test-suite/li_std_except.i b/Examples/test-suite/li_std_except.i index fc886dca7..b79d36bc1 100644 --- a/Examples/test-suite/li_std_except.i +++ b/Examples/test-suite/li_std_except.i @@ -24,6 +24,7 @@ int foo3() throw(E1) { return 0; } int foo4() throw(E2) { return 0; } // all the STL exceptions... + void throw_bad_cast() throw(std::bad_cast) { throw std::bad_cast(); } void throw_bad_exception() throw(std::bad_exception) { throw std::bad_exception(); } void throw_domain_error() throw(std::domain_error) { throw std::domain_error("oops"); } void throw_exception() throw(std::exception) { throw std::exception(); } diff --git a/Lib/csharp/std_except.i b/Lib/csharp/std_except.i index 27eb84bc2..1f6b2c483 100644 --- a/Lib/csharp/std_except.i +++ b/Lib/csharp/std_except.i @@ -16,6 +16,7 @@ namespace std struct exception {}; } +%typemap(throws, canthrow=1) std::bad_cast "SWIG_CSharpSetPendingException(SWIG_CSharpInvalidCastException, $1.what());\n return $null;" %typemap(throws, canthrow=1) std::bad_exception "SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, $1.what());\n return $null;" %typemap(throws, canthrow=1) std::domain_error "SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, $1.what());\n return $null;" %typemap(throws, canthrow=1) std::exception "SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, $1.what());\n return $null;" diff --git a/Lib/d/std_except.i b/Lib/d/std_except.i index 2b557e5fc..4a0ce6d69 100644 --- a/Lib/d/std_except.i +++ b/Lib/d/std_except.i @@ -16,6 +16,7 @@ namespace std struct exception {}; } +%typemap(throws, canthrow=1) std::bad_cast "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;" %typemap(throws, canthrow=1) std::bad_exception "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;" %typemap(throws, canthrow=1) std::domain_error "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;" %typemap(throws, canthrow=1) std::exception "SWIG_DSetPendingException(SWIG_DException, $1.what());\n return $null;" diff --git a/Lib/go/std_except.i b/Lib/go/std_except.i index 789a335f7..9439120e6 100644 --- a/Lib/go/std_except.i +++ b/Lib/go/std_except.i @@ -16,6 +16,7 @@ namespace std struct exception {}; } +%typemap(throws) std::bad_cast %{_swig_gopanic($1.what());%} %typemap(throws) std::bad_exception %{_swig_gopanic($1.what());%} %typemap(throws) std::domain_error %{_swig_gopanic($1.what());%} %typemap(throws) std::exception %{_swig_gopanic($1.what());%} diff --git a/Lib/java/std_except.i b/Lib/java/std_except.i index 9e23d50e6..b89ee617f 100644 --- a/Lib/java/std_except.i +++ b/Lib/java/std_except.i @@ -16,6 +16,7 @@ namespace std struct exception {}; } +%typemap(throws) std::bad_cast "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" %typemap(throws) std::bad_exception "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" %typemap(throws) std::domain_error "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" %typemap(throws) std::exception "SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1.what());\n return $null;" diff --git a/Lib/lua/std_except.i b/Lib/lua/std_except.i index 160828723..fd63663af 100644 --- a/Lib/lua/std_except.i +++ b/Lib/lua/std_except.i @@ -27,6 +27,7 @@ namespace std // normally objects which are thrown are returned to the interpreter as errors // (which potentially may have problems if they are not copied) // therefore all classes based upon std::exception are converted to their strings & returned as errors +%typemap(throws) std::bad_cast "SWIG_exception(SWIG_TypeError, $1.what());" %typemap(throws) std::bad_exception "SWIG_exception(SWIG_RuntimeError, $1.what());" %typemap(throws) std::domain_error "SWIG_exception(SWIG_ValueError, $1.what());" %typemap(throws) std::exception "SWIG_exception(SWIG_SystemError, $1.what());" diff --git a/Lib/std/std_except.i b/Lib/std/std_except.i index 75b8d0fd6..c8820c2c5 100644 --- a/Lib/std/std_except.i +++ b/Lib/std/std_except.i @@ -15,6 +15,10 @@ namespace std { virtual const char* what() const throw(); }; + struct bad_cast : exception + { + }; + struct bad_exception : exception { }; diff --git a/Lib/std_except.i b/Lib/std_except.i index a4a7a85ac..d070d1b9c 100644 --- a/Lib/std_except.i +++ b/Lib/std_except.i @@ -40,6 +40,7 @@ %enddef namespace std { + %std_exception_map(bad_cast, SWIG_TypeError); %std_exception_map(bad_exception, SWIG_SystemError); %std_exception_map(domain_error, SWIG_ValueError); %std_exception_map(exception, SWIG_SystemError); From ce1cb85d86eac2ad7f8704d056b5bb24cf7bff55 Mon Sep 17 00:00:00 2001 From: Daniel Vollmer Date: Sat, 17 Sep 2016 13:24:32 +0200 Subject: [PATCH 48/63] Add header for std::bad_cast --- Lib/csharp/std_except.i | 1 + Lib/d/std_except.i | 1 + Lib/exception.i | 3 +++ Lib/go/std_except.i | 1 + Lib/java/std_except.i | 1 + Lib/lua/std_except.i | 1 + Lib/std/std_except.i | 1 + Lib/std_except.i | 1 + 8 files changed, 10 insertions(+) diff --git a/Lib/csharp/std_except.i b/Lib/csharp/std_except.i index 1f6b2c483..c983bd0f6 100644 --- a/Lib/csharp/std_except.i +++ b/Lib/csharp/std_except.i @@ -7,6 +7,7 @@ * ----------------------------------------------------------------------------- */ %{ +#include #include %} diff --git a/Lib/d/std_except.i b/Lib/d/std_except.i index 4a0ce6d69..fbfd6c337 100644 --- a/Lib/d/std_except.i +++ b/Lib/d/std_except.i @@ -7,6 +7,7 @@ * ----------------------------------------------------------------------------- */ %{ +#include #include %} diff --git a/Lib/exception.i b/Lib/exception.i index c2c9c47ef..c8509987b 100644 --- a/Lib/exception.i +++ b/Lib/exception.i @@ -258,6 +258,7 @@ SWIGINTERN void SWIG_DThrowException(int code, const char *msg) { } */ %{ +#include #include %} %define SWIG_CATCH_STDEXCEPT @@ -274,6 +275,8 @@ SWIGINTERN void SWIG_DThrowException(int code, const char *msg) { SWIG_exception(SWIG_IndexError, e.what() ); } catch (std::runtime_error& e) { SWIG_exception(SWIG_RuntimeError, e.what() ); + } catch (std::bad_cast& e) { + SWIG_exception(SWIG_TypeError, e.what() ); } catch (std::exception& e) { SWIG_exception(SWIG_SystemError, e.what() ); } diff --git a/Lib/go/std_except.i b/Lib/go/std_except.i index 9439120e6..4f021a126 100644 --- a/Lib/go/std_except.i +++ b/Lib/go/std_except.i @@ -7,6 +7,7 @@ * ----------------------------------------------------------------------------- */ %{ +#include #include %} diff --git a/Lib/java/std_except.i b/Lib/java/std_except.i index b89ee617f..91d2f92cf 100644 --- a/Lib/java/std_except.i +++ b/Lib/java/std_except.i @@ -7,6 +7,7 @@ * ----------------------------------------------------------------------------- */ %{ +#include #include %} diff --git a/Lib/lua/std_except.i b/Lib/lua/std_except.i index fd63663af..34ab6a1ad 100644 --- a/Lib/lua/std_except.i +++ b/Lib/lua/std_except.i @@ -8,6 +8,7 @@ * ----------------------------------------------------------------------------- */ %{ +#include #include %} %include diff --git a/Lib/std/std_except.i b/Lib/std/std_except.i index c8820c2c5..728b9c8b5 100644 --- a/Lib/std/std_except.i +++ b/Lib/std/std_except.i @@ -3,6 +3,7 @@ #endif %{ +#include #include %} diff --git a/Lib/std_except.i b/Lib/std_except.i index d070d1b9c..50b5a88a2 100644 --- a/Lib/std_except.i +++ b/Lib/std_except.i @@ -24,6 +24,7 @@ #endif %{ +#include #include %} From 0769e9b7279a2ffd8c809892ac44f2e81924ca7c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 17 Sep 2016 17:53:48 +0100 Subject: [PATCH 49/63] Fix iterators for containers of NULL pointers (or Python None) when using -builtin. Previously iteration would stop at the first element that had a NULL pointer value. --- CHANGES.current | 4 ++++ .../python/li_std_vector_ptr_runme.py | 18 ++++++++++++++++++ .../test-suite/python/li_std_vector_runme.py | 6 ++++++ Lib/python/builtin.swg | 12 ------------ Source/Modules/python.cxx | 4 ++-- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 60f687a74..f9d3f82a8 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-17: wsfulton + [Python] Fix iterators for containers of NULL pointers (or Python None) when using + -builtin. Previously iteration would stop at the first element that was NULL. + 2016-09-16: olly [Javascript] Fix SWIG_exception() macro to return from the current function. Fixes #789, reported by Julien Dutriaux. diff --git a/Examples/test-suite/python/li_std_vector_ptr_runme.py b/Examples/test-suite/python/li_std_vector_ptr_runme.py index b49cdb4e9..baa92cfee 100644 --- a/Examples/test-suite/python/li_std_vector_ptr_runme.py +++ b/Examples/test-suite/python/li_std_vector_ptr_runme.py @@ -36,3 +36,21 @@ try: raise RuntimeError("missed exception") except TypeError: pass + +b111 = makeB(111) +bNones = BPtrVector([None, b111, None]) + +bCount = 0 +noneCount = 0 +for b in bNones: + if b == None: + noneCount = noneCount + 1 + else: + if b.val != 111: + raise RuntimeError("b.val is wrong") + bCount = bCount + 1 + +if bCount != 1: + raise RuntimeError("bCount wrong") +if noneCount != 2: + raise RuntimeError("noneCount wrong") diff --git a/Examples/test-suite/python/li_std_vector_runme.py b/Examples/test-suite/python/li_std_vector_runme.py index 68a6d0348..71460519d 100644 --- a/Examples/test-suite/python/li_std_vector_runme.py +++ b/Examples/test-suite/python/li_std_vector_runme.py @@ -2,3 +2,9 @@ from li_std_vector import * if typedef_test(101) != 101: raise RuntimeError + +try: + sv = StructVector([None, None]) + raise RuntimeError("Using None should result in a TypeError") +except TypeError: + pass diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index 1244dbbcc..f704bc485 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -199,18 +199,6 @@ wrapper##_closure(PyObject *a) { \ return result; \ } -#define SWIGPY_ITERNEXT_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *a) { \ - PyObject *result; \ - result = wrapper(a, NULL); \ - if (result && result == Py_None) { \ - Py_DECREF(result); \ - result = NULL; \ - } \ - return result; \ -} - #ifdef __cplusplus extern "C" { #endif diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index fbae8f480..1a3b886ab 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -200,7 +200,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE", "reprfunc", "SWIGPY_REPRFUNC_CLOSURE", "hashfunc", "SWIGPY_HASHFUNC_CLOSURE", - "iternextfunc", "SWIGPY_ITERNEXT_CLOSURE", + "iternextfunc", "SWIGPY_UNARYFUNC_CLOSURE", NULL }; @@ -219,7 +219,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE", "reprfunc", "SWIGPY_REPRFUNC_CLOSURE", "hashfunc", "SWIGPY_HASHFUNC_CLOSURE", - "iternextfunc", "SWIGPY_ITERNEXT_CLOSURE", + "iternextfunc", "SWIGPY_UNARYFUNC_CLOSURE", NULL }; From dd7a5a6e6ea41b9d00bab4b3548dd1ed8ccf60a3 Mon Sep 17 00:00:00 2001 From: Daniel Vollmer Date: Sat, 17 Sep 2016 19:01:42 +0200 Subject: [PATCH 50/63] Fix missed files --- Lib/guile/std_except.i | 1 + Lib/typemaps/std_except.swg | 1 + 2 files changed, 2 insertions(+) diff --git a/Lib/guile/std_except.i b/Lib/guile/std_except.i index 61bf481a3..6c30a319f 100644 --- a/Lib/guile/std_except.i +++ b/Lib/guile/std_except.i @@ -1,6 +1,7 @@ // TODO: STL exception handling // Note that the generic std_except.i file did not work %{ +#include #include %} diff --git a/Lib/typemaps/std_except.swg b/Lib/typemaps/std_except.swg index cb5ed3050..75d066490 100644 --- a/Lib/typemaps/std_except.swg +++ b/Lib/typemaps/std_except.swg @@ -20,6 +20,7 @@ %enddef namespace std { + %std_exception_map(bad_cast, SWIG_TypeError); %std_exception_map(bad_exception, SWIG_SystemError); %std_exception_map(domain_error, SWIG_ValueError); %std_exception_map(exception, SWIG_SystemError); From 1adfe2f53705a47d57421b8ff0dceaa1051966e1 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Sun, 25 Sep 2016 14:42:04 +1300 Subject: [PATCH 51/63] [PHP] Fix code generated for feature("director:except") Previously the return value of call_user_function() was ignored and we checked an uninitialised value instead. Fixes #627. Based on patch from Sergey Seroshtan. --- CHANGES.current | 6 ++++++ Examples/test-suite/director_exception.i | 15 +++++++++++++++ Source/Modules/php.cxx | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index f9d3f82a8..8483273d1 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,12 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-24: olly + [PHP] Fix code generated for feature("director:except") - + previously the return value of call_user_function() was ignored and + we checked an uninitialised value instead. Fixes #627. Based on + patch from Sergey Seroshtan. + 2016-09-17: wsfulton [Python] Fix iterators for containers of NULL pointers (or Python None) when using -builtin. Previously iteration would stop at the first element that was NULL. diff --git a/Examples/test-suite/director_exception.i b/Examples/test-suite/director_exception.i index 2559ae566..abe23b381 100644 --- a/Examples/test-suite/director_exception.i +++ b/Examples/test-suite/director_exception.i @@ -28,6 +28,21 @@ class DirectorMethodException: public Swig::DirectorException {}; %include "std_string.i" +#ifdef SWIGPHP + +%feature("director:except") { + if ($error == FAILURE) { + throw Swig::DirectorMethodException(); + } +} + +%exception { + try { $action } + catch (Swig::DirectorException &) { SWIG_fail; } +} + +#endif + #ifdef SWIGPYTHON %feature("director:except") { diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index d50246e36..ee78c6d0a 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -2625,6 +2625,7 @@ done: } /* exception handling */ + bool error_used_in_typemap = false; tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0); if (!tm) { tm = Getattr(n, "feature:director:except"); @@ -2634,6 +2635,7 @@ done: if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { if (Replaceall(tm, "$error", "error")) { /* Only declare error if it is used by the typemap. */ + error_used_in_typemap = true; Append(w->code, "int error;\n"); } } else { @@ -2657,6 +2659,9 @@ done: /* wrap complex arguments to zvals */ Printv(w->code, wrap_args, NIL); + if (error_used_in_typemap) { + Append(w->code, "error = "); + } Append(w->code, "call_user_function(EG(function_table), (zval**)&swig_self, &funcname,"); Printf(w->code, " %s, %d, args TSRMLS_CC);\n", Swig_cresult_name(), idx); From 848628ae914f1b185431ab5cbf83fa927c49df30 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 22 Sep 2016 08:12:46 +0100 Subject: [PATCH 52/63] More flexible python builtin slots The closure names used for builtin slots are mangled with their functype so that overloaded C++ method names can be used for multiple slots. For example: %feature("python:slot", "mp_subscript", functype="binaryfunc") SimpleArray::__getitem__; %feature("python:slot", "sq_item", functype="ssizeargfunc") SimpleArray::__getitem__(Py_ssize_t n); will generate closures: SWIGPY_SSIZEARGFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___ssizeargfunc_closure */ SWIGPY_BINARYFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___binaryfunc_closure */ --- CHANGES.current | 18 ++++++ .../test-suite/python/python_builtin_runme.py | 13 ++++ Examples/test-suite/python_builtin.i | 63 +++++++++++++++++++ Lib/python/builtin.swg | 42 ++++++++----- Source/Modules/python.cxx | 28 ++++++--- 5 files changed, 140 insertions(+), 24 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 8483273d1..eeeb08dfd 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -11,6 +11,24 @@ Version 3.0.11 (in progress) we checked an uninitialised value instead. Fixes #627. Based on patch from Sergey Seroshtan. +2016-09-22: wsfulton + [Python] More flexible python builtin slots for overloaded C++ function. + + The closure names used for builtin slots are mangled with their functype so + that overloaded C++ method names can be used for multiple slots. + For example: + + %feature("python:slot", "mp_subscript", functype="binaryfunc") SimpleArray::__getitem__; + %feature("python:slot", "sq_item", functype="ssizeargfunc") SimpleArray::__getitem__(Py_ssize_t n); + + will generate closures: + + SWIGPY_SSIZEARGFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___ssizeargfunc_closure */ + SWIGPY_BINARYFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___binaryfunc_closure */ + + Previously only one name was defined: _wrap_SimpleArray___getitem___closure. + Hence the overloaded __getitem__ method can be used to support both mp_subscript and sq_item slots. + 2016-09-17: wsfulton [Python] Fix iterators for containers of NULL pointers (or Python None) when using -builtin. Previously iteration would stop at the first element that was NULL. diff --git a/Examples/test-suite/python/python_builtin_runme.py b/Examples/test-suite/python/python_builtin_runme.py index 70990cbfd..dc46b63f5 100644 --- a/Examples/test-suite/python/python_builtin_runme.py +++ b/Examples/test-suite/python/python_builtin_runme.py @@ -79,3 +79,16 @@ if is_python_builtin(): if MyClass.less_than_counts != 6: raise RuntimeError("python:compare feature not working") +sa = SimpleArray(5) +elements = [x for x in sa] +if elements != [0, 10, 20, 30, 40]: + raise RuntimeError("Iteration not working") +if len(sa) != 5: + raise RuntimeError("len not working") +for i in range(5): + if sa[i] != i*10: + raise RuntimeError("indexing not working") +subslice = sa[1:3] +elements = [x for x in subslice] +if elements != [10, 20]: + raise RuntimeError("slice not working") diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i index e2c453d54..45654a014 100644 --- a/Examples/test-suite/python_builtin.i +++ b/Examples/test-suite/python_builtin.i @@ -136,3 +136,66 @@ void Dealloc2Destroyer(PyObject *v) { }; int MyClass::less_than_counts = 0; %} + +// Test 6 add in container __getitem__ to support basic sequence protocol +// Tests overloaded functions being used for more than one slot (mp_subscript and sq_item) +%include +%include +%apply int {Py_ssize_t} +%typemap(in) PySliceObject * { + if (!PySlice_Check($input)) + SWIG_exception(SWIG_TypeError, "in method '$symname', argument $argnum of type '$type'"); + $1 = (PySliceObject *)$input; +} +%typemap(typecheck,precedence=300) PySliceObject* { + $1 = PySlice_Check($input); +} + +%feature("python:slot", "mp_subscript", functype="binaryfunc") SimpleArray::__getitem__(PySliceObject *slice); +%feature("python:slot", "sq_item", functype="ssizeargfunc") SimpleArray::__getitem__(Py_ssize_t n); +%feature("python:slot", "sq_length", functype="lenfunc") SimpleArray::__len__; +%inline %{ + class SimpleArray { + size_t size; + int numbers[5]; + public: + SimpleArray(size_t size) : size(size) { + for (size_t x = 0; x= (int)size) + throw std::out_of_range("Index too large"); + return numbers[n]; + } + + SimpleArray __getitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) { + if (!PySlice_Check(slice)) + throw std::invalid_argument("Slice object expected"); + Py_ssize_t i, j, step; +#if PY_VERSION_HEX >= 0x03020000 + PySlice_GetIndices((PyObject *)slice, size, &i, &j, &step); +#else + PySlice_GetIndices((PySliceObject *)slice, size, &i, &j, &step); +#endif + if (step != 1) + throw std::invalid_argument("Only a step size of 1 is implemented"); + + { + Py_ssize_t ii = i<0 ? 0 : i>=size ? size-1 : i; + Py_ssize_t jj = j<0 ? 0 : j>=size ? size-1 : j; + if (ii > jj) + throw std::invalid_argument("getitem i should not be larger than j"); + SimpleArray n(jj-ii); + for (size_t x = 0; xdict); \ @@ -32,7 +32,7 @@ wrapper##_closure(PyObject *a) { \ #define SWIGPY_INQUIRY_CLOSURE(wrapper) \ SWIGINTERN int \ -wrapper##_closure(PyObject *a) { \ +wrapper##_inquiry_closure(PyObject *a) { \ PyObject *pyresult; \ int result; \ pyresult = wrapper(a, NULL); \ @@ -41,9 +41,15 @@ wrapper##_closure(PyObject *a) { \ return result; \ } +#define SWIGPY_GETITERFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_getiterfunc_closure(PyObject *a) { \ + return wrapper(a, NULL); \ +} + #define SWIGPY_BINARYFUNC_CLOSURE(wrapper) \ SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *a, PyObject *b) { \ +wrapper##_binaryfunc_closure(PyObject *a, PyObject *b) { \ PyObject *tuple, *result; \ tuple = PyTuple_New(1); \ assert(tuple); \ @@ -58,7 +64,7 @@ typedef ternaryfunc ternarycallfunc; #define SWIGPY_TERNARYFUNC_CLOSURE(wrapper) \ SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *a, PyObject *b, PyObject *c) { \ +wrapper##_ternaryfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \ PyObject *tuple, *result; \ tuple = PyTuple_New(2); \ assert(tuple); \ @@ -73,13 +79,13 @@ wrapper##_closure(PyObject *a, PyObject *b, PyObject *c) { \ #define SWIGPY_TERNARYCALLFUNC_CLOSURE(wrapper) \ SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *callable_object, PyObject *args, PyObject *) { \ +wrapper##_ternarycallfunc_closure(PyObject *callable_object, PyObject *args, PyObject *) { \ return wrapper(callable_object, args); \ } #define SWIGPY_LENFUNC_CLOSURE(wrapper) \ SWIGINTERN Py_ssize_t \ -wrapper##_closure(PyObject *a) { \ +wrapper##_lenfunc_closure(PyObject *a) { \ PyObject *resultobj; \ Py_ssize_t result; \ resultobj = wrapper(a, NULL); \ @@ -90,7 +96,7 @@ wrapper##_closure(PyObject *a) { \ #define SWIGPY_SSIZESSIZEARGFUNC_CLOSURE(wrapper) \ SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \ +wrapper##_ssizessizeargfunc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \ PyObject *tuple, *result; \ tuple = PyTuple_New(2); \ assert(tuple); \ @@ -103,7 +109,7 @@ wrapper##_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \ #define SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE(wrapper) \ SWIGINTERN int \ -wrapper##_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \ +wrapper##_ssizessizeobjargproc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \ PyObject *tuple, *resultobj; \ int result; \ tuple = PyTuple_New(d ? 3 : 2); \ @@ -123,7 +129,7 @@ wrapper##_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \ #define SWIGPY_SSIZEARGFUNC_CLOSURE(wrapper) \ SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *a, Py_ssize_t b) { \ +wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ PyObject *tuple, *result; \ tuple = PyTuple_New(1); \ assert(tuple); \ @@ -135,7 +141,7 @@ wrapper##_closure(PyObject *a, Py_ssize_t b) { \ #define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \ SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *a, Py_ssize_t b) { \ +wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ PyObject *arg, *result; \ arg = _PyLong_FromSsize_t(b); \ result = wrapper(a, arg); \ @@ -145,7 +151,7 @@ wrapper##_closure(PyObject *a, Py_ssize_t b) { \ #define SWIGPY_SSIZEOBJARGPROC_CLOSURE(wrapper) \ SWIGINTERN int \ -wrapper##_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \ +wrapper##_ssizeobjargproc_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \ PyObject *tuple, *resultobj; \ int result; \ tuple = PyTuple_New(2); \ @@ -162,7 +168,7 @@ wrapper##_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \ #define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \ SWIGINTERN int \ -wrapper##_closure(PyObject *a, PyObject *b, PyObject *c) { \ +wrapper##_objobjargproc_closure(PyObject *a, PyObject *b, PyObject *c) { \ PyObject *tuple, *resultobj; \ int result; \ tuple = PyTuple_New(c ? 2 : 1); \ @@ -182,13 +188,13 @@ wrapper##_closure(PyObject *a, PyObject *b, PyObject *c) { \ #define SWIGPY_REPRFUNC_CLOSURE(wrapper) \ SWIGINTERN PyObject * \ -wrapper##_closure(PyObject *a) { \ +wrapper##_reprfunc_closure(PyObject *a) { \ return wrapper(a, NULL); \ } #define SWIGPY_HASHFUNC_CLOSURE(wrapper) \ SWIGINTERN Py_hash_t \ -wrapper##_closure(PyObject *a) { \ +wrapper##_hashfunc_closure(PyObject *a) { \ PyObject *pyresult; \ Py_hash_t result; \ pyresult = wrapper(a, NULL); \ @@ -199,6 +205,12 @@ wrapper##_closure(PyObject *a) { \ return result; \ } +#define SWIGPY_ITERNEXTFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_iternextfunc_closure(PyObject *a) { \ + return wrapper(a, NULL); \ +} + #ifdef __cplusplus extern "C" { #endif diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 1a3b886ab..380cd98d5 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -47,11 +47,13 @@ static Hash *f_shadow_imports = 0; static String *f_shadow_builtin_imports = 0; static String *f_shadow_stubs = 0; static Hash *builtin_getset = 0; +static Hash *builtin_closures = 0; static Hash *class_members = 0; static File *f_builtins = 0; static String *builtin_tp_init = 0; static String *builtin_methods = 0; static String *builtin_default_unref = 0; +static String *builtin_closures_code = 0; static String *methods; static String *class_name; @@ -188,7 +190,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE", "destructor", "SWIGPY_DESTRUCTOR_CLOSURE", "inquiry", "SWIGPY_INQUIRY_CLOSURE", - "getiterfunc", "SWIGPY_UNARYFUNC_CLOSURE", + "getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE", "binaryfunc", "SWIGPY_BINARYFUNC_CLOSURE", "ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE", "ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE", @@ -200,7 +202,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE", "reprfunc", "SWIGPY_REPRFUNC_CLOSURE", "hashfunc", "SWIGPY_HASHFUNC_CLOSURE", - "iternextfunc", "SWIGPY_UNARYFUNC_CLOSURE", + "iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE", NULL }; @@ -208,7 +210,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE", "destructor", "SWIGPY_DESTRUCTOR_CLOSURE", "inquiry", "SWIGPY_INQUIRY_CLOSURE", - "getiterfunc", "SWIGPY_UNARYFUNC_CLOSURE", + "getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE", "ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE", "ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE", "lenfunc", "SWIGPY_LENFUNC_CLOSURE", @@ -219,7 +221,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) { "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE", "reprfunc", "SWIGPY_REPRFUNC_CLOSURE", "hashfunc", "SWIGPY_HASHFUNC_CLOSURE", - "iternextfunc", "SWIGPY_UNARYFUNC_CLOSURE", + "iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE", NULL }; @@ -626,6 +628,8 @@ public: f_directors_h = NewString(""); f_directors = NewString(""); builtin_getset = NewHash(); + builtin_closures = NewHash(); + builtin_closures_code = NewString(""); class_members = NewHash(); builtin_methods = NewString(""); builtin_default_unref = NewString("delete $self;"); @@ -3328,11 +3332,12 @@ public: String *func_type = Getattr(n, "feature:python:slot:functype"); String *closure_decl = getClosure(func_type, wrapper_name, overname ? 0 : funpack); String *feature_name = NewStringf("feature:python:%s", slot); - String *closure_name = Copy(wrapper_name); + String *closure_name = 0; if (closure_decl) { - Append(closure_name, "_closure"); - if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling")) - Printf(f_wrappers, "%s /* defines %s */\n\n", closure_decl, closure_name); + closure_name = NewStringf("%s_%s_closure", wrapper_name, func_type); + if (!GetFlag(builtin_closures, closure_name)) + Printf(builtin_closures_code, "%s /* defines %s */\n\n", closure_decl, closure_name); + SetFlag(builtin_closures, closure_name); Delete(closure_decl); } if (func_type) { @@ -4511,7 +4516,12 @@ public: SwigType *realct = Copy(real_classname); SwigType_add_pointer(realct); SwigType_remember(realct); - if (!builtin) { + if (builtin) { + Printv(f_wrappers, builtin_closures_code, NIL); + Delete(builtin_closures_code); + builtin_closures_code = NewString(""); + Clear(builtin_closures); + } else { Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL); Printv(f_wrappers, " PyObject *obj;\n", NIL); if (modernargs) { From 777c825cd22993b5348db5ccc85455e93f84881f Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Sep 2016 08:15:34 +0100 Subject: [PATCH 53/63] Rework Python builtin CLOSURE macros The new approach uses support functions and minimal code in the macros to make debugging easier. --- Lib/python/builtin.swg | 530 +++++++++++++++++++++++------------------ 1 file changed, 303 insertions(+), 227 deletions(-) diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index d3bb3be4c..314d2b385 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -1,234 +1,7 @@ -#define SWIGPY_UNARYFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_unaryfunc_closure(PyObject *a) { \ - return wrapper(a, NULL); \ -} - -#define SWIGPY_DESTRUCTOR_CLOSURE(wrapper) \ -SWIGINTERN void \ -wrapper##_destructor_closure(PyObject *a) { \ - SwigPyObject *sobj; \ - sobj = (SwigPyObject *)a; \ - Py_XDECREF(sobj->dict); \ - if (sobj->own) { \ - PyObject *o; \ - PyObject *val = 0, *type = 0, *tb = 0; \ - PyErr_Fetch(&val, &type, &tb); \ - o = wrapper(a, NULL); \ - if (!o) { \ - PyObject *deallocname = PyString_FromString(#wrapper); \ - PyErr_WriteUnraisable(deallocname); \ - Py_DECREF(deallocname); \ - } \ - PyErr_Restore(val, type, tb); \ - Py_XDECREF(o); \ - } \ - if (PyType_IS_GC(a->ob_type)) { \ - PyObject_GC_Del(a); \ - } else { \ - PyObject_Del(a); \ - } \ -} - -#define SWIGPY_INQUIRY_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_inquiry_closure(PyObject *a) { \ - PyObject *pyresult; \ - int result; \ - pyresult = wrapper(a, NULL); \ - result = pyresult && PyObject_IsTrue(pyresult) ? 1 : 0; \ - Py_XDECREF(pyresult); \ - return result; \ -} - -#define SWIGPY_GETITERFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_getiterfunc_closure(PyObject *a) { \ - return wrapper(a, NULL); \ -} - -#define SWIGPY_BINARYFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_binaryfunc_closure(PyObject *a, PyObject *b) { \ - PyObject *tuple, *result; \ - tuple = PyTuple_New(1); \ - assert(tuple); \ - PyTuple_SET_ITEM(tuple, 0, b); \ - Py_XINCREF(b); \ - result = wrapper(a, tuple); \ - Py_DECREF(tuple); \ - return result; \ -} - -typedef ternaryfunc ternarycallfunc; - -#define SWIGPY_TERNARYFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ternaryfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \ - PyObject *tuple, *result; \ - tuple = PyTuple_New(2); \ - assert(tuple); \ - PyTuple_SET_ITEM(tuple, 0, b); \ - PyTuple_SET_ITEM(tuple, 1, c); \ - Py_XINCREF(b); \ - Py_XINCREF(c); \ - result = wrapper(a, tuple); \ - Py_DECREF(tuple); \ - return result; \ -} - -#define SWIGPY_TERNARYCALLFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ternarycallfunc_closure(PyObject *callable_object, PyObject *args, PyObject *) { \ - return wrapper(callable_object, args); \ -} - -#define SWIGPY_LENFUNC_CLOSURE(wrapper) \ -SWIGINTERN Py_ssize_t \ -wrapper##_lenfunc_closure(PyObject *a) { \ - PyObject *resultobj; \ - Py_ssize_t result; \ - resultobj = wrapper(a, NULL); \ - result = PyNumber_AsSsize_t(resultobj, NULL); \ - Py_DECREF(resultobj); \ - return result; \ -} - -#define SWIGPY_SSIZESSIZEARGFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ssizessizeargfunc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \ - PyObject *tuple, *result; \ - tuple = PyTuple_New(2); \ - assert(tuple); \ - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \ - PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); \ - result = wrapper(a, tuple); \ - Py_DECREF(tuple); \ - return result; \ -} - -#define SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_ssizessizeobjargproc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \ - PyObject *tuple, *resultobj; \ - int result; \ - tuple = PyTuple_New(d ? 3 : 2); \ - assert(tuple); \ - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \ - PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); \ - if (d) { \ - PyTuple_SET_ITEM(tuple, 2, d); \ - Py_INCREF(d); \ - } \ - resultobj = wrapper(a, tuple); \ - result = resultobj ? 0 : -1; \ - Py_DECREF(tuple); \ - Py_XDECREF(resultobj); \ - return result; \ -} - -#define SWIGPY_SSIZEARGFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ - PyObject *tuple, *result; \ - tuple = PyTuple_New(1); \ - assert(tuple); \ - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \ - result = wrapper(a, tuple); \ - Py_DECREF(tuple); \ - return result; \ -} - -#define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ - PyObject *arg, *result; \ - arg = _PyLong_FromSsize_t(b); \ - result = wrapper(a, arg); \ - Py_DECREF(arg); \ - return result; \ -} - -#define SWIGPY_SSIZEOBJARGPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_ssizeobjargproc_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \ - PyObject *tuple, *resultobj; \ - int result; \ - tuple = PyTuple_New(2); \ - assert(tuple); \ - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); \ - PyTuple_SET_ITEM(tuple, 1, c); \ - Py_XINCREF(c); \ - resultobj = wrapper(a, tuple); \ - result = resultobj ? 0 : -1; \ - Py_XDECREF(resultobj); \ - Py_DECREF(tuple); \ - return result; \ -} - -#define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_objobjargproc_closure(PyObject *a, PyObject *b, PyObject *c) { \ - PyObject *tuple, *resultobj; \ - int result; \ - tuple = PyTuple_New(c ? 2 : 1); \ - assert(tuple); \ - PyTuple_SET_ITEM(tuple, 0, b); \ - Py_XINCREF(b); \ - if (c) { \ - PyTuple_SET_ITEM(tuple, 1, c); \ - Py_XINCREF(c); \ - } \ - resultobj = wrapper(a, tuple); \ - result = resultobj ? 0 : -1; \ - Py_XDECREF(resultobj); \ - Py_DECREF(tuple); \ - return result; \ -} - -#define SWIGPY_REPRFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_reprfunc_closure(PyObject *a) { \ - return wrapper(a, NULL); \ -} - -#define SWIGPY_HASHFUNC_CLOSURE(wrapper) \ -SWIGINTERN Py_hash_t \ -wrapper##_hashfunc_closure(PyObject *a) { \ - PyObject *pyresult; \ - Py_hash_t result; \ - pyresult = wrapper(a, NULL); \ - if (!pyresult) \ - return -1; \ - result = SWIG_PyNumber_AsPyHash(pyresult); \ - Py_DECREF(pyresult); \ - return result; \ -} - -#define SWIGPY_ITERNEXTFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_iternextfunc_closure(PyObject *a) { \ - return wrapper(a, NULL); \ -} - #ifdef __cplusplus extern "C" { #endif -SWIGINTERN int -SwigPyBuiltin_BadInit(PyObject *self, PyObject *SWIGUNUSEDPARM(args), PyObject *SWIGUNUSEDPARM(kwds)) { - PyErr_Format(PyExc_TypeError, "Cannot create new instances of type '%.300s'", self->ob_type->tp_name); - return -1; -} - -SWIGINTERN void -SwigPyBuiltin_BadDealloc(PyObject *obj) { - SwigPyObject *sobj = (SwigPyObject *)obj; - if (sobj->own) { - PyErr_Format(PyExc_TypeError, "Swig detected a memory leak in type '%.300s': no callable destructor found.", obj->ob_type->tp_name); - } -} - SWIGINTERN Py_hash_t SwigPyObject_hash(PyObject *obj) { SwigPyObject *sobj = (SwigPyObject *)obj; @@ -251,6 +24,20 @@ SWIG_PyNumber_AsPyHash(PyObject *obj) { return result; } +SWIGINTERN int +SwigPyBuiltin_BadInit(PyObject *self, PyObject *SWIGUNUSEDPARM(args), PyObject *SWIGUNUSEDPARM(kwds)) { + PyErr_Format(PyExc_TypeError, "Cannot create new instances of type '%.300s'", self->ob_type->tp_name); + return -1; +} + +SWIGINTERN void +SwigPyBuiltin_BadDealloc(PyObject *obj) { + SwigPyObject *sobj = (SwigPyObject *)obj; + if (sobj->own) { + PyErr_Format(PyExc_TypeError, "Swig detected a memory leak in type '%.300s': no callable destructor found.", obj->ob_type->tp_name); + } +} + typedef struct { PyCFunction get; PyCFunction set; @@ -547,6 +334,295 @@ SwigPyBuiltin_SetMetaType (PyTypeObject *type, PyTypeObject *metatype) #endif } + +/* Start of callback function macros for use in PyTypeObject */ + +typedef PyObject *(*SwigPyWrapperFunction)(PyObject *, PyObject *); + +#define SWIGPY_UNARYFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_unaryfunc_closure(PyObject *a) { \ + return SwigPyBuiltin_unaryfunc_closure(wrapper, a); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_unaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { + return wrapper(a, NULL); +} + +#define SWIGPY_DESTRUCTOR_CLOSURE(wrapper) \ +SWIGINTERN void \ +wrapper##_destructor_closure(PyObject *a) { \ + SwigPyBuiltin_destructor_closure(wrapper, #wrapper, a); \ +} +SWIGINTERN void +SwigPyBuiltin_destructor_closure(SwigPyWrapperFunction wrapper, const char *wrappername, PyObject *a) { + SwigPyObject *sobj; + sobj = (SwigPyObject *)a; + Py_XDECREF(sobj->dict); + if (sobj->own) { + PyObject *o; + PyObject *val = 0, *type = 0, *tb = 0; + PyErr_Fetch(&val, &type, &tb); + o = wrapper(a, NULL); + if (!o) { + PyObject *deallocname = PyString_FromString(wrappername); + PyErr_WriteUnraisable(deallocname); + Py_DECREF(deallocname); + } + PyErr_Restore(val, type, tb); + Py_XDECREF(o); + } + if (PyType_IS_GC(a->ob_type)) { + PyObject_GC_Del(a); + } else { + PyObject_Del(a); + } +} + +#define SWIGPY_INQUIRY_CLOSURE(wrapper) \ +SWIGINTERN int \ +wrapper##_inquiry_closure(PyObject *a) { \ + return SwigPyBuiltin_inquiry_closure(wrapper, a); \ +} +SWIGINTERN int +SwigPyBuiltin_inquiry_closure(SwigPyWrapperFunction wrapper, PyObject *a) { + PyObject *pyresult; + int result; + pyresult = wrapper(a, NULL); + result = pyresult && PyObject_IsTrue(pyresult) ? 1 : 0; + Py_XDECREF(pyresult); + return result; +} + +#define SWIGPY_GETITERFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_getiterfunc_closure(PyObject *a) { \ + return SwigPyBuiltin_getiterfunc_closure(wrapper, a); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_getiterfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { + return wrapper(a, NULL); +} + +#define SWIGPY_BINARYFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_binaryfunc_closure(PyObject *a, PyObject *b) { \ + return SwigPyBuiltin_binaryfunc_closure(wrapper, a, b); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_binaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) { + PyObject *tuple, *result; + tuple = PyTuple_New(1); + assert(tuple); + PyTuple_SET_ITEM(tuple, 0, b); + Py_XINCREF(b); + result = wrapper(a, tuple); + Py_DECREF(tuple); + return result; +} + +typedef ternaryfunc ternarycallfunc; + +#define SWIGPY_TERNARYFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_ternaryfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \ + return SwigPyBuiltin_ternaryfunc_closure(wrapper, a, b, c); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_ternaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) { + PyObject *tuple, *result; + tuple = PyTuple_New(2); + assert(tuple); + PyTuple_SET_ITEM(tuple, 0, b); + PyTuple_SET_ITEM(tuple, 1, c); + Py_XINCREF(b); + Py_XINCREF(c); + result = wrapper(a, tuple); + Py_DECREF(tuple); + return result; +} + +#define SWIGPY_TERNARYCALLFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_ternarycallfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \ + return SwigPyBuiltin_ternarycallfunc_closure(wrapper, a, b, c); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_ternarycallfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) { + (void) c; + return wrapper(a, b); +} + +#define SWIGPY_LENFUNC_CLOSURE(wrapper) \ +SWIGINTERN Py_ssize_t \ +wrapper##_lenfunc_closure(PyObject *a) { \ + return SwigPyBuiltin_lenfunc_closure(wrapper, a); \ +} +SWIGINTERN Py_ssize_t +SwigPyBuiltin_lenfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { + PyObject *resultobj; + Py_ssize_t result; + resultobj = wrapper(a, NULL); + result = PyNumber_AsSsize_t(resultobj, NULL); + Py_DECREF(resultobj); + return result; +} + +#define SWIGPY_SSIZESSIZEARGFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_ssizessizeargfunc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \ + return SwigPyBuiltin_ssizessizeargfunc_closure(wrapper, a, b, c); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_ssizessizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, Py_ssize_t c) { + PyObject *tuple, *result; + tuple = PyTuple_New(2); + assert(tuple); + PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); + PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); + result = wrapper(a, tuple); + Py_DECREF(tuple); + return result; +} + +#define SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE(wrapper) \ +SWIGINTERN int \ +wrapper##_ssizessizeobjargproc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \ + return SwigPyBuiltin_ssizessizeobjargproc_closure(wrapper, a, b, c, d); \ +} +SWIGINTERN int +SwigPyBuiltin_ssizessizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { + PyObject *tuple, *resultobj; + int result; + tuple = PyTuple_New(d ? 3 : 2); + assert(tuple); + PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); + PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); + if (d) { + PyTuple_SET_ITEM(tuple, 2, d); + Py_INCREF(d); + } + resultobj = wrapper(a, tuple); + result = resultobj ? 0 : -1; + Py_DECREF(tuple); + Py_XDECREF(resultobj); + return result; +} + +#define SWIGPY_SSIZEARGFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ + return SwigPyBuiltin_funpack_ssizeargfunc_closure(wrapper, a, b); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_funpack_ssizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b) { + PyObject *tuple, *result; + tuple = PyTuple_New(1); + assert(tuple); + PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); + result = wrapper(a, tuple); + Py_DECREF(tuple); + return result; +} + +#define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ + return SwigPyBuiltin_ssizeargfunc_closure(wrapper, a, b); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_ssizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b) { + PyObject *arg, *result; + arg = _PyLong_FromSsize_t(b); + result = wrapper(a, arg); + Py_DECREF(arg); + return result; +} + +#define SWIGPY_SSIZEOBJARGPROC_CLOSURE(wrapper) \ +SWIGINTERN int \ +wrapper##_ssizeobjargproc_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \ + return SwigPyBuiltin_ssizeobjargproc_closure(wrapper, a, b, c); \ +} +SWIGINTERN int +SwigPyBuiltin_ssizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, PyObject *c) { + PyObject *tuple, *resultobj; + int result; + tuple = PyTuple_New(2); + assert(tuple); + PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); + PyTuple_SET_ITEM(tuple, 1, c); + Py_XINCREF(c); + resultobj = wrapper(a, tuple); + result = resultobj ? 0 : -1; + Py_XDECREF(resultobj); + Py_DECREF(tuple); + return result; +} + +#define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \ +SWIGINTERN int \ +wrapper##_objobjargproc_closure(PyObject *a, PyObject *b, PyObject *c) { \ + return SwigPyBuiltin_objobjargproc_closure(wrapper, a, b, c); \ +} +SWIGINTERN int +SwigPyBuiltin_objobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) { + PyObject *tuple, *resultobj; + int result; + tuple = PyTuple_New(c ? 2 : 1); + assert(tuple); + PyTuple_SET_ITEM(tuple, 0, b); + Py_XINCREF(b); + if (c) { + PyTuple_SET_ITEM(tuple, 1, c); + Py_XINCREF(c); + } + resultobj = wrapper(a, tuple); + result = resultobj ? 0 : -1; + Py_XDECREF(resultobj); + Py_DECREF(tuple); + return result; +} + +#define SWIGPY_REPRFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_reprfunc_closure(PyObject *a) { \ + return SwigPyBuiltin_reprfunc_closure(wrapper, a); \ +} +SWIGINTERN PyObject * +SwigPyBuiltin_reprfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { + return wrapper(a, NULL); +} + +#define SWIGPY_HASHFUNC_CLOSURE(wrapper) \ +SWIGINTERN Py_hash_t \ +wrapper##_hashfunc_closure(PyObject *a) { \ + return SwigPyBuiltin_hashfunc_closure(wrapper, a); \ +} +SWIGINTERN Py_hash_t +SwigPyBuiltin_hashfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { + PyObject *pyresult; + Py_hash_t result; + pyresult = wrapper(a, NULL); + if (!pyresult) + return -1; + result = SWIG_PyNumber_AsPyHash(pyresult); + Py_DECREF(pyresult); + return result; +} + +#define SWIGPY_ITERNEXTFUNC_CLOSURE(wrapper) \ +SWIGINTERN PyObject * \ +wrapper##_iternextfunc_closure(PyObject *a) { \ + return SwigPyBuiltin_iternextfunc_closure(wrapper, a);\ +} +SWIGINTERN PyObject * +SwigPyBuiltin_iternextfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { + return wrapper(a, NULL); +} + +/* End of callback function macros for use in PyTypeObject */ + #ifdef __cplusplus } #endif From d3f7fd965c822bea53e95f39f30648867084e4d5 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 25 Sep 2016 14:20:00 +0100 Subject: [PATCH 54/63] Add bad_cast enhancement to changes file --- CHANGES.current | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index eeeb08dfd..a27b73de2 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-25: wsfulton + Patch #793 from q-p to expand exception handling to include std::bad_cast + in std_except.i. + 2016-09-24: olly [PHP] Fix code generated for feature("director:except") - previously the return value of call_user_function() was ignored and From 0c09b00d6e489f71e2ddd899213b0778ed45520e Mon Sep 17 00:00:00 2001 From: Simon Marchetto Date: Mon, 26 Sep 2016 11:54:17 +0200 Subject: [PATCH 55/63] scilab: mlists that map pointers can be given a custom type name --- CHANGES.current | 3 +++ Lib/scilab/scipointer.swg | 4 ++-- Lib/scilab/scirun.swg | 16 +++++++++------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index a27b73de2..11f364f5c 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-26: smarchetto + [Scilab] mlists that map pointers can be given a custom type name. + 2016-09-25: wsfulton Patch #793 from q-p to expand exception handling to include std::bad_cast in std_except.i. diff --git a/Lib/scilab/scipointer.swg b/Lib/scilab/scipointer.swg index 8d0526d4d..94ca4ef37 100644 --- a/Lib/scilab/scipointer.swg +++ b/Lib/scilab/scipointer.swg @@ -6,7 +6,7 @@ } %fragment("SWIG_NewPointerObj", "header") { -#define SWIG_NewPointerObj(pointer, pointerDescriptor, flags) SwigScilabPtrFromObject(pvApiCtx, SWIG_Scilab_GetOutputPosition(), pointer, pointerDescriptor, flags) +#define SWIG_NewPointerObj(pointer, pointerDescriptor, flags) SwigScilabPtrFromObject(pvApiCtx, SWIG_Scilab_GetOutputPosition(), pointer, pointerDescriptor, flags, NULL) } /* @@ -17,7 +17,7 @@ } %fragment("SWIG_NewFunctionPtrObj", "header") { -#define SWIG_NewFunctionPtrObj(pointer, pointerDescriptor) SwigScilabPtrFromObject(pvApiCtx, SWIG_Scilab_GetOutputPosition(), pointer, pointerDescriptor, 0) +#define SWIG_NewFunctionPtrObj(pointer, pointerDescriptor) SwigScilabPtrFromObject(pvApiCtx, SWIG_Scilab_GetOutputPosition(), pointer, pointerDescriptor, 0, NULL) } // No fragment used here, the functions "SwigScilabPtrToObject" and "SwigScilabPtrFromObject" are defined in sciruntime.swg diff --git a/Lib/scilab/scirun.swg b/Lib/scilab/scirun.swg index 58c313df7..3b8289199 100644 --- a/Lib/scilab/scirun.swg +++ b/Lib/scilab/scirun.swg @@ -142,10 +142,10 @@ SwigScilabCheckPtr(void *pvApiCtx, int iVar, swig_type_info *descriptor, char *f if (descriptor) { swig_cast_info *cast = SWIG_TypeCheck(SWIG_TypeName((swig_type_info*)pvTypeinfo), descriptor); return (cast != NULL); - } + } else { return SWIG_ERROR; - } + } } else { return (iType == sci_pointer); @@ -232,12 +232,11 @@ SwigScilabPtrToObject(void *pvApiCtx, int iVar, void **pvObj, swig_type_info *de } SWIGRUNTIMEINLINE int -SwigScilabPtrFromObject(void *pvApiCtx, int iVarOut, void *pvObj, swig_type_info *descriptor, int flags) { +SwigScilabPtrFromObject(void *pvApiCtx, int iVarOut, void *pvObj, swig_type_info *descriptor, int flags, const char *pstTypeName) { SciErr sciErr; if (descriptor) { int *piMListAddr = NULL; - const char *pstString; sciErr = createMList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, 3, &piMListAddr); if (sciErr.iErr) { @@ -245,8 +244,11 @@ SwigScilabPtrFromObject(void *pvApiCtx, int iVarOut, void *pvObj, swig_type_info return SWIG_ERROR; } - pstString = SWIG_TypeName(descriptor); - sciErr = createMatrixOfStringInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piMListAddr, 1, 1, 1, &pstString); + if (pstTypeName == NULL) { + pstTypeName = SWIG_TypeName(descriptor); + } + + sciErr = createMatrixOfStringInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piMListAddr, 1, 1, 1, &pstTypeName); if (sciErr.iErr) { printError(&sciErr, 0); return SWIG_ERROR; @@ -451,7 +453,7 @@ int SWIG_ptr(SWIG_GatewayParameters) { } SWIG_Scilab_SetOutputPosition(1); return SWIG_Scilab_SetOutput(pvApiCtx, - SwigScilabPtrFromObject(pvApiCtx, 1, (void *) (uintptr_t)dValue, NULL, 0)); + SwigScilabPtrFromObject(pvApiCtx, 1, (void *) (uintptr_t)dValue, NULL, 0, NULL)); } else { return SWIG_ERROR; From 457ea5d209228b279051b3d4637b625ef1eb4898 Mon Sep 17 00:00:00 2001 From: Simon Marchetto Date: Mon, 26 Sep 2016 13:55:45 +0200 Subject: [PATCH 56/63] scilab: remove compilation warnings --- Lib/scilab/scibool.swg | 1 - Lib/scilab/scisequencebool.swg | 2 +- Lib/scilab/scisequencestring.swg | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/scilab/scibool.swg b/Lib/scilab/scibool.swg index ea7938dc8..9aed88eca 100644 --- a/Lib/scilab/scibool.swg +++ b/Lib/scilab/scibool.swg @@ -125,7 +125,6 @@ SWIG_SciBoolean_AsIntArrayAndSize(void *pvApiCtx, int iVar, int *iRows, int *iCo } if (isBooleanType(pvApiCtx, piAddrVar)) { - int i; sciErr = getMatrixOfBoolean(pvApiCtx, piAddrVar, iRows, iCols, piValue); if (sciErr.iErr) { printError(&sciErr, 0); diff --git a/Lib/scilab/scisequencebool.swg b/Lib/scilab/scisequencebool.swg index 0430c3e39..b7d078448 100644 --- a/Lib/scilab/scisequencebool.swg +++ b/Lib/scilab/scisequencebool.swg @@ -84,7 +84,7 @@ SWIG_FromSet_Sequence_dec(bool)(int size, int *pSequence) { SWIGINTERN bool SWIG_AsVal_SequenceItem_dec(bool)(SwigSciObject obj, int *pSequence, int iItemIndex) { - return pSequence[iItemIndex]; + return (bool) pSequence[iItemIndex]; } } diff --git a/Lib/scilab/scisequencestring.swg b/Lib/scilab/scisequencestring.swg index 36f0927a8..d3c05e4f8 100644 --- a/Lib/scilab/scisequencestring.swg +++ b/Lib/scilab/scisequencestring.swg @@ -1,5 +1,5 @@ /* - *char + * * Scilab matrix of string <-> C++ std::string container * */ @@ -88,7 +88,7 @@ SWIG_AsVal_SequenceItem_dec(std::string)(SwigSciObject obj, char **pSequence, in SWIGINTERN int SWIG_From_SequenceItem_dec(std::string)(char **pSequence, int iItemIndex, std::string itemValue) { - char *pChar = new char(itemValue.size() + 1); + char *pChar = new char((int) itemValue.size() + 1); strcpy(pChar, itemValue.c_str()); pSequence[iItemIndex] = pChar; return SWIG_OK; From bac85d5b1a1f25cd031076eb53233b2ccba8e9ea Mon Sep 17 00:00:00 2001 From: Li Shengqiu Date: Tue, 27 Sep 2016 10:08:47 +0800 Subject: [PATCH 57/63] [Go] Fix argument names in inherited functions #795 (#797) * [Go] Fix argument names in inherited functions #795 This commit fixes a wrong argument name replacement in the inherited functions as well as a memory leak. * Add testcase for #795 * Move variable_replacement testcase into common * Move variable_replacement testcase into common --- Examples/test-suite/common.mk | 1 + Examples/test-suite/variable_replacement.i | 16 ++++++++++++++++ Source/Modules/go.cxx | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Examples/test-suite/variable_replacement.i diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index c57af4469..6e4034cb1 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -520,6 +520,7 @@ CPP_TEST_CASES += \ valuewrapper_opaque \ varargs \ varargs_overload \ + variable_replacement \ virtual_destructor \ virtual_poly \ virtual_vs_nonvirtual_base \ diff --git a/Examples/test-suite/variable_replacement.i b/Examples/test-suite/variable_replacement.i new file mode 100644 index 000000000..d44ac1b96 --- /dev/null +++ b/Examples/test-suite/variable_replacement.i @@ -0,0 +1,16 @@ +%module variable_replacement + +%inline %{ + +class A { +public: + int a(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12) + { + return 0; + } +}; + +class B : public A { +}; + +%} diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 7fa9b2670..128888acf 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -2445,7 +2445,8 @@ private: } String *code = Copy(Getattr(n, "wrap:action")); - Replaceall(code, Getattr(parms, "lname"), current); + Replace(code, Getattr(parms, "lname"), current, DOH_REPLACE_ANY | DOH_REPLACE_ID); + Delete(current); Printv(actioncode, code, "\n", NULL); } From bbebd1a012341f511e01f24343ad0f2efe9c9565 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 27 Sep 2016 15:13:10 +1300 Subject: [PATCH 58/63] Add entry for #795 fix --- CHANGES.current | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 11f364f5c..8802c8e96 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-27: dontpanic92 + [Go] Fix argument names in inherited functions taking more than 8 + parameters. Fixes #795. + 2016-09-26: smarchetto [Scilab] mlists that map pointers can be given a custom type name. From 2d871655e37d2e587a935aaba5023735767f291e Mon Sep 17 00:00:00 2001 From: ahmed-usman Date: Mon, 26 Sep 2016 22:15:47 -0400 Subject: [PATCH 59/63] Update xml.cxx to return typenames (#777) Typenames were being returned wrong, so add a condition to handle templateparms correctly. --- Source/Modules/xml.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx index a69e7b043..5f090561a 100644 --- a/Source/Modules/xml.cxx +++ b/Source/Modules/xml.cxx @@ -144,8 +144,8 @@ public: Xml_print_kwargs(Getattr(obj, k)); } else if (Cmp(k, "parms") == 0 || Cmp(k, "pattern") == 0) { Xml_print_parmlist(Getattr(obj, k)); - } else if (Cmp(k, "catchlist") == 0) { - Xml_print_parmlist(Getattr(obj, k), "catchlist"); + } else if (Cmp(k, "catchlist") == 0 || Cmp(k, "templateparms") == 0) { + Xml_print_parmlist(Getattr(obj, k), Char(k)); } else { DOH *o; print_indent(0); From 209074dfff2704efd88566dce220dde2abbf9812 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 27 Sep 2016 15:17:51 +1300 Subject: [PATCH 60/63] Add entry for PR #777 Give up waiting for the submitter to. --- CHANGES.current | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 8802c8e96..ea66de5d5 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-27: ahmed-usman + [xml] Handle template parameters correctly. + 2016-09-27: dontpanic92 [Go] Fix argument names in inherited functions taking more than 8 parameters. Fixes #795. From 7bfa5fb9518b6499b244549fe416eb5149166131 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 27 Sep 2016 08:12:49 +0100 Subject: [PATCH 61/63] Temporarily remove OSX testing of Guile on Travis Seems like OSX 10.9 is now too old for homebrew and Guile --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac97dc6b5..bcf231725 100644 --- a/.travis.yml +++ b/.travis.yml @@ -162,9 +162,6 @@ matrix: - compiler: clang os: osx env: SWIGLANG=go - - compiler: clang - os: osx - env: SWIGLANG=guile - compiler: clang os: osx env: SWIGLANG=java @@ -199,6 +196,10 @@ matrix: - compiler: gcc os: linux env: SWIGLANG=python SWIG_FEATURES=-O + # brew install guile fails on Travis as OSX 10.9 is too old now, default osx_image needs changing + - compiler: clang + os: osx + env: SWIGLANG=guile before_install: - date -u - uname -a From 08688d7d9df55529b29426fc065779ca108e7c36 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 29 Sep 2016 08:06:22 +0100 Subject: [PATCH 62/63] Add support for "ret" typemap where missing and improve documentation on it. --- CHANGES.current | 5 +++ Doc/Manual/Contents.html | 1 + Doc/Manual/Typemaps.html | 48 ++++++++++++++++++++++++--- Examples/test-suite/typemap_various.i | 34 ++++++++++++------- Source/Modules/allegrocl.cxx | 7 ++++ Source/Modules/cffi.cxx | 8 +++++ Source/Modules/go.cxx | 8 +++++ Source/Modules/javascript.cxx | 5 +++ Source/Modules/ocaml.cxx | 8 +++++ Source/Modules/r.cxx | 7 ++++ Source/Modules/scilab.cxx | 9 ++++- 11 files changed, 123 insertions(+), 17 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index ea66de5d5..148fd17af 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.11 (in progress) ============================ +2016-09-29: wsfulton + [Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab] + Add missing support for the "ret" typemap in a few target languages. + The documentation also now has info on the "ret" typemap. + 2016-09-27: ahmed-usman [xml] Handle template parameters correctly. diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 3f283ecb9..0bde863be 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -457,6 +457,7 @@

  • "argout" typemap
  • "freearg" typemap
  • "newfree" typemap +
  • "ret" typemap
  • "memberin" typemap
  • "varin" typemap
  • "varout" typemap diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index b074e9f94..309984b50 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -63,6 +63,7 @@
  • "argout" typemap
  • "freearg" typemap
  • "newfree" typemap +
  • "ret" typemap
  • "memberin" typemap
  • "varin" typemap
  • "varout" typemap @@ -2802,7 +2803,46 @@ string *foo(); See Object ownership and %newobject for further details.

    -

    11.5.10 "memberin" typemap

    +

    11.5.10 "ret" typemap

    + + +

    +The "ret" typemap is not used very often, but can be useful for anything associated with +the return type, such as resource management, return value error checking, etc. +Usually this can all be done in the "out" typemap, but sometimes it is handy to use the +"out" typemap code untouched and add to the generated code using the code in the "ret" typemap. +One such case is memory clean up. For example, a stringheap_t type is defined indicating +that the returned memory must be deleted and a string_t type is defined indicating +that the returned memory must not be deleted. +

    + +
    +
    +%typemap(ret) stringheap_t %{
    +  free($1);
    +%}
    +
    +typedef char * string_t;
    +typedef char * stringheap_t;
    +
    +string_t MakeString1();
    +stringheap_t MakeString2();
    +
    +
    + +

    +The "ret" typemap above will only be used for MakeString2, but both functions +will use the default "out" typemap for char * provided by SWIG. +The code above would ensure the appropriate memory is freed in all target languages as the need +to provide custom "out" typemaps (which involve target language specific code) is not necessary. +

    + +

    +This approach is an alternative to using the "newfree" typemap and %newobject as there +is no need to list all the functions that require the memory cleanup, it is purely done on types. +

    + +

    11.5.11 "memberin" typemap

    @@ -2824,7 +2864,7 @@ It is rarely necessary to write "memberin" typemaps---SWIG already provides a default implementation for arrays, strings, and other objects.

    -

    11.5.11 "varin" typemap

    +

    11.5.12 "varin" typemap

    @@ -2832,7 +2872,7 @@ The "varin" typemap is used to convert objects in the target language to C for t purposes of assigning to a C/C++ global variable. This is implementation specific.

    -

    11.5.12 "varout" typemap

    +

    11.5.13 "varout" typemap

    @@ -2840,7 +2880,7 @@ The "varout" typemap is used to convert a C/C++ object to an object in the targe language when reading a C/C++ global variable. This is implementation specific.

    -

    11.5.13 "throws" typemap

    +

    11.5.14 "throws" typemap

    diff --git a/Examples/test-suite/typemap_various.i b/Examples/test-suite/typemap_various.i index c2f70ce55..3436bac1c 100644 --- a/Examples/test-suite/typemap_various.i +++ b/Examples/test-suite/typemap_various.i @@ -25,23 +25,33 @@ void foo1(Foo f, const Foo& ff) {} void foo2(Foo f, const Foo& ff) {} %} -#ifdef SWIGUTL -%typemap(ret) int Bar1::foo() { /* hello1 */ }; -%typemap(ret) int Bar2::foo() { /* hello2 */ }; -%typemap(ret) int foo() {/* hello3 */ }; -#endif +// Check "ret" typemap is implemented +%{ + template struct NeededForTest {}; +%} +%fragment("NeededForTest", "header") %{ + template<> struct NeededForTest { NeededForTest(short) {} }; +%} + +%typemap(ret) short "_ret_typemap_for_short_no_compile" +%typemap(ret, fragment="NeededForTest") short Bar1::foofunction() { /* ret typemap for short */ NeededForTest needed($1); }; +%typemap(ret, fragment="NeededForTest") short globalfoofunction() { /* ret typemap for short */ NeededForTest needed($1); }; %inline %{ struct Bar1 { - int foo() { return 1;} - }; - - struct Bar2 { - int foo() { return 1;} + short foofunction() { return 1;} }; + short globalfoofunction() { return 1;} %} - +%{ +void CheckRetTypemapUsed() { + // If the "ret" typemap is not used, the NeededForTest template specialization will not have been + // generated and so the following code will result in a compile failure + NeededForTest needed(111); + (void)needed; +} +%} %newobject FFoo::Bar(bool) const ; %typemap(newfree) char* Bar(bool) { @@ -62,7 +72,7 @@ void foo2(Foo f, const Foo& ff) {} #endif // Test obscure bug where named typemaps where not being applied when symbol name contained a number -%typemap(out) double "_typemap_for_double_no_compile_" +%typemap(out) double "_out_typemap_for_double_no_compile_" %typemap(out) double ABCD::meth {$1 = 0.0; TYPEMAP_OUT_INIT} %typemap(out) double ABCD::m1 {$1 = 0.0; TYPEMAP_OUT_INIT} %typemap(out) double ABCD::_x2 {$1 = 0.0; TYPEMAP_OUT_INIT} diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx index b69e1dd70..77f1319c7 100644 --- a/Source/Modules/allegrocl.cxx +++ b/Source/Modules/allegrocl.cxx @@ -2722,6 +2722,13 @@ int ALLEGROCL::functionWrapper(Node *n) { } } + /* See if there is any return cleanup code */ + if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { + Replaceall(tm, "$source", Swig_cresult_name()); + Printf(f->code, "%s\n", tm); + Delete(tm); + } + emit_return_variable(n, t, f); if (CPlusPlus) { diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx index c355e452a..bf3338813 100644 --- a/Source/Modules/cffi.cxx +++ b/Source/Modules/cffi.cxx @@ -543,6 +543,14 @@ int CFFI::functionWrapper(Node *n) { cleanupFunction(n, f, parms); + /* See if there is any return cleanup code */ + String *tm = 0; + if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { + Replaceall(tm, "$source", Swig_cresult_name()); + Printf(f->code, "%s\n", tm); + Delete(tm); + } + if (!is_void_return) { Printf(f->code, " return lresult;\n"); } diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 128888acf..d370b886e 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -2599,6 +2599,14 @@ private: Replaceall(f->code, "$cleanup", cleanup); Delete(cleanup); + /* See if there is any return cleanup code */ + String *tm; + if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { + Replaceall(tm, "$source", Swig_cresult_name()); + Printf(f->code, "%s\n", tm); + Delete(tm); + } + Replaceall(f->code, "$symname", Getattr(n, "sym:name")); } diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 6f0fb3afd..4e7a7912f 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1354,6 +1354,11 @@ void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { } } + /* See if there is any return cleanup code */ + if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { + Printf(wrapper->code, "%s\n", tm); + Delete(tm); + } } int JSEmitter::switchNamespace(Node *n) { diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 9df6a9551..73dd14f96 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -676,6 +676,14 @@ public: Printv(f->code, tm, "\n", NIL); } } + + /* See if there is any return cleanup code */ + if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { + Replaceall(tm, "$source", Swig_cresult_name()); + Printf(f->code, "%s\n", tm); + Delete(tm); + } + // Free any memory allocated by the function being wrapped.. if ((tm = Swig_typemap_lookup("swig_result", n, Swig_cresult_name(), 0))) { diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 301b49f9e..95d6b96f2 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -2097,6 +2097,13 @@ int R::functionWrapper(Node *n) { } } + /* See if there is any return cleanup code */ + if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { + Replaceall(tm, "$source", Swig_cresult_name()); + Printf(f->code, "%s\n", tm); + Delete(tm); + } + Printv(f->code, UnProtectWrapupCode, NIL); /*If the user gave us something to convert the result in */ diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index c44c92d6c..5997b5876 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -412,7 +412,7 @@ public: emit_return_variable(node, functionReturnType, wrapper); /* Return the function value if necessary */ - String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, "result", wrapper, functionActionCode); + String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, Swig_cresult_name(), wrapper, functionActionCode); if (functionReturnTypemap) { // Result is actually the position of output value on stack if (Len(functionReturnTypemap) > 0) { @@ -471,6 +471,13 @@ public: } } + /* See if there is any return cleanup code */ + String *tm; + if ((tm = Swig_typemap_lookup("ret", node, Swig_cresult_name(), 0))) { + Replaceall(tm, "$source", Swig_cresult_name()); + Printf(wrapper->code, "%s\n", tm); + Delete(tm); + } /* Close the function(ok) */ Printv(wrapper->code, "return SWIG_OK;\n", NIL); From 08e32e794c992459f6429b3e6af8d75e1aab0d89 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 30 Sep 2016 18:07:33 +0100 Subject: [PATCH 63/63] Add further documentation/info on the smartptr feature to the shared_ptr library file [skip ci] --- Lib/shared_ptr.i | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/shared_ptr.i b/Lib/shared_ptr.i index 450493db4..2975b0628 100644 --- a/Lib/shared_ptr.i +++ b/Lib/shared_ptr.i @@ -4,6 +4,13 @@ // to use a pointer to the smart pointer of the type, rather than the usual pointer to the underlying type. // So for some type T, shared_ptr * is used rather than T *. +// Another key part of the implementation is the smartptr feature: +// %feature("smartptr") T { shared_ptr } +// This feature marks the class T as having a smartptr to it (the shared_ptr type). This is then used to +// support smart pointers and inheritance. Say class D derives from base B, then shared_ptr is marked +// with a fake inheritance from shared_ptr in the type system if the "smartptr" feature is used on both +// B and D. This is to emulate the conversion of shared_ptr to shared_ptr in the target language. + // shared_ptr namespaces could be boost or std or std::tr1 // For example for std::tr1, use: // #define SWIG_SHARED_PTR_NAMESPACE std