From 82a6fe02e3772e6f09097a221fbb5756b622318e Mon Sep 17 00:00:00 2001
From: Rokas Kupstys
Date: Thu, 6 Sep 2018 14:21:54 +0300
Subject: [PATCH 001/662] Improve correctness of SwigDerivedClassHasMethod() by
making sure only methods that have `override` are used connected by director.
C# does not treat `virtual` methods of child classes as overriding (ass opposed to c++). In order to override a method it must have `override` specified.
Previous version of this method treated `virtual void foo()` or `void foo()` in a subclass as methods that override virtual method of parent class. This resulted in `SwigDirectorConnect()` creating delegates and connecting them to a native class. Presence of such methods caused needless roundtrip through managed layer while in the end correct native function was called.
This is the old code flow:
```cpp
void SwigDirector_MyClass::nonOverride() {
if (!swig_callbacknonOverride) { // 0. swig_callbacknonOverride is set
MyClass::nonOverride();
return;
} else {
swig_callbacknonOverride(); // 1. this is called because wrapper mistakenly assumes overriding
}
}
SWIGEXPORT void SWIGSTDCALL CSharp_director_basicNamespace_MyClass_nonOverrideSwigExplicitMyClass(void * jarg1) {
MyClass *arg1 = (MyClass *) 0 ;
arg1 = (MyClass *)jarg1;
(arg1)->MyClass::nonOverride(); // 5. Correct method called in the end
}
```
```cs
private void SwigDirectornonOverride() {
nonOverride(); // 2.
}
public virtual void nonOverride() {
if (SwigDerivedClassHasMethod("nonOverride", swigMethodTypes4)) // 3. This returns `true`
director_basicPINVOKE.MyClass_nonOverrideSwigExplicitMyClass(swigCPtr); // 4. Native method of director class called explicitly
else
director_basicPINVOKE.MyClass_nonOverride(swigCPtr);
}
```
This is the new code flow:
```cpp
void SwigDirector_MyClass::nonOverride() {
if (!swig_callbacknonOverride) { // 0. swig_callbacknonOverride is not set
MyClass::nonOverride(); // 1. Calls correct method immediately
return;
} else {
swig_callbacknonOverride();
}
}
```
---
Source/Modules/csharp.cxx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index bd00ffaf3..75ee34023 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -1953,7 +1953,7 @@ public:
Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n");
Printf(proxy_class_code,
" global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
- Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(%s));\n", proxy_class_name);
+ Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.IsVirtual && methodInfo.DeclaringType.IsSubclassOf(typeof(%s)) && methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType;\n", proxy_class_name);
/* Could add this code to cover corner case where the GetMethod() returns a method which allows type
* promotion, eg it will return foo(double), if looking for foo(int).
if (hasDerivedMethod) {
From 15f9403e06989cd1f6f592bbe52c1a735f94372b Mon Sep 17 00:00:00 2001
From: Rokas Kupstys
Date: Wed, 26 Sep 2018 12:20:38 +0300
Subject: [PATCH 002/662] Fix expanded director_basic test.
Since we are mixing `new` and `override` a class instance may have multiple methods with the same name. in case of director_basic test one method comes from `MyClassMiddle` (one that participates in dynamic dispatch) and one comes from `MyClassEnd` (one with `new` keyword). Therefore all methods have to be checked.
---
Source/Modules/csharp.cxx | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index 75ee34023..2fa3eff25 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -1951,9 +1951,32 @@ public:
// Only emit if there is at least one director method
Printf(proxy_class_code, "\n");
Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n");
- Printf(proxy_class_code,
- " global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
- Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.IsVirtual && methodInfo.DeclaringType.IsSubclassOf(typeof(%s)) && methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType;\n", proxy_class_name);
+ Printf(proxy_class_code, " global::System.Reflection.MethodInfo[] methodInfos = this.GetType().GetMethods(\n");
+ Printf(proxy_class_code, " global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance);\n");
+ Printf(proxy_class_code, " foreach (global::System.Reflection.MethodInfo methodInfo in methodInfos) {\n");
+ Printf(proxy_class_code, " if (methodInfo.DeclaringType == null)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " if (methodInfo.Name != methodName)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " var parameters = methodInfo.GetParameters();\n");
+ Printf(proxy_class_code, " if (parameters.Length != methodTypes.Length)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " bool parametersMatch = true;\n");
+ Printf(proxy_class_code, " for (var i = 0; i < parameters.Length; i++) {\n");
+ Printf(proxy_class_code, " if (parameters[i].ParameterType != methodTypes[i]) {\n");
+ Printf(proxy_class_code, " parametersMatch = false;\n");
+ Printf(proxy_class_code, " break;\n");
+ Printf(proxy_class_code, " }\n");
+ Printf(proxy_class_code, " }\n\n");
+ Printf(proxy_class_code, " if (!parametersMatch)\n");
+ Printf(proxy_class_code, " continue;\n\n");
+ Printf(proxy_class_code, " if (methodInfo.IsVirtual && (methodInfo.DeclaringType.IsSubclassOf(typeof(%s))) &&\n", proxy_class_name);
+ Printf(proxy_class_code, " methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType) {\n");
+ Printf(proxy_class_code, " return true;\n");
+ Printf(proxy_class_code, " }\n");
+ Printf(proxy_class_code, " }\n\n");
+ Printf(proxy_class_code, " return false;\n");
+
/* Could add this code to cover corner case where the GetMethod() returns a method which allows type
* promotion, eg it will return foo(double), if looking for foo(int).
if (hasDerivedMethod) {
@@ -1973,7 +1996,7 @@ public:
}
}
*/
- Printf(proxy_class_code, " return hasDerivedMethod;\n");
+ //Printf(proxy_class_code, " return hasDerivedMethod;\n");
Printf(proxy_class_code, " }\n");
}
From c1258323b113033988240d3838f0001608163876 Mon Sep 17 00:00:00 2001
From: Seth R Johnson
Date: Tue, 9 May 2017 14:36:14 -0400
Subject: [PATCH 003/662] Fix missing include in SWIG typemap
---
Lib/carrays.i | 6 ++++++
Lib/cdata.i | 4 +++-
Lib/cpointer.i | 6 ++++++
Lib/swig.swg | 36 ++++++++++++++++++++----------------
4 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/Lib/carrays.i b/Lib/carrays.i
index 3a9c3cfee..0aa3eee89 100644
--- a/Lib/carrays.i
+++ b/Lib/carrays.i
@@ -5,6 +5,12 @@
* pointers as arrays.
* ----------------------------------------------------------------------------- */
+#ifndef __cplusplus
+// C uses free/calloc/malloc
+%include "swigfragments.swg"
+%fragment("");
+#endif
+
/* -----------------------------------------------------------------------------
* %array_functions(TYPE,NAME)
*
diff --git a/Lib/cdata.i b/Lib/cdata.i
index 23b7211e7..e058fe28b 100644
--- a/Lib/cdata.i
+++ b/Lib/cdata.i
@@ -68,7 +68,7 @@ static jbyteArray SWIG_JavaArrayOutCDATA(JNIEnv *jenv, char *result, jsize sz) {
/* -----------------------------------------------------------------------------
- * %cdata(TYPE [, NAME])
+ * %cdata(TYPE [, NAME])
*
* Convert raw C data to a binary string.
* ----------------------------------------------------------------------------- */
@@ -107,6 +107,8 @@ SWIGCDATA cdata_##NAME(TYPE *ptr, int nelements);
%cdata(void);
+%fragment("");
+
/* Memory move function. Due to multi-argument typemaps this appears to be wrapped as
void memmove(void *data, const char *s); */
void memmove(void *data, const void *indata, int inlen);
diff --git a/Lib/cpointer.i b/Lib/cpointer.i
index 881c511fc..5eca6fae1 100644
--- a/Lib/cpointer.i
+++ b/Lib/cpointer.i
@@ -5,6 +5,12 @@
* pointer objects.
* ----------------------------------------------------------------------------- */
+#ifndef __cplusplus
+// C uses free/calloc/malloc
+%include "swigfragments.swg"
+%fragment("");
+#endif
+
/* -----------------------------------------------------------------------------
* %pointer_class(type,name)
*
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 6dc215dcf..c215e8d89 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -442,6 +442,10 @@ namespace std {
* Default char * and C array typemaps
* ----------------------------------------------------------------------------- */
+%fragment("", "runtime") %{
+#include
+%}
+
/* Set up the typemap for handling new return strings */
#ifdef __cplusplus
@@ -453,7 +457,7 @@ namespace std {
/* Default typemap for handling char * members */
#ifdef __cplusplus
-%typemap(memberin) char * {
+%typemap(memberin,fragment="") char * {
delete [] $1;
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
@@ -462,7 +466,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="") const char * {
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
strcpy((char *)$1, (const char *)$input);
@@ -470,7 +474,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin) char * {
+%typemap(globalin,fragment="") char * {
delete [] $1;
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
@@ -479,7 +483,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="") const char * {
if ($input) {
$1 = ($1_type) (new char[strlen((const char *)$input)+1]);
strcpy((char *)$1, (const char *)$input);
@@ -488,7 +492,7 @@ namespace std {
}
}
#else
-%typemap(memberin) char * {
+%typemap(memberin,fragment="") char * {
free($1);
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
@@ -497,7 +501,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="") const char * {
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
strcpy((char *)$1, (const char *)$input);
@@ -505,7 +509,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin) char * {
+%typemap(globalin,fragment="") char * {
free($1);
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
@@ -514,7 +518,7 @@ namespace std {
$1 = 0;
}
}
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="") const char * {
if ($input) {
$1 = ($1_type) malloc(strlen((const char *)$input)+1);
strcpy((char *)$1, (const char *)$input);
@@ -527,7 +531,7 @@ namespace std {
/* Character array handling */
-%typemap(memberin) char [ANY] {
+%typemap(memberin,fragment="") char [ANY] {
if($input) {
strncpy((char*)$1, (const char *)$input, $1_dim0-1);
$1[$1_dim0-1] = 0;
@@ -536,7 +540,7 @@ namespace std {
}
}
-%typemap(globalin) char [ANY] {
+%typemap(globalin,fragment="") char [ANY] {
if($input) {
strncpy((char*)$1, (const char *)$input, $1_dim0-1);
$1[$1_dim0-1] = 0;
@@ -545,25 +549,25 @@ namespace std {
}
}
-%typemap(memberin) char [] {
+%typemap(memberin,fragment="") char [] {
if ($input) strcpy((char *)$1, (const char *)$input);
else $1[0] = 0;
}
-%typemap(globalin) char [] {
+%typemap(globalin,fragment="") char [] {
if ($input) strcpy((char *)$1, (const char *)$input);
else $1[0] = 0;
}
/* memberin/globalin typemap for arrays. */
-%typemap(memberin) SWIGTYPE [ANY] {
+%typemap(memberin,fragment="") SWIGTYPE [ANY] {
size_t ii;
$1_basetype *b = ($1_basetype *) $1;
for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii);
}
-%typemap(globalin) SWIGTYPE [ANY] {
+%typemap(globalin,fragment="") SWIGTYPE [ANY] {
size_t ii;
$1_basetype *b = ($1_basetype *) $1;
for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii);
@@ -571,7 +575,7 @@ namespace std {
/* memberin/globalin typemap for double arrays. */
-%typemap(memberin) SWIGTYPE [ANY][ANY] {
+%typemap(memberin,fragment="") SWIGTYPE [ANY][ANY] {
$basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input);
$basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1);
size_t ii = 0;
@@ -583,7 +587,7 @@ namespace std {
}
}
-%typemap(globalin) SWIGTYPE [ANY][ANY] {
+%typemap(globalin,fragment="") SWIGTYPE [ANY][ANY] {
$basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input);
$basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1);
size_t ii = 0;
From feeb2516aedfc19fdc1eefe233dec9bc5593fe2b Mon Sep 17 00:00:00 2001
From: Seth R Johnson
Date: Tue, 7 Nov 2017 18:35:00 -0500
Subject: [PATCH 004/662] "Include what you use" for tests
Many of these tests implicitly required the target language library files to include the headers upstream.
---
Examples/test-suite/default_args.i | 59 ++++++++++---------
Examples/test-suite/director_thread.i | 2 +-
Examples/test-suite/li_cdata.i | 4 ++
Examples/test-suite/li_cdata_cpp.i | 4 ++
Examples/test-suite/li_std_except.i | 2 +
Examples/test-suite/memberin_extend.i | 1 +
Examples/test-suite/mod.h | 2 +-
Examples/test-suite/namespace_typemap.i | 1 +
Examples/test-suite/nested_extend_c.i | 4 ++
Examples/test-suite/operator_overload_break.i | 1 +
Examples/test-suite/operator_pointer_ref.i | 2 +
.../test-suite/smart_pointer_const_overload.i | 4 ++
Examples/test-suite/special_variable_macros.i | 2 +
Examples/test-suite/string_simple.i | 1 +
.../testdir/inctest/subdir2/hello.i | 1 +
Examples/test-suite/threads.i | 1 +
Examples/test-suite/typedef_struct.i | 1 +
17 files changed, 61 insertions(+), 31 deletions(-)
diff --git a/Examples/test-suite/default_args.i b/Examples/test-suite/default_args.i
index 6b680f561..2f8fdbbd2 100644
--- a/Examples/test-suite/default_args.i
+++ b/Examples/test-suite/default_args.i
@@ -18,6 +18,7 @@
%{
#define TESTCASE_THROW1(T1)
#define TESTCASE_THROW2(T1, T2)
+#include
%}
%include
@@ -71,7 +72,7 @@
class EnumClass {
public:
enum speed { FAST, SLOW };
- // Note: default values should be EnumClass::FAST and SWEET
+ // Note: default values should be EnumClass::FAST and SWEET
bool blah(speed s = FAST, flavor f = SWEET) { return (s == FAST && f == SWEET); };
};
@@ -83,16 +84,16 @@
// casts
const char * casts1(const char *m = (const char *) NULL) {
- char *ret = NULL;
- if (m) {
+ char *ret = NULL;
+ if (m) {
ret = new char[strlen(m)+1];
strcpy(ret, m);
}
return ret;
}
const char * casts2(const char *m = (const char *) "Hello") {
- char *ret = NULL;
- if (m) {
+ char *ret = NULL;
+ if (m) {
ret = new char[strlen(m)+1];
strcpy(ret, m);
}
@@ -108,16 +109,16 @@
char chartest6(char c = '\x43') { return c; } // 'C'
// namespaces
- namespace AType {
- enum AType { NoType };
- }
+ namespace AType {
+ enum AType { NoType };
+ }
void dummy(AType::AType aType = AType::NoType) {}
- namespace A {
- namespace B {
- int CONST_NUM = 10;
- }
+ namespace A {
+ namespace B {
+ int CONST_NUM = 10;
+ }
int afunction(int i = B::CONST_NUM) { return i; }
- }
+ }
// references
int reftest1(const int &x = 42) { return x; }
@@ -131,7 +132,7 @@
void test(int x = Oak + Fir + Cedar) {}
};
enum Tree::types chops(enum Tree::types type) { return type; }
-
+
%}
// Rename a class member
@@ -155,11 +156,11 @@
static int spam;
Foo(){}
-
+
Foo(int x, int y = 0, int z = 0){}
void meth(int x, int y = 0, int z = 0){}
-
+
// Use a renamed member as a default argument. SWIG has to resolve
// bar to Foo::bar and not Foo::spam. SWIG-1.3.11 got this wrong.
// (Different default parameter wrapping in SWIG-1.3.23 ensures SWIG doesn't have to resolve these symbols).
@@ -189,20 +190,20 @@
// tests valuewrapper
%feature("compactdefaultargs") MyClass2::set;
%inline %{
- enum MyType { Val1, Val2 };
+ enum MyType { Val1, Val2 };
- class MyClass1
- {
- public:
+ class MyClass1
+ {
+ public:
MyClass1(MyType myType) {}
- };
+ };
- class MyClass2
- {
- public :
+ class MyClass2
+ {
+ public :
void set(MyClass1 cl1 = Val1) {}
- // This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
- // But it works in C++ since there is a "conversion" constructor in MyClass1.
+ // This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
+ // But it works in C++ since there is a "conversion" constructor in MyClass1.
void set2(MyClass1 cl1 = Val1) {}
};
%}
@@ -281,7 +282,7 @@ struct ConstMethods {
};
%}
-// const methods
+// const methods
// runtime test needed to check that the const method is called
struct ConstMethods {
int coo(double d = 0.0) const;
@@ -305,8 +306,8 @@ struct ConstMethods {
return(x+p);
}
- typedef struct Pointf {
- double x,y;
+ typedef struct Pointf {
+ double x,y;
} Pointf;
}
%}
diff --git a/Examples/test-suite/director_thread.i b/Examples/test-suite/director_thread.i
index c4564737f..649ab2538 100644
--- a/Examples/test-suite/director_thread.i
+++ b/Examples/test-suite/director_thread.i
@@ -20,7 +20,6 @@
#ifdef _WIN32
#include
#include
-#include
#else
#include
#include
@@ -30,6 +29,7 @@
#endif
#include
+#include
#include "swig_examples_lock.h"
class Foo;
diff --git a/Examples/test-suite/li_cdata.i b/Examples/test-suite/li_cdata.i
index 2180af96e..4e1a01e4e 100644
--- a/Examples/test-suite/li_cdata.i
+++ b/Examples/test-suite/li_cdata.i
@@ -5,4 +5,8 @@
%cdata(int);
%cdata(double);
+%{
+#include
+%}
+
void *malloc(size_t size);
diff --git a/Examples/test-suite/li_cdata_cpp.i b/Examples/test-suite/li_cdata_cpp.i
index 2d7d300e4..80ff2932b 100644
--- a/Examples/test-suite/li_cdata_cpp.i
+++ b/Examples/test-suite/li_cdata_cpp.i
@@ -5,4 +5,8 @@
%cdata(int);
%cdata(double);
+%{
+#include
+%}
+
void *malloc(size_t size);
diff --git a/Examples/test-suite/li_std_except.i b/Examples/test-suite/li_std_except.i
index 60bce999d..9bf70cd3f 100644
--- a/Examples/test-suite/li_std_except.i
+++ b/Examples/test-suite/li_std_except.i
@@ -9,6 +9,8 @@
%}
%inline %{
+ #include
+ #include
struct E1 : public std::exception
{
};
diff --git a/Examples/test-suite/memberin_extend.i b/Examples/test-suite/memberin_extend.i
index c6eb10526..43251973f 100644
--- a/Examples/test-suite/memberin_extend.i
+++ b/Examples/test-suite/memberin_extend.i
@@ -11,6 +11,7 @@ struct ExtendMe {
%{
#include
-$ swig -c++ -python -debug-module 4 example.i
- +++ include ----------------------------------------
- | name - "example.i"
+$ swig -c++ -python -debug-module 1 -debug-quiet example.i
+debug-module stage 1
++++ module ----------------------------------------
+| name - "example"
+|
++++ insert ----------------------------------------
+| code - "\n#include \"example.h\"\n"
+|
++++ include ----------------------------------------
+| name - "example.h"
- +++ module ----------------------------------------
- | name - "example"
- |
- +++ insert ----------------------------------------
- | code - "\n#include \"example.h\"\n"
- |
- +++ include ----------------------------------------
- | name - "example.h"
+ +++ class ----------------------------------------
+ | abstracts - 0x7f4f15182930
+ | allows_typedef - "1"
+ | kind - "class"
+ | name - "Shape"
+ | sym:name - "Shape"
- +++ class ----------------------------------------
- | abstract - "1"
- | sym:name - "Shape"
- | name - "Shape"
- | kind - "class"
- | symtab - 0x40194140
- | sym:symtab - 0x40191078
+ +++ access ----------------------------------------
+ | kind - "public"
+ |
+ +++ constructor ----------------------------------------
+ | access - "public"
+ | code - "{\n nshapes++;\n }"
+ | decl - "f()."
+ | feature:new - "1"
+ | ismember - "1"
+ | name - "Shape"
+ | sym:name - "Shape"
+ |
+ +++ destructor ----------------------------------------
+ | access - "public"
+ | code - "{\n nshapes--;\n }"
+ | decl - "f()."
+ | ismember - "1"
+ | name - "~Shape"
+ | storage - "virtual"
+ | sym:name - "~Shape"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "x"
+ | sym:name - "x"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "y"
+ | sym:name - "y"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f(double,double)."
+ | ismember - "1"
+ | kind - "function"
+ | name - "move"
+ | parms - 'double dx,double dy'
+ | sym:name - "move"
+ | type - "void"
+ |
+ +++ cdecl ----------------------------------------
+ | abstract - "1"
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "area"
+ | storage - "virtual"
+ | sym:name - "area"
+ | type - "double"
+ | value - "0"
+ | valuetype - "int"
+ |
+ +++ cdecl ----------------------------------------
+ | abstract - "1"
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "perimeter"
+ | storage - "virtual"
+ | sym:name - "perimeter"
+ | type - "double"
+ | value - "0"
+ | valuetype - "int"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "nshapes"
+ | storage - "static"
+ | sym:name - "nshapes"
+ | type - "int"
+ |
+ +++ class ----------------------------------------
+ | allows_typedef - "1"
+ | baselist - 0x7f4f15182ad0
+ | kind - "class"
+ | name - "Circle"
+ | privatebaselist - 0x7f4f15182b10
+ | protectedbaselist - 0x7f4f15182af0
+ | sym:name - "Circle"
- +++ access ----------------------------------------
- | kind - "public"
- |
- +++ constructor ----------------------------------------
- | sym:name - "Shape"
- | name - "Shape"
- | decl - "f()."
- | code - "{\n nshapes++;\n }"
- | sym:symtab - 0x40194140
- |
- +++ destructor ----------------------------------------
- | sym:name - "~Shape"
- | name - "~Shape"
- | storage - "virtual"
- | code - "{\n nshapes--;\n }"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "x"
- | name - "x"
- | decl - ""
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "y"
- | name - "y"
- | decl - ""
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "move"
- | name - "move"
- | decl - "f(double, double)."
- | parms - double, double
- | type - "void"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "area"
- | name - "area"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | value - "0"
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "perimeter"
- | name - "perimeter"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | value - "0"
- | type - "double"
- | sym:symtab - 0x40194140
- |
- +++ cdecl ----------------------------------------
- | sym:name - "nshapes"
- | name - "nshapes"
- | decl - ""
- | storage - "static"
- | type - "int"
- | sym:symtab - 0x40194140
- |
- +++ class ----------------------------------------
- | sym:name - "Circle"
- | name - "Circle"
- | kind - "class"
- | bases - 0x40194510
- | symtab - 0x40194538
- | sym:symtab - 0x40191078
+ +++ access ----------------------------------------
+ | kind - "private"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "private"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "radius"
+ | type - "double"
+ |
+ +++ access ----------------------------------------
+ | kind - "public"
+ |
+ +++ constructor ----------------------------------------
+ | access - "public"
+ | code - "{ }"
+ | decl - "f(double)."
+ | feature:new - "1"
+ | ismember - "1"
+ | name - "Circle"
+ | parms - 'double r'
+ | sym:name - "Circle"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "area"
+ | storage - "virtual"
+ | sym:name - "area"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "perimeter"
+ | storage - "virtual"
+ | sym:name - "perimeter"
+ | type - "double"
+ |
+ +++ class ----------------------------------------
+ | allows_typedef - "1"
+ | baselist - 0x7f4f15183830
+ | kind - "class"
+ | name - "Square"
+ | privatebaselist - 0x7f4f15183870
+ | protectedbaselist - 0x7f4f15183850
+ | sym:name - "Square"
- +++ access ----------------------------------------
- | kind - "private"
- |
- +++ cdecl ----------------------------------------
- | name - "radius"
- | decl - ""
- | type - "double"
- |
- +++ access ----------------------------------------
- | kind - "public"
- |
- +++ constructor ----------------------------------------
- | sym:name - "Circle"
- | name - "Circle"
- | parms - double
- | decl - "f(double)."
- | code - "{ }"
- | sym:symtab - 0x40194538
- |
- +++ cdecl ----------------------------------------
- | sym:name - "area"
- | name - "area"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194538
- |
- +++ cdecl ----------------------------------------
- | sym:name - "perimeter"
- | name - "perimeter"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194538
- |
- +++ class ----------------------------------------
- | sym:name - "Square"
- | name - "Square"
- | kind - "class"
- | bases - 0x40194760
- | symtab - 0x40194788
- | sym:symtab - 0x40191078
-
- +++ access ----------------------------------------
- | kind - "private"
- |
- +++ cdecl ----------------------------------------
- | name - "width"
- | decl - ""
- | type - "double"
- |
- +++ access ----------------------------------------
- | kind - "public"
- |
- +++ constructor ----------------------------------------
- | sym:name - "Square"
- | name - "Square"
- | parms - double
- | decl - "f(double)."
- | code - "{ }"
- | sym:symtab - 0x40194788
- |
- +++ cdecl ----------------------------------------
- | sym:name - "area"
- | name - "area"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194788
- |
- +++ cdecl ----------------------------------------
- | sym:name - "perimeter"
- | name - "perimeter"
- | decl - "f(void)."
- | parms - void
- | storage - "virtual"
- | type - "double"
- | sym:symtab - 0x40194788
+ +++ access ----------------------------------------
+ | kind - "private"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "private"
+ | decl - ""
+ | ismember - "1"
+ | kind - "variable"
+ | name - "width"
+ | type - "double"
+ |
+ +++ access ----------------------------------------
+ | kind - "public"
+ |
+ +++ constructor ----------------------------------------
+ | access - "public"
+ | code - "{ }"
+ | decl - "f(double)."
+ | feature:new - "1"
+ | ismember - "1"
+ | name - "Square"
+ | parms - 'double w'
+ | sym:name - "Square"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "area"
+ | storage - "virtual"
+ | sym:name - "area"
+ | type - "double"
+ |
+ +++ cdecl ----------------------------------------
+ | access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | kind - "function"
+ | name - "perimeter"
+ | storage - "virtual"
+ | sym:name - "perimeter"
+ | type - "double"
@@ -698,31 +731,28 @@ The parse tree can be viewed after the final stage of processing by running SWIG
-$ swig -debug-top 4 example.i
+$ swig -debug-top 1 -debug-quiet example.i
...
+++ cdecl ----------------------------------------
- | sym:name - "foo_i"
- | name - "foo"
| decl - "f(int)."
+ | name - "foo"
| parms - int
+ | sym:name - "foo_i"
| type - "void"
- | sym:symtab - 0x40165078
|
+++ cdecl ----------------------------------------
- | sym:name - "foo_d"
- | name - "foo"
| decl - "f(double)."
+ | name - "foo"
| parms - double
+ | sym:name - "foo_d"
| type - "void"
- | sym:symtab - 0x40165078
|
+++ cdecl ----------------------------------------
- | sym:name - "foo"
- | name - "foo"
| decl - "f(p.Bar)."
+ | name - "foo"
| parms - Bar *
+ | sym:name - "foo"
| type - "void"
- | sym:symtab - 0x40165078
@@ -787,19 +817,18 @@ public:
The behavior of %feature is very easy to describe--it simply
attaches a new attribute to any parse tree node that matches the
given prototype. When a feature is added, it shows up as an attribute in the feature: namespace.
-You can see this when running with the -debug-top 4 option. For example:
+You can see this when running with the -debug-top 4 -debug-quiet option. For example:
+++ cdecl ----------------------------------------
- | sym:name - "getitem"
- | name - "getitem"
| decl - "f(int).p."
- | parms - int
- | type - "Object"
| feature:except - "{\n try {\n $action\n } catc..."
- | sym:symtab - 0x40168ac8
+ | name - "getitem"
+ | parms - int
+ | sym:name - "getitem"
+ | type - "Object"
|
@@ -3765,6 +3794,7 @@ There are various command line options which can aid debugging a SWIG interface
-debug-symbols - Display target language symbols in the symbol tables
-debug-csymbols - Display C symbols in the symbol tables
-debug-lsymbols - Display target language layer symbols
+-debug-quiet - Display less parse tree node debug info when using other -debug options
-debug-tags - Display information about the tags found in the interface
-debug-template - Display information for debugging templates
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index ea2e625ef..1d929ac71 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -155,6 +155,7 @@ General Options
-debug-symbols - Display target language symbols in the symbol tables
-debug-csymbols - Display C symbols in the symbol tables
-debug-lsymbols - Display target language layer symbols
+ -debug-quiet - Display less parse tree node debug info when using other -debug options
-debug-tags - Display information about the tags found in the interface
-debug-template - Display information for debugging templates
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages
@@ -2186,18 +2187,19 @@ of the expression.
For a comprehensive understanding of how the matching works, the internal
parse tree needs to be examined using the
-command line option: -debug-module 1.
+command line option: -debug-module 1 -debug-quiet.
A snippet of the resulting output might be:
- +++ destructor - 0x7fc10ea05af0 ----------------------------------------
- | name - "~Shape"
- | ismember - "1"
- | sym:name - "~Shape"
+ +++ destructor ----------------------------------------
| access - "public"
+ | decl - "f()."
+ | ismember - "1"
+ | name - "~Shape"
| storage - "virtual"
+ | sym:name - "~Shape"
diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
index 604b43743..b17c5e503 100644
--- a/Source/Modules/javascript.cxx
+++ b/Source/Modules/javascript.cxx
@@ -760,13 +760,10 @@ int JSEmitter::emitWrapperFunction(Node *n) {
ret = emitSetter(n, is_member, is_static);
} else if (is_getter) {
ret = emitGetter(n, is_member, is_static);
- } else {
- Swig_print_node(n);
}
} else {
Printf(stderr, "Warning: unsupported wrapper function type\n");
- Swig_print_node(n);
ret = SWIG_ERROR;
}
} else {
@@ -778,7 +775,6 @@ int JSEmitter::emitWrapperFunction(Node *n) {
ret = emitDtor(n);
} else {
Printf(stderr, "Warning: unsupported wrapper function type");
- Swig_print_node(n);
ret = SWIG_ERROR;
}
}
@@ -1409,7 +1405,6 @@ int JSEmitter::switchNamespace(Node *n) {
String *_nspace = lang->getNSpace();
if (!Equal(nspace, _nspace)) {
Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace);
- Swig_print_node(n);
}
#endif
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index 239deabeb..f412a3eeb 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -74,6 +74,7 @@ static const char *usage1 = (const char *) "\
-debug-symbols - Display target language symbols in the symbol tables\n\
-debug-csymbols - Display C symbols in the symbol tables\n\
-debug-lsymbols - Display target language layer symbols\n\
+ -debug-quiet - Display less parse tree node debug info when using other -debug options\n\
-debug-tags - Display information about the tags found in the interface\n\
-debug-template - Display information for debugging templates\n\
-debug-top - Display entire parse tree at stages 1-4, is a csv list of stages\n\
@@ -778,6 +779,9 @@ static void getoptions(int argc, char *argv[]) {
} else if (strncmp(argv[i], "-w", 2) == 0) {
Swig_mark_arg(i);
Swig_warnfilter(argv[i] + 2, 1);
+ } else if (strcmp(argv[i], "-debug-quiet") == 0) {
+ Swig_print_quiet(1);
+ Swig_mark_arg(i);
} else if (strcmp(argv[i], "-debug-symtabs") == 0) {
dump_symtabs = 1;
Swig_mark_arg(i);
diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx
index 8a4ce48f7..034e0e76f 100644
--- a/Source/Modules/overload.cxx
+++ b/Source/Modules/overload.cxx
@@ -339,7 +339,6 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
Setattr(nodes[i].n, "overload:ignore", "1");
Append(result, nodes[i].n);
// Printf(stdout,"[ %d ] %d %s\n", i, nodes[i].implicitconv_function, ParmList_errorstr(nodes[i].parms));
- // Swig_print_node(nodes[i].n);
if (i == nnodes-1 || nodes[i].argc != nodes[i+1].argc) {
if (argc_changed_index+2 < nnodes && (nodes[argc_changed_index+1].argc == nodes[argc_changed_index+2].argc)) {
// Add additional implicitconv functions in same order as already ranked.
@@ -351,7 +350,6 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
SetFlag(nodes[j].n, "implicitconvtypecheckoff");
Append(result, nodes[j].n);
// Printf(stdout,"[ %d ] %d + %s\n", j, nodes[j].implicitconv_function, ParmList_errorstr(nodes[j].parms));
- // Swig_print_node(nodes[j].n);
}
}
}
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index 9d9204c0f..541e7e622 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -1542,8 +1542,6 @@ List * R::Swig_overload_rank(Node *n,
if (nodes[i].error)
Setattr(nodes[i].n, "overload:ignore", "1");
Append(result,nodes[i].n);
- // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
- // Swig_print_node(nodes[i].n);
}
}
return result;
diff --git a/Source/Swig/swigtree.h b/Source/Swig/swigtree.h
index acd0e5e90..8f70a2cde 100644
--- a/Source/Swig/swigtree.h
+++ b/Source/Swig/swigtree.h
@@ -51,3 +51,4 @@ extern void Swig_restore(Node *node);
extern void Swig_print_tags(File *obj, Node *root);
extern void Swig_print_tree(Node *obj);
extern void Swig_print_node(Node *obj);
+extern int Swig_print_quiet(int quiet);
diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c
index 5b0e9e1e9..e5d3467e5 100644
--- a/Source/Swig/tree.c
+++ b/Source/Swig/tree.c
@@ -16,6 +16,20 @@
#include
#include
+static int debug_quiet = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_print_quiet()
+ *
+ * Set quiet mode when printing a parse tree node
+ * ----------------------------------------------------------------------------- */
+
+int Swig_print_quiet(int quiet) {
+ int previous_quiet = debug_quiet;
+ debug_quiet = quiet;
+ return previous_quiet;
+}
+
/* -----------------------------------------------------------------------------
* Swig_print_tags()
*
@@ -68,31 +82,40 @@ void Swig_print_node(Node *obj) {
Node *cobj;
print_indent(0);
- Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
- ki = First(obj);
- while (ki.key) {
- String *k = ki.key;
- if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
- (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
+ if (debug_quiet)
+ Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj));
+ else
+ Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
+
+ List *keys = Keys(obj);
+ SortList(keys, 0);
+ ki = First(keys);
+ while (ki.item) {
+ String *k = ki.item;
+ DOH *value = Getattr(obj, k);
+ if (Equal(k, "nodeType") || (*(Char(k)) == '$')) {
/* Do nothing */
- } else if (Cmp(k, "kwargs") == 0 || Cmp(k, "parms") == 0 || Cmp(k, "wrap:parms") == 0 ||
- Cmp(k, "pattern") == 0 || Cmp(k, "templateparms") == 0 || Cmp(k, "throws") == 0) {
+ } else if (debug_quiet && (Equal(k, "nodeType") || Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") ||
+ Equal(k, "previousSibling") || Equal(k, "symtab") || Equal(k, "csymtab") || Equal(k, "sym:symtab") || Equal(k, "sym:nextSibling") ||
+ Equal(k, "sym:previousSibling") || Equal(k, "csym:nextSibling") || Equal(k, "csym:previousSibling"))) {
+ /* Do nothing */
+ } else if (Equal(k, "kwargs") || Equal(k, "parms") || Equal(k, "wrap:parms") || Equal(k, "pattern") || Equal(k, "templateparms") || Equal(k, "throws")) {
print_indent(2);
/* Differentiate parameter lists by displaying within single quotes */
- Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(Getattr(obj, k)));
+ Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(value));
} else {
DOH *o;
const char *trunc = "";
print_indent(2);
- if (DohIsString(Getattr(obj, k))) {
- o = Str(Getattr(obj, k));
+ if (DohIsString(value)) {
+ o = Str(value);
if (Len(o) > 80) {
trunc = "...";
}
Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc);
Delete(o);
} else {
- Printf(stdout, "%-12s - %p\n", k, Getattr(obj, k));
+ Printf(stdout, "%-12s - %p\n", k, value);
}
}
ki = Next(ki);
@@ -107,6 +130,7 @@ void Swig_print_node(Node *obj) {
print_indent(1);
Printf(stdout, "\n");
}
+ Delete(keys);
}
/* -----------------------------------------------------------------------------
From 51a7f27d1cb92d5caa81b6c6a58ecec830f3e753 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 25 Mar 2022 23:44:07 +0000
Subject: [PATCH 378/662] Minor fix to Swig_print_node
---
Source/Swig/tree.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c
index e5d3467e5..bc552988c 100644
--- a/Source/Swig/tree.c
+++ b/Source/Swig/tree.c
@@ -95,7 +95,7 @@ void Swig_print_node(Node *obj) {
DOH *value = Getattr(obj, k);
if (Equal(k, "nodeType") || (*(Char(k)) == '$')) {
/* Do nothing */
- } else if (debug_quiet && (Equal(k, "nodeType") || Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") ||
+ } else if (debug_quiet && (Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") ||
Equal(k, "previousSibling") || Equal(k, "symtab") || Equal(k, "csymtab") || Equal(k, "sym:symtab") || Equal(k, "sym:nextSibling") ||
Equal(k, "sym:previousSibling") || Equal(k, "csym:nextSibling") || Equal(k, "csym:previousSibling"))) {
/* Do nothing */
From 5c68705a218afb6afd45498a9c0e096a56adab2d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 26 Mar 2022 12:03:09 +0000
Subject: [PATCH 379/662] Comment broken part of using_member.i
---
Examples/test-suite/using_member.i | 1 +
1 file changed, 1 insertion(+)
diff --git a/Examples/test-suite/using_member.i b/Examples/test-suite/using_member.i
index 6b4af2ea7..c80a83a50 100644
--- a/Examples/test-suite/using_member.i
+++ b/Examples/test-suite/using_member.i
@@ -46,6 +46,7 @@ namespace one {
class BB : public two::three::AA
{
public:
+// TODO: two::three::AA::great not introduced
using two::three::AA::great;
int great(bool) {return 2;}
int jj() {return 3;}
From 3ab288dfa48e34788da25cf0ec5b3bdd0e8d63f6 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 26 Mar 2022 15:06:13 +0000
Subject: [PATCH 380/662] Different capsule names for builtin changes entry
---
CHANGES.current | 8 ++++++++
.../test-suite/python/python_runtime_data_runme.py | 12 ++++++++----
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 64e4c4402..56cb2c560 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,14 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-03-26: eltoder
+ [Python] #1684 Use different capsule names with and without -builtin
+
+ Types generated with and without -builtin are not compatible. Mixing
+ them in a common type list leads to crashes. Avoid this by using
+ different capsule names: "type_pointer_capsule" without -builtin and
+ "type_pointer_capsule_builtin" with.
+
2022-03-15: ianlancetaylor
[Go] Don't convert arrays to pointers if there is a "gotype"
typemap entry.
diff --git a/Examples/test-suite/python/python_runtime_data_runme.py b/Examples/test-suite/python/python_runtime_data_runme.py
index 341315ee3..063bf82d1 100644
--- a/Examples/test-suite/python/python_runtime_data_runme.py
+++ b/Examples/test-suite/python/python_runtime_data_runme.py
@@ -1,11 +1,15 @@
import python_runtime_data_builtin as builtin
import python_runtime_data_nobuiltin as nobuiltin
-assert builtin.is_python_builtin()
-assert not nobuiltin.is_python_builtin()
+def swig_assert(a):
+ if not a:
+ raise RuntimeError("Failed")
+
+swig_assert(builtin.is_python_builtin())
+swig_assert(not nobuiltin.is_python_builtin())
for i in range(1, 5):
v1 = builtin.vectord([1.] * i)
- assert len(v1) == i
+ swig_assert(len(v1) == i)
v2 = nobuiltin.vectord([1.] * i)
- assert len(v2) == i
+ swig_assert(len(v2) == i)
From f2dd436a5b6c71d1c552a9238a33980f2f0bb529 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 26 Mar 2022 15:16:22 +0000
Subject: [PATCH 381/662] Rework swig_and_compile_multi_cpp makefile helper
Seems less cryptic and more maintainable to me
---
Examples/test-suite/common.mk | 14 ++++++++------
Examples/test-suite/python/Makefile.in | 5 ++++-
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 85b27979d..ddbb75d22 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -831,6 +831,13 @@ endif
partialcheck:
$(MAKE) check CC=true CXX=true LDSHARED=true CXXSHARED=true RUNTOOL=true COMPILETOOL=true
+swig_and_compile_cpp_helper = \
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+ LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT=$(2) NOLINK=true \
+ TARGET="$(TARGETPREFIX)$(1)$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$(1).i" \
+ $(LANGUAGE)$(VARIANT)_cpp
+
swig_and_compile_cpp = \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
@@ -847,12 +854,7 @@ swig_and_compile_c = \
swig_and_compile_multi_cpp = \
for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
- swigopt=$$(name=SWIGOPT_$$f; eval echo \$$$$name); \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT="$${swigopt:-$(SWIGOPT)}" NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- $(LANGUAGE)$(VARIANT)_cpp; \
+ $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)'); \
done
swig_and_compile_external = \
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index 57106edd1..a85b2984a 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -105,9 +105,12 @@ VALGRIND_OPT += --suppressions=pythonswig.supp
# Custom tests - tests with additional commandline options
#python_flatstaticmethod.cpptest: SWIGOPT += -flatstaticmethod
+# Make sure just python_runtime_data_builtin.i uses the -builtin option. Note: does not use python_runtime_data.list for all steps.
python_runtime_data.multicpptest: override SWIG_FEATURES := $(filter-out -builtin,$(SWIG_FEATURES))
python_runtime_data.multicpptest: override SWIGOPT := $(filter-out -builtin,$(SWIGOPT))
-python_runtime_data.multicpptest: export SWIGOPT_python_runtime_data_builtin = $(SWIGOPT) -builtin
+python_runtime_data.multicpptest: swig_and_compile_multi_cpp = \
+ $(call swig_and_compile_cpp_helper,python_runtime_data_builtin,'$(SWIGOPT) -builtin') && \
+ $(call swig_and_compile_cpp_helper,python_runtime_data_nobuiltin,'$(SWIGOPT)')
# Rules for the different types of tests
%.cpptest:
From c5f209706ed411099ae128a49a9c1c987e789d0d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 11:27:58 +0100
Subject: [PATCH 382/662] Further makefile refactoring for multicpptests
---
Examples/test-suite/common.mk | 2 ++
Examples/test-suite/go/Makefile.in | 48 +++++++-----------------------
2 files changed, 13 insertions(+), 37 deletions(-)
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index ddbb75d22..f887037d9 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -814,6 +814,8 @@ check-cpp: $(CPP_TEST_CASES:=.cpptest)
check-cpp11: $(CPP11_TEST_CASES:=.cpptest)
+check-multicpp: $(MULTI_CPP_TEST_CASES:=.multicpptest)
+
ifdef HAS_DOXYGEN
check-doxygen: $(DOXYGEN_TEST_CASES:=.cpptest)
endif
diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in
index e905a1060..3f1bbea4e 100644
--- a/Examples/test-suite/go/Makefile.in
+++ b/Examples/test-suite/go/Makefile.in
@@ -43,17 +43,9 @@ INCLUDES = -I$(abs_top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)
%.multicpptest:
$(setup)
- mkdir -p gopath/$*/src 2>/dev/null || true
- if ! test -d gopath/$*/src/swigtests; then \
- (cd gopath/$*/src && ln -s . swigtests); \
- fi
+ $(call go_multicpp_setup,$*)
+for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- GOMOD="$*" \
- $(LANGUAGE)$(VARIANT)_cpp; \
+ $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)') GOMOD="$*"; \
done
$(run_multi_testcase)
@@ -61,28 +53,9 @@ li_windows.cpptest:
# Does not work because go build won't build li_windows.go,
# because file names with "windows" are only built on Windows.
-multi_import.multicpptest:
- $(setup)
- mkdir -p gopath/multi_import/src 2>/dev/null || true
- if ! test -d gopath/multi_import/src/swigtests; then \
- (cd gopath/multi_import/src && ln -s . swigtests); \
- fi
- for f in multi_import_d multi_import_b multi_import_a; do \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- GOMOD="multi_import" \
- $(LANGUAGE)$(VARIANT)_cpp; \
- done
- $(run_multi_testcase)
-
go_subdir_import.multicpptest:
$(setup)
- mkdir -p gopath/go_subdir_import/src 2>/dev/null || true
- if ! test -d gopath/go_subdir_import/src/swigtests; then \
- (cd gopath/go_subdir_import/src && ln -s . swigtests); \
- fi
+ $(call go_multicpp_setup,go_subdir_import)
mkdir -p testdir/go_subdir_import 2>/dev/null || true
mkdir -p gopath/go_subdir_import/src/testdir/go_subdir_import 2>/dev/null || true
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
@@ -93,16 +66,17 @@ go_subdir_import.multicpptest:
INTERFACE='testdir/go_subdir_import/go_subdir_import_b.i' \
GOMOD="go_subdir_import" \
$(LANGUAGE)$(VARIANT)_cpp;
- for f in testdir/go_subdir_import/go_subdir_import_c go_subdir_import_a ; do \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
- SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
- LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
- TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
- GOMOD="go_subdir_import" \
- $(LANGUAGE)$(VARIANT)_cpp; \
+ +for f in testdir/go_subdir_import/go_subdir_import_c go_subdir_import_a ; do \
+ $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)') GOMOD="go_subdir_import"; \
done
$(run_multi_testcase)
+go_multicpp_setup = \
+ mkdir -p gopath/$*/src 2>/dev/null || true; \
+ if ! test -d gopath/$*/src/swigtests; then \
+ (cd gopath/$*/src && ln -s . swigtests); \
+ fi
+
# Runs the testcase.
run_testcase = \
if test -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
From ffe2f85417c0313b35387e266b539dd275f9cd6d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 12:44:19 +0100
Subject: [PATCH 383/662] go_multicpp_setup make function correction
---
Examples/test-suite/go/Makefile.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in
index 3f1bbea4e..a0da7f180 100644
--- a/Examples/test-suite/go/Makefile.in
+++ b/Examples/test-suite/go/Makefile.in
@@ -43,7 +43,7 @@ INCLUDES = -I$(abs_top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)
%.multicpptest:
$(setup)
- $(call go_multicpp_setup,$*)
+ $(go_multicpp_setup)
+for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
$(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)') GOMOD="$*"; \
done
@@ -55,7 +55,7 @@ li_windows.cpptest:
go_subdir_import.multicpptest:
$(setup)
- $(call go_multicpp_setup,go_subdir_import)
+ $(go_multicpp_setup)
mkdir -p testdir/go_subdir_import 2>/dev/null || true
mkdir -p gopath/go_subdir_import/src/testdir/go_subdir_import 2>/dev/null || true
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
From a71c318b06232697bac8e8312316e70eac3e1f7e Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 13:33:02 +0100
Subject: [PATCH 384/662] Stop testing two recently failing ocaml tests
Problem here seems to be one also affecting other ocaml broken tests:
1. Enum value names should be using sym:name not name (ie %rename is broken for ocaml enum items)
2. directorin typemaps are not correct
---
Examples/test-suite/ocaml/Makefile.in | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in
index 10b537e4c..e9253b920 100644
--- a/Examples/test-suite/ocaml/Makefile.in
+++ b/Examples/test-suite/ocaml/Makefile.in
@@ -25,10 +25,12 @@ director_enum \
director_primitives \
director_redefined \
director_string \
+director_using_member_scopes \
enum_thorough \
li_windows \
member_pointer_const \
preproc_constants \
+rename_camel \
smart_pointer_inherit \
FAILING_C_TESTS = \
From f44153069b86c8e195b9c0d33eb2d7dfa95859f9 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 13:50:30 +0100
Subject: [PATCH 385/662] Ocaml test-suite 'passes' with c++11 testing now
Test c++17 on Github Actions to try keep it passing when
configure detects g++ can test c++17.
---
.github/workflows/ci.yml | 1 +
Examples/test-suite/cpp11_rvalue_reference2.i | 10 +++++-----
Examples/test-suite/cpp11_template_explicit.i | 2 +-
Examples/test-suite/cpp11_userdefined_literals.i | 4 ++--
Examples/test-suite/ocaml/Makefile.in | 2 ++
5 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 88fd32328..731bcffae 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -296,6 +296,7 @@ jobs:
- SWIGLANG: mzscheme
continue-on-error: true
- SWIGLANG: ocaml
+ CPPSTD: c++17
continue-on-error: true
os: ubuntu-18.04 # ocaml-4.08 in ubuntu-20.04 not yet working
# Run all of them, as opposed to aborting when one fails
diff --git a/Examples/test-suite/cpp11_rvalue_reference2.i b/Examples/test-suite/cpp11_rvalue_reference2.i
index a2a0020f5..a3af6daf8 100644
--- a/Examples/test-suite/cpp11_rvalue_reference2.i
+++ b/Examples/test-suite/cpp11_rvalue_reference2.i
@@ -20,10 +20,10 @@ static const bool PublicGlobalTrue = true;
static const UserDef PublicUserDef = UserDef();
struct Thingy {
typedef int Integer;
- int val;
+ int valval;
int &lvalref;
int &&rvalref;
- Thingy(int v, int &&rvalv) : val(v), lvalref(val), rvalref(std::move(rvalv)) {}
+ Thingy(int v, int &&rvalv) : valval(v), lvalref(valval), rvalref(std::move(rvalv)) {}
void refIn(long &i) {}
void rvalueIn(long &&i) {}
short && rvalueInOut(short &&i) { return std::move(i); }
@@ -31,10 +31,10 @@ struct Thingy {
// test both primitive and user defined rvalue reference default arguments and compactdefaultargs
void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {}
void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {}
- operator int &&() { return std::move(val); }
- Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
+ operator int &&() { return std::move(valval); }
+ Thingy(const Thingy& rhs) : valval(rhs.valval), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
Thingy& operator=(const Thingy& rhs) {
- val = rhs.val;
+ valval = rhs.valval;
lvalref = rhs.lvalref;
rvalref = rhs.rvalref;
return *this;
diff --git a/Examples/test-suite/cpp11_template_explicit.i b/Examples/test-suite/cpp11_template_explicit.i
index 630342862..950f1d265 100644
--- a/Examples/test-suite/cpp11_template_explicit.i
+++ b/Examples/test-suite/cpp11_template_explicit.i
@@ -12,7 +12,7 @@
template class Temper {
public:
- T val;
+ T valu;
};
class A {
diff --git a/Examples/test-suite/cpp11_userdefined_literals.i b/Examples/test-suite/cpp11_userdefined_literals.i
index 43103cc8c..9284739cd 100644
--- a/Examples/test-suite/cpp11_userdefined_literals.i
+++ b/Examples/test-suite/cpp11_userdefined_literals.i
@@ -17,8 +17,8 @@
#include
struct OutputType {
- int val;
- OutputType(int v) : val(v) {}
+ int valu;
+ OutputType(int v) : valu(v) {}
};
// Raw literal
diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in
index e9253b920..68fea58fc 100644
--- a/Examples/test-suite/ocaml/Makefile.in
+++ b/Examples/test-suite/ocaml/Makefile.in
@@ -17,6 +17,8 @@ FAILING_CPP_TESTS = \
allprotected \
apply_signed_char \
apply_strings \
+cpp11_director_enums \
+cpp11_strongly_typed_enumerations \
cpp_enum \
default_constructor \
director_binary_string \
From 282fdb17159cb6153d69ebba2c9b5a105b4c747d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 15:06:47 +0100
Subject: [PATCH 386/662] MzScheme 'passes' with c++11 testing now
Test c++17 on Github Actions to try keep it passing when
configure detects g++ can test c++17.
---
.github/workflows/ci.yml | 1 +
Examples/test-suite/common.mk | 1 +
Examples/test-suite/mzscheme/Makefile.in | 5 +++++
3 files changed, 7 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 731bcffae..65ec30886 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -294,6 +294,7 @@ jobs:
GCC: 11
# Experimental languages (these are allowed to fail)
- SWIGLANG: mzscheme
+ CPPSTD: c++17
continue-on-error: true
- SWIGLANG: ocaml
CPPSTD: c++17
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index f887037d9..c9c9e373b 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -774,6 +774,7 @@ command_line_define.ctest: SWIGOPT += -DFOO
# Allow modules to define temporarily failing tests.
C_TEST_CASES := $(filter-out $(FAILING_C_TESTS),$(C_TEST_CASES))
CPP_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP_TEST_CASES))
+CPP11_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP11_TEST_CASES))
MULTI_CPP_TEST_CASES := $(filter-out $(FAILING_MULTI_CPP_TESTS),$(MULTI_CPP_TEST_CASES))
diff --git a/Examples/test-suite/mzscheme/Makefile.in b/Examples/test-suite/mzscheme/Makefile.in
index 6a8ef74e4..e3fe17313 100644
--- a/Examples/test-suite/mzscheme/Makefile.in
+++ b/Examples/test-suite/mzscheme/Makefile.in
@@ -19,6 +19,11 @@ char_strings \
chartest \
class_scope_weird \
constant_pointers \
+cpp11_alternate_function_syntax \
+cpp11_director_enums \
+cpp11_ref_qualifiers \
+cpp11_rvalue_reference2 \
+cpp11_strongly_typed_enumerations \
cpp_basic \
cpp_enum \
curiously_recurring_template_pattern \
From cbd9bd6d71c4265f5347bd6a37bd9e3b5e7c896f Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 16:43:30 +0100
Subject: [PATCH 387/662] Fix running make-cpp11 for ocaml
---
Examples/test-suite/ocaml/Makefile.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in
index 68fea58fc..995f7f49b 100644
--- a/Examples/test-suite/ocaml/Makefile.in
+++ b/Examples/test-suite/ocaml/Makefile.in
@@ -97,6 +97,7 @@ extra_objects: swig.cmi swig.cmo swigp4.cmi
$(C_TEST_CASES:=.ctest): extra_objects
$(CPP_TEST_CASES:=.cpptest): extra_objects
+$(CPP11_TEST_CASES:=.cpptest): extra_objects
$(MULTI_CPP_TEST_CASES:=.multicpptest): extra_objects
# Clean
From 27d6f5c2fef0abe43208cbb6a2f4f11e1e144881 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 18:28:49 +0100
Subject: [PATCH 388/662] git commit -m "Fix test-suite's make clean to clean
cpp11 testcases
Always clean cpp11 tests even if --enable-cpp11-testing is not active
May result in cpp11 tests being deleted twice though" ../
---
Examples/test-suite/common.mk | 1 +
1 file changed, 1 insertion(+)
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index c9c9e373b..96660c0d7 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -787,6 +787,7 @@ BROKEN_TEST_CASES = $(CPP_TEST_BROKEN:=.cpptest) \
$(C_TEST_BROKEN:=.ctest)
ALL_CLEAN = $(CPP_TEST_CASES:=.clean) \
+ $(CPP11_TEST_CASES:=.clean) \
$(C_TEST_CASES:=.clean) \
$(MULTI_CPP_TEST_CASES:=.clean) \
$(CPP_TEST_BROKEN:=.clean) \
From 5cc4591ae77416d8f8be23fa7d5a622eba5e8240 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 27 Mar 2022 19:34:20 +0100
Subject: [PATCH 389/662] Consistent cpp11 testing in test-suite
Move HAVE_CXX11 into makefiles so that running test-suite
from top level directory or in the language's test-suite directory
is consistent. For example, running 'make check-java-test-suite'
behaves the same as 'cd Examples/test-suite/java && make check'.
---
Examples/test-suite/cffi/Makefile.in | 1 +
Examples/test-suite/csharp/Makefile.in | 1 +
Examples/test-suite/d/Makefile.in | 1 +
Examples/test-suite/errors/Makefile.in | 1 +
Examples/test-suite/go/Makefile.in | 1 +
Examples/test-suite/guile/Makefile.in | 1 +
Examples/test-suite/java/Makefile.in | 1 +
Examples/test-suite/javascript/Makefile.in | 1 +
Examples/test-suite/lua/Makefile.in | 1 +
Examples/test-suite/mzscheme/Makefile.in | 1 +
Examples/test-suite/ocaml/Makefile.in | 1 +
Examples/test-suite/octave/Makefile.in | 1 +
Examples/test-suite/perl5/Makefile.in | 1 +
Examples/test-suite/php/Makefile.in | 1 +
Examples/test-suite/python/Makefile.in | 1 +
Examples/test-suite/r/Makefile.in | 1 +
Examples/test-suite/ruby/Makefile.in | 1 +
Examples/test-suite/scilab/Makefile.in | 1 +
Examples/test-suite/tcl/Makefile.in | 1 +
Makefile.in | 3 +--
20 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/Examples/test-suite/cffi/Makefile.in b/Examples/test-suite/cffi/Makefile.in
index b2e86e102..1ce64675a 100644
--- a/Examples/test-suite/cffi/Makefile.in
+++ b/Examples/test-suite/cffi/Makefile.in
@@ -6,6 +6,7 @@ LANGUAGE = cffi
CFFI = @CFFIBIN@
SCRIPTSUFFIX = _runme.lisp
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in
index 02dcaafb0..74010c284 100644
--- a/Examples/test-suite/csharp/Makefile.in
+++ b/Examples/test-suite/csharp/Makefile.in
@@ -8,6 +8,7 @@ CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
CSHARPCONVERTPATH = @top_srcdir@/@CSHARPCONVERTPATH@
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
diff --git a/Examples/test-suite/d/Makefile.in b/Examples/test-suite/d/Makefile.in
index a20cfb4e3..e6b4e2d18 100644
--- a/Examples/test-suite/d/Makefile.in
+++ b/Examples/test-suite/d/Makefile.in
@@ -4,6 +4,7 @@
LANGUAGE = d
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
diff --git a/Examples/test-suite/errors/Makefile.in b/Examples/test-suite/errors/Makefile.in
index 7137a6862..97c7d5c76 100644
--- a/Examples/test-suite/errors/Makefile.in
+++ b/Examples/test-suite/errors/Makefile.in
@@ -16,6 +16,7 @@
LANGUAGE = errors
ERROR_EXT = newerr
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in
index a0da7f180..67f96cf7e 100644
--- a/Examples/test-suite/go/Makefile.in
+++ b/Examples/test-suite/go/Makefile.in
@@ -12,6 +12,7 @@ SCRIPTSUFFIX = _runme.go
SO = @SO@
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/guile/Makefile.in b/Examples/test-suite/guile/Makefile.in
index 55885fc29..1fda5dc9c 100644
--- a/Examples/test-suite/guile/Makefile.in
+++ b/Examples/test-suite/guile/Makefile.in
@@ -8,6 +8,7 @@ LANGUAGE = guile
VARIANT =
SCRIPTSUFFIX = _runme.scm
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in
index e2a3d2472..7a34f587b 100644
--- a/Examples/test-suite/java/Makefile.in
+++ b/Examples/test-suite/java/Makefile.in
@@ -11,6 +11,7 @@ JAVA_TOOLS_JAR = @JAVA_TOOLS_JAR@
SCRIPTSUFFIX = _runme.java
SKIP_DOXYGEN_TEST_CASES = @JAVA_SKIP_DOXYGEN_TEST_CASES@
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
index 4f2d450e5..57b6eac75 100644
--- a/Examples/test-suite/javascript/Makefile.in
+++ b/Examples/test-suite/javascript/Makefile.in
@@ -9,6 +9,7 @@ SCRIPTSUFFIX = _runme.js
OBJEXT = @OBJEXT@
SO = @SO@
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/lua/Makefile.in b/Examples/test-suite/lua/Makefile.in
index c0730466f..2d4100d1b 100644
--- a/Examples/test-suite/lua/Makefile.in
+++ b/Examples/test-suite/lua/Makefile.in
@@ -6,6 +6,7 @@ LANGUAGE = lua
LUA = @LUABIN@
SCRIPTSUFFIX = _runme.lua
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/mzscheme/Makefile.in b/Examples/test-suite/mzscheme/Makefile.in
index e3fe17313..93dbb4ba1 100644
--- a/Examples/test-suite/mzscheme/Makefile.in
+++ b/Examples/test-suite/mzscheme/Makefile.in
@@ -6,6 +6,7 @@ LANGUAGE = mzscheme
MZSCHEME = mzscheme
SCRIPTSUFFIX = _runme.scm
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in
index 995f7f49b..79e25efcf 100644
--- a/Examples/test-suite/ocaml/Makefile.in
+++ b/Examples/test-suite/ocaml/Makefile.in
@@ -9,6 +9,7 @@ OCAMLPP = -pp "camlp4o ./swigp4.cmo"
VARIANT = _static
SCRIPTSUFFIX = _runme.ml
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in
index 9602d85f5..81696b3ff 100644
--- a/Examples/test-suite/octave/Makefile.in
+++ b/Examples/test-suite/octave/Makefile.in
@@ -7,6 +7,7 @@ OCTAVE = @OCTAVE@
SCRIPTSUFFIX = _runme.m
PCHSUPPORT = @PCHSUPPORT@
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/perl5/Makefile.in b/Examples/test-suite/perl5/Makefile.in
index 6388e5b32..3fb3ebac6 100644
--- a/Examples/test-suite/perl5/Makefile.in
+++ b/Examples/test-suite/perl5/Makefile.in
@@ -7,6 +7,7 @@ PERL = @PERL@
SCRIPTSUFFIX = _runme.pl
TEST_RUNNER = $(srcdir)/run-perl-test.pl
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in
index a31eedbee..c460bff28 100644
--- a/Examples/test-suite/php/Makefile.in
+++ b/Examples/test-suite/php/Makefile.in
@@ -5,6 +5,7 @@
LANGUAGE = php
SCRIPTSUFFIX = _runme.php
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index ccd5ca513..c061f903a 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -14,6 +14,7 @@ SCRIPTSUFFIX = _runme.py
PYCODESTYLE = @PYCODESTYLE@
PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,E741,W291,W391
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/r/Makefile.in b/Examples/test-suite/r/Makefile.in
index 33e9d90da..484dea375 100644
--- a/Examples/test-suite/r/Makefile.in
+++ b/Examples/test-suite/r/Makefile.in
@@ -8,6 +8,7 @@ WRAPSUFFIX = .R
R_OPT = --quiet --no-save --no-restore
RUNR = R CMD BATCH $(R_OPT) '--args $(SCRIPTDIR)'
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in
index f982eca1f..3b673bf71 100644
--- a/Examples/test-suite/ruby/Makefile.in
+++ b/Examples/test-suite/ruby/Makefile.in
@@ -6,6 +6,7 @@ LANGUAGE = ruby
RUBY = @RUBY@
SCRIPTSUFFIX = _runme.rb
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Examples/test-suite/scilab/Makefile.in b/Examples/test-suite/scilab/Makefile.in
index f873b8687..e1effcd64 100644
--- a/Examples/test-suite/scilab/Makefile.in
+++ b/Examples/test-suite/scilab/Makefile.in
@@ -7,6 +7,7 @@ SCILAB = @SCILAB@
SCILAB_OPT = @SCILABOPT@
SCRIPTSUFFIX = _runme.sci
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = ../@top_srcdir@
top_builddir = ../@top_builddir@
diff --git a/Examples/test-suite/tcl/Makefile.in b/Examples/test-suite/tcl/Makefile.in
index 322e71914..84a7299f7 100644
--- a/Examples/test-suite/tcl/Makefile.in
+++ b/Examples/test-suite/tcl/Makefile.in
@@ -6,6 +6,7 @@ LANGUAGE = tcl
TCLSH = tclsh
SCRIPTSUFFIX = _runme.tcl
+HAVE_CXX11 = @HAVE_CXX11@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
diff --git a/Makefile.in b/Makefile.in
index 6edfc240a..f4cb794d8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -29,7 +29,6 @@ TARGET = $(TARGET_NOEXE)@EXEEXT@
SOURCE = Source
CCACHE = CCache
DOCS = Doc/Manual
-HAVE_CXX11 = @HAVE_CXX11@
swig: libfiles source ccache
@@ -249,7 +248,7 @@ check-%-test-suite:
echo warning: cannot $(ACTION) $* test-suite "(no dir $$dir)";\
else \
echo $(ACTION)ing $* test-suite; \
- (cd $$dir && $(MAKE) $(FLAGS) $(ACTION) HAVE_CXX11=$(HAVE_CXX11)) \
+ (cd $$dir && $(MAKE) $(FLAGS) $(ACTION)) \
|| passed=false; \
fi; \
test $$passed = true
From 2ded25d138ba51152087aebde9ab5c2d685519fc Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 28 Mar 2022 09:15:57 +0100
Subject: [PATCH 390/662] Fixes for ISO C89
---
Source/CParse/cscanner.c | 3 ++-
Source/Swig/naming.c | 2 +-
Source/Swig/tree.c | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
index 85d350cdc..a658f5a6f 100644
--- a/Source/CParse/cscanner.c
+++ b/Source/CParse/cscanner.c
@@ -955,6 +955,7 @@ int yylex(void) {
} else {
/* SWIG directives */
+ String *stext = 0;
if (strcmp(yytext, "%module") == 0)
return (MODULE);
if (strcmp(yytext, "%insert") == 0)
@@ -1041,7 +1042,7 @@ int yylex(void) {
* the operator.
*/
cparse_unknown_directive = NewString(yytext);
- String *stext = NewString(yytext + 1);
+ stext = NewString(yytext + 1);
Seek(stext,0,SEEK_SET);
Setfile(stext,cparse_file);
Setline(stext,cparse_line);
diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c
index 1599941b7..4d07d5b2f 100644
--- a/Source/Swig/naming.c
+++ b/Source/Swig/naming.c
@@ -1101,6 +1101,7 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) {
int errornum;
size_t errpos;
int rc;
+ pcre2_match_data *match_data = 0;
compiled_pat = pcre2_compile((PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, 0, &errornum, &errpos, NULL);
if (!compiled_pat) {
@@ -1111,7 +1112,6 @@ static int name_regexmatch_value(Node *n, String *pattern, String *s) {
Exit(EXIT_FAILURE);
}
- pcre2_match_data *match_data = 0;
match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL);
rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)Char(s), PCRE2_ZERO_TERMINATED, 0, 0, match_data, 0);
pcre2_code_free(compiled_pat);
diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c
index bc552988c..7033bbefb 100644
--- a/Source/Swig/tree.c
+++ b/Source/Swig/tree.c
@@ -80,6 +80,7 @@ static void print_indent(int l) {
void Swig_print_node(Node *obj) {
Iterator ki;
Node *cobj;
+ List *keys = Keys(obj);
print_indent(0);
if (debug_quiet)
@@ -87,7 +88,6 @@ void Swig_print_node(Node *obj) {
else
Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
- List *keys = Keys(obj);
SortList(keys, 0);
ki = First(keys);
while (ki.item) {
From e1e4e4df285bfdb2de3de49cf2409783de4ae79a Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 28 Mar 2022 09:16:46 +0100
Subject: [PATCH 391/662] Add rvalue reference typemaps for D
---
Lib/d/dswigtype.swg | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index f0d604b6f..1d97cb089 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -20,6 +20,10 @@
%typemap(imtype) SWIGTYPE & "void*"
%typemap(dtype, nativepointer="$dtype") SWIGTYPE & "$dclassname"
+%typemap(ctype) SWIGTYPE && "void *"
+%typemap(imtype) SWIGTYPE && "void*"
+%typemap(dtype, nativepointer="$dtype") SWIGTYPE && "$dclassname"
+
%typemap(ctype) SWIGTYPE *const& "void *"
%typemap(imtype) SWIGTYPE *const& "void*"
%typemap(dtype) SWIGTYPE *const& "$*dclassname"
@@ -28,6 +32,7 @@
SWIGTYPE,
SWIGTYPE *,
SWIGTYPE &,
+ SWIGTYPE &&,
SWIGTYPE [],
SWIGTYPE *const&
""
@@ -148,6 +153,43 @@
}
+/*
+ * Rvalue reference conversion typemaps.
+ */
+
+%typemap(in, canthrow=1) SWIGTYPE && %{ $1 = ($1_ltype)$input;
+ if (!$1) {
+ SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type type is null");
+ return $null;
+ } %}
+%typemap(out) SWIGTYPE && "$result = (void *)$1;"
+
+%typemap(directorin) SWIGTYPE &&
+ "$input = ($1_ltype) &$1;"
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE &&
+%{ if (!$input) {
+ SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
+ return $null;
+ }
+ $result = ($1_ltype)$input; %}
+
+%typemap(ddirectorin,
+ nativepointer="cast($dtype)$winput"
+) SWIGTYPE && "new $dclassname($winput, false)"
+%typemap(ddirectorout,
+ nativepointer="cast(void*)$dcall"
+) SWIGTYPE && "$dclassname.swigGetCPtr($dcall)"
+
+%typemap(din,
+ nativepointer="cast(void*)$dinput"
+) SWIGTYPE && "$dclassname.swigGetCPtr($dinput)"
+%typemap(dout, excode=SWIGEXCODE,
+ nativepointer="{\n auto ret = cast($dtype)$imcall;$excode\n return ret;\n}") SWIGTYPE && {
+ $dclassname ret = new $dclassname($imcall, $owner);$excode
+ return ret;
+}
+
+
/*
* Array conversion typemaps.
*/
@@ -164,6 +206,7 @@
// Treat references to arrays like references to a single element.
%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
+%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
/*
From 8be06d0e8c09b17338fef7585886444718c64d2c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 28 Mar 2022 09:21:46 +0100
Subject: [PATCH 392/662] Correct MzScheme and OCaml GHA testing
---
.github/workflows/ci.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 65ec30886..48c3d0459 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -295,9 +295,11 @@ jobs:
# Experimental languages (these are allowed to fail)
- SWIGLANG: mzscheme
CPPSTD: c++17
+ GCC: 11
continue-on-error: true
- SWIGLANG: ocaml
CPPSTD: c++17
+ GCC: 11
continue-on-error: true
os: ubuntu-18.04 # ocaml-4.08 in ubuntu-20.04 not yet working
# Run all of them, as opposed to aborting when one fails
From 0b157406638dc0a37b01a9f498577a2a72e9108c Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 28 Mar 2022 19:30:47 +0100
Subject: [PATCH 393/662] Fix warning in D test-suite
---
.../test-suite/csharp/multiple_inheritance_overload_runme.cs | 4 ++--
.../test-suite/java/multiple_inheritance_overload_runme.java | 4 ++--
Examples/test-suite/multiple_inheritance_overload.i | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs
index 4036722a9..24a284931 100644
--- a/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs
+++ b/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs
@@ -29,7 +29,7 @@ public class multiple_inheritance_overload_runme {
check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
- Base db1 = BaseSwigImpl.inout(d1);
+ Base db1 = BaseSwigImpl.in_out(d1);
check(db1.Method(i) != 0, "db1.Method failed");
check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
@@ -47,7 +47,7 @@ public class multiple_inheritance_overload_runme {
check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
- Base mb2 = BaseSwigImpl.inout(m1);
+ Base mb2 = BaseSwigImpl.in_out(m1);
check(mb2.Method(i) != 0, "mb2.Method failed");
check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
diff --git a/Examples/test-suite/java/multiple_inheritance_overload_runme.java b/Examples/test-suite/java/multiple_inheritance_overload_runme.java
index d2cc3ed71..e516e7738 100644
--- a/Examples/test-suite/java/multiple_inheritance_overload_runme.java
+++ b/Examples/test-suite/java/multiple_inheritance_overload_runme.java
@@ -36,7 +36,7 @@ public class multiple_inheritance_overload_runme {
check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
- Base db1 = BaseSwigImpl.inout(d1);
+ Base db1 = BaseSwigImpl.in_out(d1);
check(db1.Method(i) != 0, "db1.Method failed");
check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
@@ -54,7 +54,7 @@ public class multiple_inheritance_overload_runme {
check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
- Base mb2 = BaseSwigImpl.inout(m1);
+ Base mb2 = BaseSwigImpl.in_out(m1);
check(mb2.Method(i) != 0, "mb2.Method failed");
check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
diff --git a/Examples/test-suite/multiple_inheritance_overload.i b/Examples/test-suite/multiple_inheritance_overload.i
index 77f5a9ad4..237ebd6f1 100644
--- a/Examples/test-suite/multiple_inheritance_overload.i
+++ b/Examples/test-suite/multiple_inheritance_overload.i
@@ -47,7 +47,7 @@ public:
virtual int SimilarOverloadedMethod(Integer i) { return 0; }
virtual int SimilarOverloadedMethod(unsigned short i) { return 1; }
virtual ~Base() {}
- static Base *inout(Base *p) { return p; }
+ static Base *in_out(Base *p) { return p; }
};
class Derived : public Base, public AnotherSpace::AnotherBase
From 4c074415498ff47cf79cf05215f1803d4c79177d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 29 Mar 2022 09:01:18 +0100
Subject: [PATCH 394/662] GHA: MzScheme go back to c++98 testing
MzScheme headers have a problem when using -Werror that the test-suite uses:
/usr/include/racket/sconfig.h:126:43: error: invalid suffix on literal; C++11 requires a space between literal and string macro [-Werror=literal-suffix]
126 | # define SCHEME_PLATFORM_LIBRARY_SUBPATH "x86_64-"SPLS_LINUX
---
.github/workflows/ci.yml | 2 --
1 file changed, 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 48c3d0459..2f9d128b7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -294,8 +294,6 @@ jobs:
GCC: 11
# Experimental languages (these are allowed to fail)
- SWIGLANG: mzscheme
- CPPSTD: c++17
- GCC: 11
continue-on-error: true
- SWIGLANG: ocaml
CPPSTD: c++17
From ef3f25ab1c03d37802d9c228a5dab2946b549a3b Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Fri, 1 Apr 2022 11:24:15 +1300
Subject: [PATCH 395/662] Remove -browse command line option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This option was undocumented. If used it quietly did nothing
unless you'd installed the SWILL library before building SWIG, but
SWILL is no longer maintained and hasn't seen a release since
2008-04-10.
It's clear nobody has used this functionality for some time as the
code to support it in SWIG isn't actually valid ISO C++:
Modules/browser.cxx: In member function ‘void Browser::show_attributes(Node*)’:
Modules/browser.cxx:57:23: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
57 | char *trunc = "";
| ^~
Modules/browser.cxx:61:21: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
61 | trunc = "...";
| ^~~~~
Closes #2251
---
CHANGES.current | 3 +
Source/Makefile.am | 6 +-
Source/Modules/browser.cxx | 421 -------------------------------------
Source/Modules/main.cxx | 7 -
Source/Modules/swigmod.h | 8 +-
configure.ac | 4 -
6 files changed, 7 insertions(+), 442 deletions(-)
delete mode 100644 Source/Modules/browser.cxx
diff --git a/CHANGES.current b/CHANGES.current
index 7ce58028d..99581a84b 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-04-01: olly
+ Remove undocumented and non-functional -browse command line option.
+
2022-03-26: eltoder
[Python] #1684 Use different capsule names with and without -builtin
diff --git a/Source/Makefile.am b/Source/Makefile.am
index 5cfb88839..095c5d4ea 100644
--- a/Source/Makefile.am
+++ b/Source/Makefile.am
@@ -6,8 +6,6 @@ AUTOMAKE_OPTIONS = foreign nostdinc subdir-objects 1.7.2
SOURCE_DIR=$(top_srcdir)/Source
BUILD_SOURCE_DIR=$(top_builddir)/Source
-SWIG_CXX_DEFS = @SWILL@
-
AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \
-I$(BUILD_SOURCE_DIR)/CParse \
-I$(SOURCE_DIR)/Include \
@@ -18,7 +16,7 @@ AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \
-I$(SOURCE_DIR)/Swig \
-I$(SOURCE_DIR)/Modules
-AM_CXXFLAGS = $(SWIG_CXX_DEFS)
+AM_CXXFLAGS =
AM_YFLAGS = -d
@@ -46,7 +44,6 @@ eswig_SOURCES = CParse/cscanner.c \
Doxygen/pydoc.cxx \
Doxygen/pydoc.h \
Modules/allocate.cxx \
- Modules/browser.cxx \
Modules/contract.cxx \
Modules/csharp.cxx \
Modules/d.cxx \
@@ -98,7 +95,6 @@ eswig_SOURCES = CParse/cscanner.c \
Swig/wrapfunc.c
bin_PROGRAMS = eswig
-eswig_LDADD = @SWIGLIBS@
# Override the link stage to avoid using Libtool
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/Source/Modules/browser.cxx b/Source/Modules/browser.cxx
deleted file mode 100644
index 217b40a7e..000000000
--- a/Source/Modules/browser.cxx
+++ /dev/null
@@ -1,421 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * browser.cxx
- *
- * A web-base parse tree browser using SWILL. This is an optional
- * feature that's normally disabled.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-#ifdef SWIG_SWILL
-extern "C" {
-#include "swill.h"
-} static FILE *out = 0;
-static Node *view_top = 0;
-
-class Browser:public Dispatcher {
- void show_checkbox(Node *t, Node *n) {
- int v = 0;
- if (Getmeta(n, "visible")) {
- v = 1;
- }
- if (v) {
- Printf(out, "[-] ", n, t, n, n);
- } else {
- Printf(out, "[+] ", n, t, n, n);
- }
- }
- void show_attributes(Node *obj) {
- if (!Getmeta(obj, "visible"))
- return;
- String *os = NewString("");
- String *k;
- Iterator ki;
- ki = First(obj);
- while (ki.key) {
- k = ki.key;
- if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
- (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
- /* Do nothing */
- } else if (Cmp(k, "parms") == 0) {
- String *o = NewString("");
- Printf(o, "%s", ParmList_protostr(Getattr(obj, k)));
- Replaceall(o, "&", "&");
- Replaceall(o, "<", "<");
- Replaceall(o, ">", ">");
- Printf(os, "? %-12s - %s\n", Getattr(obj, k), k, o);
- Delete(o);
- } else {
- DOH *o;
- char *trunc = "";
- if (DohIsString(Getattr(obj, k))) {
- o = Str(Getattr(obj, k));
- if (Len(o) > 70) {
- trunc = "...";
- }
- Replaceall(o, "&", "&");
- Replaceall(o, "<", "<");
- Printf(os, "? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc);
- Delete(o);
- } else {
- Printf(os, "? %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k));
- }
- }
- ki = Next(ki);
- }
- Printf(out, "\n%s
\n", Char(os));
- Delete(os);
- }
-
-public:
- virtual int emit_one(Node *n) {
- char *tag = Char(nodeType(n));
- char *file = Char(Getfile(n));
- int line = Getline(n);
- char *name = GetChar(n, "name");
-
- show_checkbox(view_top, n);
- Printf(out, "%s", n, tag);
- if (name) {
- Printf(out, " (%s)", name);
- }
- Printf(out, ". %s:%d\n", file, line);
- Printf(out, "
");
- Dispatcher::emit_one(n);
- return SWIG_OK;
- }
- virtual int emit_children(Node *n) {
- if (Getmeta(n, "visible")) {
- Printf(out, "\n");
- Dispatcher::emit_children(n);
- Printf(out, "
\n");
- }
- return SWIG_OK;
- }
- virtual int defaultHandler(Node *n) {
- show_attributes(n);
- return SWIG_OK;
- }
- virtual int top(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int includeDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int importDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int extendDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int classDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int templateDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int lambdaDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
- virtual int enumDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int typemapDirective(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int namespaceDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
- virtual int usingDeclaration(Node *n) {
- show_attributes(n);
- emit_children(n);
- return SWIG_OK;
- }
-
-};
-
-static int browser_exit = 0;
-static Node *tree_top = 0;
-static Browser *browse = 0;
-
-/* ----------------------------------------------------------------------
- * exit_handler() - Force the browser to exit
- * ---------------------------------------------------------------------- */
-
-void exit_handler(FILE *f) {
- browser_exit = 1;
- Printf(f, "Terminated.\n");
-}
-
-/* ----------------------------------------------------------------------
- * node_handler() - Generate information about a specific node
- * ---------------------------------------------------------------------- */
-
-static void display(FILE *f, Node *n) {
- /* Print standard HTML header */
-
- Printf(f, "SWIG-%s\n", Swig_package_version());
- Printf(f, "SWIG-%s
\n", Swig_package_version());
- Printf(f, "[ Exit ]");
- Printf(f, " [ Top ]", tree_top);
- if (n != tree_top) {
- Printf(f, " [ Up ]", parentNode(n));
- }
- Printf(f, " [ Symbols ]");
- Printf(f, "
\n");
-
- out = f;
-
- browse->emit_one(n);
-
- /* Print standard footer */
- Printf(f, "
\n");
-
-}
-
-void node_handler(FILE *f) {
- Node *n = 0;
- if (!swill_getargs("p(node)", &n)) {
- n = tree_top;
- }
- view_top = n;
- display(f, n);
-}
-
-
-/* ----------------------------------------------------------------------
- * hide_handler() - Hide a node
- * ---------------------------------------------------------------------- */
-
-void hide_handler(FILE *f) {
- Node *n = 0;
- if (!swill_getargs("p(hn)", &n)) {
- n = 0;
- }
- if (n) {
- Delmeta(n, "visible");
- }
- node_handler(f);
-}
-
-void show_handler(FILE *f) {
- Node *n = 0;
- if (!swill_getargs("p(hn)", &n)) {
- n = 0;
- }
- if (n) {
- Setmeta(n, "visible", "1");
- }
- node_handler(f);
-}
-
-void raw_data(FILE *out, Node *obj) {
- if (!obj)
- return;
- if (DohIsMapping(obj)) {
- String *k;
- Iterator ki;
- String *os = NewString("");
- Printf(os, "Hash {\n");
- ki = First(obj);
- while (ki.key) {
- k = ki.key;
- DOH *o;
- const char *trunc = "";
- if (DohIsString(Getattr(obj, k))) {
- o = Str(Getattr(obj, k));
- if (Len(o) > 70) {
- trunc = "...";
- }
- Replaceall(o, "<", "<");
- Printf(os, " ? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc);
- Delete(o);
- } else {
- Printf(os, " ? %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k));
- }
- ki = Next(ki);
- }
- Printf(os, "}\n");
- Printf(out, "\n%s
\n", Char(os));
- Delete(os);
- } else if (DohIsString(obj)) {
- String *o = Str(obj);
- Replaceall(o, "<", "<");
- Printf(out, "\n%s
\n", Char(o));
- Delete(o);
- } else if (DohIsSequence(obj)) {
- int i;
- String *os = NewString("");
- Printf(os, "List [\n");
- for (i = 0; i < Len(obj); i++) {
- DOH *o = Getitem(obj, i);
- const char *trunc = "";
- if (DohIsString(o)) {
- String *s = Str(o);
- if (Len(s) > 70) {
- trunc = "...";
- }
- Replaceall(o, "<", "<");
- Printf(os, " ? [%d] - \"%(escape)-0.70s%s\"\n", o, i, s, trunc);
- Delete(s);
- } else {
- Printf(os, " ? [%d] - %p\n", o, i, o);
- }
- }
- Printf(os, "\n]\n");
- Printf(out, "\n%s
\n", Char(os));
- Delete(os);
- }
-}
-
-void data_handler(FILE *f) {
- DOH *n = 0;
- if (!swill_getargs("p(n)", &n)) {
- n = 0;
- }
- Printf(f, "SWIG-%s\n", Swig_package_version());
- Printf(f, "SWIG-%s
\n", Swig_package_version());
- Printf(f, "[ Exit ]");
- Printf(f, " [ Top ]", tree_top);
- Printf(f, "
\n");
- if (n) {
- raw_data(f, n);
- }
- /* Print standard footer */
- Printf(f, "
\n");
-}
-
-void symbol_handler(FILE *f) {
- Symtab *sym;
- char *name = 0;
-
- Printf(f, "SWIG-%s\n", Swig_package_version());
- Printf(f, "SWIG-%s
\n", Swig_package_version());
- Printf(f, "[ Exit ]");
- Printf(f, " [ Top ]", tree_top);
- Printf(f, " [ Symbols ]");
- Printf(f, "
\n");
-
- if (!swill_getargs("p(sym)|s(name)", &sym, &name)) {
- sym = Swig_symbol_getscope("");
- name = 0;
- }
- if (!sym) {
- Printf(f, "No symbol table specified!\n");
- return;
- }
- {
- String *q = Swig_symbol_qualifiedscopename(sym);
- if (!Len(q)) {
- Printf(f, "Symbol table: :: (global)
\n");
- } else {
- Printf(f, "Symbol table: %s
\n", q);
- }
- Delete(q);
- }
-
- fprintf(f, "
");
-
- if (name) {
- Node *n = Swig_symbol_clookup(name, sym);
- Printf(f, "Symbol '%s':\n", name);
- Printf(f, "\n");
- if (!n) {
- Printf(f, "Not defined!\n");
- } else {
- raw_data(f, n);
- }
- Printf(f, "
\n");
- }
-
- Printf(f, "Nested scopes
\n");
- Printf(f, "
\n");
- {
- Hash *h;
- h = firstChild(sym);
- while (h) {
- Printf(f, "%s\n", h, Getattr(h, "name"));
- h = nextSibling(h);
- }
- }
- Printf(f, "
\n");
-
- Printf(f, "Symbol table contents\n");
- raw_data(f, Getattr(sym, "symtab"));
- Printf(f, "
\n");
-
-}
-#endif
-
-void Swig_browser(Node *top, int port) {
-#ifdef SWIG_SWILL
- int sport;
- browser_exit = 0;
-
- /* Initialize the server */
- sport = swill_init(port);
- if (sport < 0) {
- Printf(stderr, "Couldn't open socket on port %d. Sorry.\n", port);
- return;
- }
- browse = new Browser();
- Setmeta(top, "visible", "1");
- tree_top = top;
-
- Printf(stderr, "SWIG: Tree browser listening on port %d\n", sport);
-
- swill_handle("exit.html", exit_handler, 0);
- swill_handle("index.html", node_handler, 0);
- swill_handle("hide.html", hide_handler, 0);
- swill_handle("show.html", show_handler, 0);
- swill_handle("data.html", data_handler, 0);
- swill_handle("symbol.html", symbol_handler, 0);
- swill_netscape("index.html");
-
- while (!browser_exit) {
- swill_serve();
- }
- Printf(stderr, "Browser terminated.\n");
- swill_close();
- delete browse;
- return;
-#else
- (void) top;
- (void) port;
-#endif
-}
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index f412a3eeb..9344a7299 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -194,7 +194,6 @@ static int dump_tags = 0;
static int dump_module = 0;
static int dump_top = 0;
static int dump_xml = 0;
-static int browse = 0;
static int dump_typedef = 0;
static int dump_classes = 0;
static int werror = 0;
@@ -850,9 +849,6 @@ static void getoptions(int argc, char *argv[]) {
} else if (strcmp(argv[i], "-nocontract") == 0) {
Swig_mark_arg(i);
Swig_contract_mode_set(0);
- } else if (strcmp(argv[i], "-browse") == 0) {
- browse = 1;
- Swig_mark_arg(i);
} else if ((strcmp(argv[i], "-debug-typedef") == 0) || (strcmp(argv[i], "-dump_typedef") == 0)) {
dump_typedef = 1;
Swig_mark_arg(i);
@@ -1335,9 +1331,6 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
lang->top(top);
- if (browse) {
- Swig_browser(top, 0);
- }
Delete(infile_filename);
Delete(basename);
}
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index 3661a2b61..de6ee48ef 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -430,16 +430,14 @@ extern "C" {
void Swig_print_with_location(DOH *object, int count = -1);
}
+void Swig_default_allocators(Node *n);
+void Swig_process_types(Node *n);
+
/* Contracts */
void Swig_contracts(Node *n);
void Swig_contract_mode_set(int flag);
int Swig_contract_mode_get();
-/* Browser */
-void Swig_browser(Node *n, int);
-void Swig_default_allocators(Node *n);
-void Swig_process_types(Node *n);
-
/* Nested classes */
void Swig_nested_process_classes(Node *n);
void Swig_nested_name_unnamed_c_structs(Node *n);
diff --git a/configure.ac b/configure.ac
index feda58891..2afaf2275 100644
--- a/configure.ac
+++ b/configure.ac
@@ -460,10 +460,6 @@ AC_SEARCH_LIBS(t_open, nsl) # SVR4
AC_SEARCH_LIBS(gethostbyname, inet) # Sequent
AC_SEARCH_LIBS(socket, socket) # SVR4 sockets
-AC_CHECK_LIB(swill, swill_init, [SWIGLIBS="-lswill $LIBS" SWILL="-DSWIG_SWILL"])
-AC_SUBST(SWIGLIBS)
-AC_SUBST(SWILL)
-
# check for --with-libm=...
AC_SUBST(LIBM)
LIBM=-lm
From 471df4823b977525e304a137fb87255239737f5d Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Mon, 4 Apr 2022 08:59:36 +1200
Subject: [PATCH 396/662] Don't call skip_decl() on "Syntax error in input(3)"
This is a useless left-over from long ago (2007) when we didn't exit
right away after reporting this error.
---
Source/CParse/parser.y | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 7a5ef42c5..b6ded8381 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4670,9 +4670,7 @@ cpp_members : cpp_member cpp_members {
| include_directive { $$ = $1; }
| empty { $$ = 0;}
| error {
- int start_line = cparse_line;
- skip_decl();
- Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
+ Swig_error(cparse_file,cparse_line,"Syntax error in input(3).\n");
Exit(EXIT_FAILURE);
} cpp_members {
$$ = $3;
From 322574722bc2d1a2b951f736c4ce840bd921580b Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 30 Mar 2022 20:16:28 +0100
Subject: [PATCH 397/662] Testcase warning fix for c# old versions of MSVC
---
Examples/test-suite/cpp_typedef.i | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Examples/test-suite/cpp_typedef.i b/Examples/test-suite/cpp_typedef.i
index d77485c77..8578988e9 100644
--- a/Examples/test-suite/cpp_typedef.i
+++ b/Examples/test-suite/cpp_typedef.i
@@ -3,7 +3,7 @@
%module cpp_typedef
%{
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && _MSC_VER >= 1900
#pragma warning( disable : 5208) // warning C5208: unnamed class used in typedef name cannot declare members other than non-static data members, member enumerations, or member classes
#endif
From e8c1bda0b5f3ed940797a01cf6988a298ab69bf8 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 2 Apr 2022 18:57:11 +0100
Subject: [PATCH 398/662] D compiler detection enhancements
Detect LLVM D compiler ldmd2 or ldc2.
Show D version. Note that dmd does not have an
explicit command line option to show version.
---
Examples/Makefile.in | 3 +--
configure.ac | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index 1a27b32cd..d7b9a5bcf 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -1626,8 +1626,7 @@ d_run:
# -----------------------------------------------------------------
d_version:
- # Needs improvement!
- echo D version guess - $(D_VERSION)
+ ($(DCOMPILER) --version 2> /dev/null || $(DCOMPILER)) | head -n 3
# -----------------------------------------------------------------
# Clean the D examples
diff --git a/configure.ac b/configure.ac
index 2afaf2275..360b2f440 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2568,7 +2568,7 @@ _ACEOF
fi
if test -z "$D2COMPILERBIN" ; then
- AC_CHECK_PROGS(D2COMPILER, dmd gdmd)
+ AC_CHECK_PROGS(D2COMPILER, dmd gdmd ldmd2 ldc2)
if test -n "$D2COMPILER" ; then
AC_MSG_CHECKING(whether the D2 compiler works)
From b35ebc81a97bfdf813020215b1f9086690fd5c10 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 6 Apr 2022 08:08:14 +0100
Subject: [PATCH 399/662] Doxygen comments take precedence over the autodoc
feature.
If a "docstring" feature is present it will still override a Doxygen comment.
If the "autodoc" feature is also present, the combined "autodoc" and "docstring"
will override the Doxygen comment. If no "docstring" is present then the
"autodoc" feature will not be generated when there is a Doxygen comment.
This way the "autodoc" feature can be specified and used to provide documentation
for 'missing' Doxygen comments.
Closes #1635
---
CHANGES.current | 14 ++++
Doc/Manual/Contents.html | 1 +
Doc/Manual/Python.html | 24 +++++++
Examples/test-suite/common.mk | 1 +
.../test-suite/doxygen_autodoc_docstring.i | 66 +++++++++++++++++++
.../python/doxygen_autodoc_docstring_runme.py | 44 +++++++++++++
Source/Modules/python.cxx | 47 ++++++-------
7 files changed, 175 insertions(+), 22 deletions(-)
create mode 100644 Examples/test-suite/doxygen_autodoc_docstring.i
create mode 100644 Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
diff --git a/CHANGES.current b/CHANGES.current
index 99581a84b..690a12938 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,20 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-04-06: wsfulton
+ [Python] #1635 The "autodoc" feature no longer overrides Doxygen comments
+ in the generated docstring.
+
+ If a "docstring" feature is present it will still override a Doxygen comment.
+ If the "autodoc" feature is also present, the combined "autodoc" and "docstring"
+ will override the Doxygen comment. If no "docstring" is present then the
+ "autodoc" feature will not be generated when there is a Doxygen comment.
+
+ This way the "autodoc" feature can be specified and used to provide documentation
+ for 'missing' Doxygen comments.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
2022-04-01: olly
Remove undocumented and non-functional -browse command line option.
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 6b33b99db..57ef77087 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -1464,6 +1464,7 @@
%feature("autodoc", "docstring")
%feature("docstring")
+Doxygen comments
Python Packages
diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html
index e2c9c8630..ce6ed2877 100644
--- a/Doc/Manual/Python.html
+++ b/Doc/Manual/Python.html
@@ -114,6 +114,7 @@
- %feature("autodoc", "docstring")
%feature("docstring")
+Doxygen comments
Python Packages
@@ -152,6 +153,7 @@
+
This chapter describes SWIG's support of Python. SWIG is compatible
with all recent Python versions (Python 2.7 and Python >= 3.2). If you
@@ -5898,6 +5900,28 @@ with more than one line.
+
+
+
+
+Please see the separate Doxygen chapter for information
+on making use of C++ Doxygen comments and translating them into Python docstring comments.
+
+
+
+Note that when generating docstrings and Doxygen comments have also been turned on,
+the docstring feature will take precedence over a Doxygen comment.
+If the autodoc feature is also turned on, then it will be
+used in conjunction with the docstring feature.
+However, if there is no docstring feature present and there is a Doxygen comment, then the autodoc docstring will not be generated. The Doxygen comment alone will be used.
+
+
+
+This way, if the autodoc feature is specified globally it will fill in any missing
+Doxygen documentation comments.
+Doxygen comments can be overridden by using the docstring feature.
+
+
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 96660c0d7..57e663878 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -638,6 +638,7 @@ endif
ifdef HAS_DOXYGEN
DOXYGEN_TEST_CASES += \
doxygen_alias \
+ doxygen_autodoc_docstring \
doxygen_basic_notranslate \
doxygen_basic_translate \
doxygen_basic_translate_style2 \
diff --git a/Examples/test-suite/doxygen_autodoc_docstring.i b/Examples/test-suite/doxygen_autodoc_docstring.i
new file mode 100644
index 000000000..7dcaa56f5
--- /dev/null
+++ b/Examples/test-suite/doxygen_autodoc_docstring.i
@@ -0,0 +1,66 @@
+%module doxygen_autodoc_docstring
+
+%feature("autodoc", 1);
+
+%feature("docstring") ClassWithDocString "Class doc from docstring";
+%feature("docstring") functionWithDocString "Function doc from docstring";
+%feature("docstring") ClassWithDocStringAndDoxygenComment "Class doc from docstring overriding doxycomment";
+%feature("docstring") functionWithDocStringAndDoxygenComment "Function doc from docstring overriding doxycomment";
+
+%inline %{
+class ClassWithoutDoxygenComment {};
+
+void functionWithoutDoxygenComment(int number) {}
+
+/**
+ * Class doxygen comment
+ */
+class ClassWithDoxygenComment {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDoxygenComment(int number) {}
+
+class ClassWithDocString {};
+
+void functionWithDocString(int number) {}
+
+/**
+ * Class doxygen comment
+ */
+class ClassWithDocStringAndDoxygenComment {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDocStringAndDoxygenComment(int number) {}
+%}
+
+
+%feature("autodoc", ""); // clear autodoc
+
+%feature("docstring") ClassWithDocStringAndDoxygenCommentNoAutodoc "Class doc from docstring overriding doxycomment (no autodoc)";
+%feature("docstring") functionWithDocStringAndDoxygenCommentNoAutodoc "Function doc from docstring overriding doxycomment (no autodoc)";
+
+%inline %{
+/**
+ * Class doxygen comment
+ */
+class ClassWithDocStringAndDoxygenCommentNoAutodoc {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDocStringAndDoxygenCommentNoAutodoc(int number) {}
+
+/**
+ * Class doxygen comment 2
+ */
+class ClassWithDoxygenComment2 {};
+
+/**
+ * Function doxygen comment 2
+ */
+void functionWithDoxygenComment2(int number) {}
+%}
diff --git a/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
new file mode 100644
index 000000000..7dac428cb
--- /dev/null
+++ b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
@@ -0,0 +1,44 @@
+from doxygen_autodoc_docstring import *
+import inspect
+import string
+import os
+import sys
+import comment_verifier
+
+# documentation from autogenerated 'feature:autodoc'
+comment_verifier.check(inspect.getdoc(ClassWithoutDoxygenComment),
+ "Proxy of C++ ClassWithoutDoxygenComment class.")
+comment_verifier.check(inspect.getdoc(functionWithoutDoxygenComment),
+ "functionWithoutDoxygenComment(int number)")
+
+# documentation from doxygen comments
+comment_verifier.check(inspect.getdoc(ClassWithDoxygenComment),
+ "Class doxygen comment")
+comment_verifier.check(inspect.getdoc(functionWithDoxygenComment),
+ "Function doxygen comment")
+
+# documentation from 'feature:docstring'
+comment_verifier.check(inspect.getdoc(ClassWithDocString),
+ "Class doc from docstring")
+comment_verifier.check(inspect.getdoc(functionWithDocString),
+ "functionWithDocString(int number)\n"
+ "Function doc from docstring")
+
+# documentation from 'feature:docstring' + autodoc (overriding doxycomment)
+comment_verifier.check(inspect.getdoc(ClassWithDocStringAndDoxygenComment),
+ "Class doc from docstring overriding doxycomment")
+comment_verifier.check(inspect.getdoc(functionWithDocStringAndDoxygenComment),
+ "functionWithDocStringAndDoxygenComment(int number)\n"
+ "Function doc from docstring overriding doxycomment")
+
+# documentation from 'feature:docstring' (overriding doxycomment)
+comment_verifier.check(inspect.getdoc(ClassWithDocStringAndDoxygenCommentNoAutodoc),
+ "Class doc from docstring overriding doxycomment (no autodoc)")
+comment_verifier.check(inspect.getdoc(functionWithDocStringAndDoxygenCommentNoAutodoc),
+ "Function doc from docstring overriding doxycomment (no autodoc)")
+
+# documentation from doxygen comments (2) no autodoc feature present
+comment_verifier.check(inspect.getdoc(ClassWithDoxygenComment2),
+ "Class doxygen comment 2")
+comment_verifier.check(inspect.getdoc(functionWithDoxygenComment2),
+ "Function doxygen comment 2")
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index b2e67ff10..915e3f97f 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -1492,16 +1492,18 @@ public:
/* ------------------------------------------------------------
* build_combined_docstring()
*
- * Build the full docstring which may be a combination of the
- * explicit docstring and autodoc string or, if none of them
- * is specified, obtained by translating Doxygen comment to
- * Python.
+ * Build the full docstring:
+ * Use the docstring if there is one present otherwise
+ * use the Doxygen comment if there is one present.
+ * Ignore autodoc if there is a Doxygen comment, otherwise
+ * create the autodoc string and append to any docstring.
*
* Return new string to be deleted by caller (never NIL but
* may be empty if there is no docstring).
* ------------------------------------------------------------ */
String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
+ bool add_autodoc = true;
String *docstr = Getattr(n, "feature:docstring");
if (docstr) {
// Simplify the code below by just ignoring empty docstrings.
@@ -1519,26 +1521,10 @@ public:
}
}
- if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
- String *autodoc = make_autodoc(n, ad_type, low_level);
- if (autodoc && Len(autodoc) > 0) {
- if (docstr) {
- Append(autodoc, "\n");
- Append(autodoc, docstr);
- }
-
- String *tmp = autodoc;
- autodoc = docstr;
- docstr = tmp;
- }
-
- Delete(autodoc);
- }
-
if (!docstr) {
- if (doxygen) {
+ if (doxygen && doxygenTranslator->hasDocumentation(n)) {
docstr = Getattr(n, "python:docstring");
- if (!docstr && doxygenTranslator->hasDocumentation(n)) {
+ if (!docstr) {
docstr = doxygenTranslator->getDocumentation(n, 0);
// Avoid rebuilding it again the next time: notice that we can't do
@@ -1554,9 +1540,26 @@ public:
// the cached object!
docstr = Copy(docstr);
}
+ add_autodoc = false;
}
}
+ if (add_autodoc && Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
+ String *autodoc = make_autodoc(n, ad_type, low_level);
+ if (autodoc && Len(autodoc) > 0) {
+ if (docstr) {
+ Append(autodoc, "\n");
+ Append(autodoc, docstr);
+ }
+
+ String *tmp = autodoc;
+ autodoc = docstr;
+ docstr = tmp;
+ }
+
+ Delete(autodoc);
+ }
+
if (!docstr)
docstr = NewString("");
From dba941120db4b573fd49eb3fb61287635173da2f Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 6 Apr 2022 19:39:24 +0100
Subject: [PATCH 400/662] Enable C++11 testing by default, Appveyor testing
scaled back
./configure now enables C++11 and later C++ standards testing by default (when
running: 'make check').
The options to control this testing are the same:
./configure --enable-cpp11-testing
./configure --disable-cpp11-testing
But the former is now the default and the latter can be used to turn off C++11 and
later C++ standards testing.
Reduce the number of tests on Appveyor by only running 32-bit (x86) using
latest Visual Studio (2022). Drop 32-bit Cygwin and MinGW testing.
Add C# and Java testing on VS2022 and drop Java testing on older Visual Studio.
This reduces the really long run times on Appveyor, however, VS2022 is
somewhat slower than older compilers.
---
.github/workflows/ci.yml | 3 ++-
CHANGES.current | 12 ++++++++++++
appveyor.yml | 26 +++++++++++++++++++++-----
configure.ac | 18 ++++++++++--------
4 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2f9d128b7..f6fb3ec7a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -392,7 +392,8 @@ jobs:
esac
echo CSTD="$CSTD" >> $GITHUB_ENV
fi
- if test -n "$CPPSTD"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=$CPPSTD $CXXFLAGS"); fi
+ if test -z "$CPPSTD"; then CONFIGOPTS+=("--disable-cpp11-testing"); fi
+ if test -n "$CPPSTD"; then CONFIGOPTS+=("CXXFLAGS=-std=$CPPSTD $CXXFLAGS"); fi
if test -n "$CSTD"; then CONFIGOPTS+=("CFLAGS=-std=$CSTD $CFLAGS"); fi
if test -n "$SWIGLANG"; then CONFIGOPTS+=(--without-alllang --with-$WITHLANG); fi
echo "${CONFIGOPTS[@]}"
diff --git a/CHANGES.current b/CHANGES.current
index 690a12938..b406611dc 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,18 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-04-06: wsfulton
+ ./configure now enables C++11 and later C++ standards testing by default (when
+ running: 'make check').
+
+ The options to control this testing are the same:
+
+ ./configure --enable-cpp11-testing
+ ./configure --disable-cpp11-testing
+
+ But the former is now the default and the latter can be used to turn off C++11 and
+ later C++ standards testing.
+
2022-04-06: wsfulton
[Python] #1635 The "autodoc" feature no longer overrides Doxygen comments
in the generated docstring.
diff --git a/appveyor.yml b/appveyor.yml
index 314cd3333..3a25ed199 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,4 @@
platform:
-- x86
- x64
skip_commits:
@@ -18,8 +17,6 @@ environment:
VSVER: 12
- SWIGLANG: csharp
VSVER: 14
- - SWIGLANG: java
- VSVER: 14
- SWIGLANG: python
VSVER: 14
VER: 27
@@ -34,10 +31,29 @@ environment:
VSVER: 16
VER: 39
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ - SWIGLANG: csharp
+ VSVER: 17
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: csharp
+ VSVER: 17
+ Platform: x86
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: java
+ VSVER: 17
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: java
+ VSVER: 17
+ Platform: x86
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- SWIGLANG: python
VSVER: 17
VER: 310
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+ - SWIGLANG: python
+ VSVER: 17
+ VER: 310
+ Platform: x86
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- SWIGLANG: python
OSVARIANT: cygwin
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
@@ -160,8 +176,8 @@ build_script:
- if "%BUILDSYSTEM%"=="cmake" cmake --version && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/WX /DPCRE2_STATIC" -DCMAKE_CXX_FLAGS="/WX /DPCRE2_STATIC" -DPCRE2_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE2_LIBRARY=%PCRE_ROOT%/lib/pcre2-8-static.lib -DBISON_EXECUTABLE=C:/cygwin/bin/bison.exe . && cmake --build . --config Release --target install && ctest --output-on-failure -V -C Release && appveyor exit
- if "%OSVARIANT%"=="" bash -c "exec 0
Date: Wed, 6 Apr 2022 20:51:37 +0100
Subject: [PATCH 401/662] Temporarily disable
doxygen_autodoc_docstring_runme.py
---
Examples/test-suite/python/doxygen_autodoc_docstring_runme.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
index 7dac428cb..bd6afe731 100644
--- a/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
+++ b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
@@ -5,6 +5,7 @@ import os
import sys
import comment_verifier
+exit(0) # temporarily skip runtime test until builtin is fixed
# documentation from autogenerated 'feature:autodoc'
comment_verifier.check(inspect.getdoc(ClassWithoutDoxygenComment),
"Proxy of C++ ClassWithoutDoxygenComment class.")
From da07af7fe20b7ec80f88bd44d9331e7ed82083af Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 6 Apr 2022 22:33:17 +0100
Subject: [PATCH 402/662] doxygen_autodoc_docstring test fix for Python builtin
---
Examples/test-suite/doxygen_autodoc_docstring.i | 9 +++++++++
.../test-suite/python/doxygen_autodoc_docstring_runme.py | 3 +--
Examples/test-suite/python_builtin.i | 1 -
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/Examples/test-suite/doxygen_autodoc_docstring.i b/Examples/test-suite/doxygen_autodoc_docstring.i
index 7dcaa56f5..e590d7f94 100644
--- a/Examples/test-suite/doxygen_autodoc_docstring.i
+++ b/Examples/test-suite/doxygen_autodoc_docstring.i
@@ -64,3 +64,12 @@ class ClassWithDoxygenComment2 {};
*/
void functionWithDoxygenComment2(int number) {}
%}
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+bool is_python_builtin() { return true; }
+#else
+bool is_python_builtin() { return false; }
+#endif
+%}
+
diff --git a/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
index bd6afe731..9780516b9 100644
--- a/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
+++ b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
@@ -5,10 +5,9 @@ import os
import sys
import comment_verifier
-exit(0) # temporarily skip runtime test until builtin is fixed
# documentation from autogenerated 'feature:autodoc'
comment_verifier.check(inspect.getdoc(ClassWithoutDoxygenComment),
- "Proxy of C++ ClassWithoutDoxygenComment class.")
+ "::ClassWithoutDoxygenComment" if is_python_builtin() else "Proxy of C++ ClassWithoutDoxygenComment class.")
comment_verifier.check(inspect.getdoc(functionWithoutDoxygenComment),
"functionWithoutDoxygenComment(int number)")
diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i
index 994c625e8..754526dad 100644
--- a/Examples/test-suite/python_builtin.i
+++ b/Examples/test-suite/python_builtin.i
@@ -244,4 +244,3 @@ public:
}
};
%}
-
From a5be4a10b5b22f35aa6fccd52e181ceb3d9fda03 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 6 Apr 2022 22:48:33 +0100
Subject: [PATCH 403/662] Slight performance improvement for %pythonnondynamic
Setting this is much more likely than thisown
---
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 915e3f97f..69984ae5e 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -737,10 +737,10 @@ public:
tab4, tab4, "if name in (\"this\", \"thisown\"):\n",
tab4, tab4, tab4, "set(self, name, value)\n",
#else
- tab4, tab4, "if name == \"thisown\":\n",
- tab4, tab4, tab4, "self.this.own(value)\n",
- tab4, tab4, "elif name == \"this\":\n",
+ tab4, tab4, "if name == \"this\":\n",
tab4, tab4, tab4, "set(self, name, value)\n",
+ tab4, tab4, "elif name == \"thisown\":\n",
+ tab4, tab4, tab4, "self.this.own(value)\n",
#endif
tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
tab4, tab4, tab4, "set(self, name, value)\n",
From 9c67a2c007be56aa5b9892e854ea141396645df9 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 6 Apr 2022 22:58:17 +0100
Subject: [PATCH 404/662] Remove legacy USE_THISOWN conditional compilation
Seems to be a left over from 'thisown' partial removal
in 985adc13fba238405028361a8d8e35e8b1b1008c
---
Source/Modules/python.cxx | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 69984ae5e..7e369b76c 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -733,15 +733,10 @@ public:
Printv(f_shadow, "\n",
"def _swig_setattr_nondynamic_instance_variable(set):\n",
tab4, "def set_instance_attr(self, name, value):\n",
-#ifdef USE_THISOWN
- tab4, tab4, "if name in (\"this\", \"thisown\"):\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
-#else
tab4, tab4, "if name == \"this\":\n",
tab4, tab4, tab4, "set(self, name, value)\n",
tab4, tab4, "elif name == \"thisown\":\n",
tab4, tab4, tab4, "self.this.own(value)\n",
-#endif
tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
tab4, tab4, tab4, "set(self, name, value)\n",
tab4, tab4, "else:\n",
@@ -3903,11 +3898,7 @@ public:
String *symname = Getattr(n, "sym:name");
String *mrename = Swig_name_disown(NSPACE_TODO, symname); //Getattr(n, "name"));
Printv(f_shadow, tab4, "def __disown__(self):\n", NIL);
-#ifdef USE_THISOWN
- Printv(f_shadow, tab8, "self.thisown = 0\n", NIL);
-#else
Printv(f_shadow, tab8, "self.this.disown()\n", NIL);
-#endif
Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL);
Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL);
Delete(mrename);
@@ -4969,9 +4960,6 @@ public:
if (have_pythonprepend(n))
Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
-#ifdef USE_THISOWN
- Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
-#endif
if (have_pythonappend(n))
Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow_stubs, tab4, "return val\n", NIL);
@@ -5027,12 +5015,6 @@ public:
Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
-#ifdef USE_THISOWN
- Printv(f_shadow, tab8, "try:\n", NIL);
- Printv(f_shadow, tab8, tab4, "if self.thisown:", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL);
- Printv(f_shadow, tab8, "except __builtin__.Exception: pass\n", NIL);
-#else
-#endif
if (have_pythonappend(n))
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow, tab8, "pass\n", NIL);
From a12fc916e4070958f95e492351e0702192128ca3 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 6 Apr 2022 23:06:48 +0100
Subject: [PATCH 405/662] Remove unused functions in Python builtin mode
---
Source/Modules/python.cxx | 91 ++++++++++++++++++++-------------------
1 file changed, 47 insertions(+), 44 deletions(-)
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 7e369b76c..5b7f535ce 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -712,9 +712,11 @@ public:
Printv(default_import_code, tab4, "from ", module, " import *\n", NULL);
}
- /* Need builtins to qualify names like Exception that might also be
- defined in this module (try both Python 3 and Python 2 names) */
- Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
+ if (!builtin) {
+ /* Need builtins to qualify names like Exception that might also be
+ defined in this module (try both Python 3 and Python 2 names) */
+ Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
+ }
if (!builtin && fastproxy) {
Printf(f_shadow, "\n");
@@ -722,53 +724,54 @@ public:
Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module);
}
- Printv(f_shadow, "\n",
- "def _swig_repr(self):\n",
- tab4, "try:\n",
- tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
- tab4, "except __builtin__.Exception:\n",
- tab4, tab4, "strthis = \"\"\n",
- tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
+ if (!builtin) {
+ Printv(f_shadow, "\n",
+ "def _swig_repr(self):\n",
+ tab4, "try:\n",
+ tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
+ tab4, "except __builtin__.Exception:\n",
+ tab4, tab4, "strthis = \"\"\n",
+ tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
- Printv(f_shadow, "\n",
- "def _swig_setattr_nondynamic_instance_variable(set):\n",
- tab4, "def set_instance_attr(self, name, value):\n",
- tab4, tab4, "if name == \"this\":\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
- tab4, tab4, "elif name == \"thisown\":\n",
- tab4, tab4, tab4, "self.this.own(value)\n",
- tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
- tab4, tab4, tab4, "set(self, name, value)\n",
- tab4, tab4, "else:\n",
- tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
- tab4, "return set_instance_attr\n\n", NIL);
+ Printv(f_shadow, "\n",
+ "def _swig_setattr_nondynamic_instance_variable(set):\n",
+ tab4, "def set_instance_attr(self, name, value):\n",
+ tab4, tab4, "if name == \"this\":\n",
+ tab4, tab4, tab4, "set(self, name, value)\n",
+ tab4, tab4, "elif name == \"thisown\":\n",
+ tab4, tab4, tab4, "self.this.own(value)\n",
+ tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
+ tab4, tab4, tab4, "set(self, name, value)\n",
+ tab4, tab4, "else:\n",
+ tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
+ tab4, "return set_instance_attr\n\n", NIL);
- Printv(f_shadow, "\n",
- "def _swig_setattr_nondynamic_class_variable(set):\n",
- tab4, "def set_class_attr(cls, name, value):\n",
- tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
- tab4, tab4, tab4, "set(cls, name, value)\n",
- tab4, tab4, "else:\n",
- tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
- tab4, "return set_class_attr\n\n", NIL);
+ Printv(f_shadow, "\n",
+ "def _swig_setattr_nondynamic_class_variable(set):\n",
+ tab4, "def set_class_attr(cls, name, value):\n",
+ tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
+ tab4, tab4, tab4, "set(cls, name, value)\n",
+ tab4, tab4, "else:\n",
+ tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
+ tab4, "return set_class_attr\n\n", NIL);
- Printv(f_shadow, "\n",
- "def _swig_add_metaclass(metaclass):\n",
- tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
- tab4, "def wrapper(cls):\n",
- tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
- tab4, "return wrapper\n\n", NIL);
+ Printv(f_shadow, "\n",
+ "def _swig_add_metaclass(metaclass):\n",
+ tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
+ tab4, "def wrapper(cls):\n",
+ tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
+ tab4, "return wrapper\n\n", NIL);
- Printv(f_shadow, "\n",
- "class _SwigNonDynamicMeta(type):\n",
- tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
- tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
- "\n", NIL);
+ Printv(f_shadow, "\n",
+ "class _SwigNonDynamicMeta(type):\n",
+ tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
+ tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
+ "\n", NIL);
- Printv(f_shadow, "\n", NIL);
+ Printv(f_shadow, "\n", NIL);
- if (directorsEnabled()) {
- Printv(f_shadow, "import weakref\n\n", NIL);
+ if (directorsEnabled())
+ Printv(f_shadow, "import weakref\n\n", NIL);
}
}
// Include some information in the code
From fe0af80933807ef7f6aed02981e601876850fd11 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 6 Apr 2022 23:49:59 +0100
Subject: [PATCH 406/662] Remove some unnecessary empty lines from generated
.py file
---
Source/Modules/python.cxx | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 5b7f535ce..c97bc4610 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -876,8 +876,10 @@ public:
Printv(f_shadow_py, default_import_code, NIL);
}
- Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
- Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
+ if (Len(f_shadow) > 0)
+ Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
+ if (Len(f_shadow_stubs) > 0)
+ Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
Delete(f_shadow_py);
}
@@ -2635,7 +2637,7 @@ public:
add_method(symname, wname, 0, p);
/* Create a shadow for this function (if enabled and not in a member function) */
- if (!builtin && shadow && (!(shadow & PYSHADOW_MEMBER)) && use_static_method) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0);
}
DelWrapper(f);
@@ -3309,9 +3311,10 @@ public:
add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments);
/* Create a shadow for this function (if enabled and not in a member function) */
- if (!builtin && shadow && (!(shadow & PYSHADOW_MEMBER)) && use_static_method) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs);
}
+
} else {
if (!Getattr(n, "sym:nextSibling")) {
dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class, use_static_method);
@@ -3470,7 +3473,7 @@ public:
if (builtin)
Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name);
have_globals = 1;
- if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name);
}
}
@@ -3628,7 +3631,7 @@ public:
if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
Replaceall(tm, "$value", value);
- if (needs_swigconstant(n) && !builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER)) && (!in_class || !Getattr(n, "feature:python:callback"))) {
+ if (needs_swigconstant(n) && !builtin && shadow && !(shadow & PYSHADOW_MEMBER) && (!in_class || !Getattr(n, "feature:python:callback"))) {
// Generate `*_swigconstant()` method which registers the new constant.
//
// *_swigconstant methods are required for constants of class type.
@@ -3666,7 +3669,7 @@ public:
return SWIG_NOWRAP;
}
- if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
String *f_s;
if (!in_class) {
f_s = f_shadow;
@@ -4617,7 +4620,8 @@ public:
}
shadow_indent = 0;
- Printf(f_shadow_file, "%s\n", f_shadow_stubs);
+ if (Len(f_shadow_stubs) > 0)
+ Printf(f_shadow_file, "%s\n", f_shadow_stubs);
Clear(f_shadow_stubs);
}
From 779d5cf57ade9de944d8feece9f5101668e2245f Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Wed, 6 Apr 2022 09:57:54 +1200
Subject: [PATCH 407/662] Remove bogus parser grammar rule for unary &&
This appears to have been accidentally added in
d8cc75946b236f08f9561a82867997e1021f96ab as part of the changes to
support C++11 rvalue references, presumably to match the existing
correct rule for unary &.
There is a non-standard GCC extension for taking the address of a label
using unary &&:
https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
However this extension only works in an expression in a function body,
and SWIG doesn't parse the contents of function bodies so this grammar
rule isn't even providing any useful support for this extension.
---
Source/CParse/parser.y | 4 ----
1 file changed, 4 deletions(-)
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index b6ded8381..9ecb65ba1 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -6743,10 +6743,6 @@ valexpr : exprsimple { $$ = $1; }
$$ = $2;
$$.val = NewStringf("&%s",$2.val);
}
- | LAND expr {
- $$ = $2;
- $$.val = NewStringf("&&%s",$2.val);
- }
| STAR expr {
$$ = $2;
$$.val = NewStringf("*%s",$2.val);
From 1aeaa2a64424e5ffa3797063e23591854a7a5399 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 7 Apr 2022 12:05:54 +1200
Subject: [PATCH 408/662] Recognise and ignore Doxygen group commands @{ and @}
Fixes #1750
---
CHANGES.current | 3 +++
Examples/test-suite/doxygen_parsing.i | 9 +++++++++
.../test-suite/java/doxygen_parsing_runme.java | 8 ++++++++
Source/Doxygen/doxycommands.h | 2 ++
Source/Doxygen/doxyparser.h | 2 +-
Source/Modules/python.cxx | 14 ++++++++++----
6 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index b406611dc..d41a4c235 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-04-07: olly
+ #1750 SWIG now recognises and ignores Doxygen group commands `@{` and `@}`.
+
2022-04-06: wsfulton
./configure now enables C++11 and later C++ standards testing by default (when
running: 'make check').
diff --git a/Examples/test-suite/doxygen_parsing.i b/Examples/test-suite/doxygen_parsing.i
index 3a559053d..9df0097ec 100644
--- a/Examples/test-suite/doxygen_parsing.i
+++ b/Examples/test-suite/doxygen_parsing.i
@@ -133,6 +133,15 @@ struct SomeAnotherStruct
}
};
+struct Foo1750
+{
+ /// @name Group name
+ /// @{
+ int a;
+ /// @}
+ int b;
+};
+
#ifdef SWIGPYTHON_BUILTIN
bool is_python_builtin() { return true; }
#else
diff --git a/Examples/test-suite/java/doxygen_parsing_runme.java b/Examples/test-suite/java/doxygen_parsing_runme.java
index 29e524f78..2c76001db 100644
--- a/Examples/test-suite/java/doxygen_parsing_runme.java
+++ b/Examples/test-suite/java/doxygen_parsing_runme.java
@@ -132,6 +132,14 @@ public class doxygen_parsing_runme {
wantedComments.put("doxygen_parsing.doxygen_parsingConstants.CONSTANT_VALUE",
"The constant comment \n" +
"");
+ wantedComments.put("doxygen_parsing.Foo1750.getA()",
+ "");
+ wantedComments.put("doxygen_parsing.Foo1750.getB()",
+ "");
+ wantedComments.put("doxygen_parsing.Foo1750.setA(int)",
+ "");
+ wantedComments.put("doxygen_parsing.Foo1750.setB(int)",
+ "");
// and ask the parser to check comments for us
System.exit(CommentParser.check(wantedComments));
diff --git a/Source/Doxygen/doxycommands.h b/Source/Doxygen/doxycommands.h
index b5d65af65..939b56917 100644
--- a/Source/Doxygen/doxycommands.h
+++ b/Source/Doxygen/doxycommands.h
@@ -44,6 +44,8 @@ const int sectionIndicatorsSize = sizeof(sectionIndicators) / sizeof(*sectionInd
const char *simpleCommands[] = {
// the first line are escaped chars, except \~, which is a language ID command.
"n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::",
+ // Member groups, which we currently ignore.
+ "{", "}",
"endcond",
"callgraph", "callergraph", "showinitializer", "hideinitializer", "internal",
"nosubgrouping", "public", "publicsection", "private", "privatesection",
diff --git a/Source/Doxygen/doxyparser.h b/Source/Doxygen/doxyparser.h
index e692729ce..7a7d5c4f2 100644
--- a/Source/Doxygen/doxyparser.h
+++ b/Source/Doxygen/doxyparser.h
@@ -238,7 +238,7 @@ private:
* Method for Adding a Simple Command
* Format: @command
* Plain commands, such as newline etc, they contain no other data
- * \n \\ \@ \& \$ \# \< \> \%
+ * \n \\ \@ \& \$ \# \< \> \% \{ \}
*/
void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList);
/*
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index c97bc4610..cd87984dc 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -5053,8 +5053,11 @@ public:
Printv(f_shadow, tab4, symname, variable_annotation, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
- if (have_docstring(n))
- Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
+ if (have_docstring(n)) {
+ String *s = docstring(n, AUTODOC_VAR, tab4);
+ if (Len(s))
+ Printv(f_shadow, ", doc=", s, NIL);
+ }
Printv(f_shadow, ")\n", NIL);
Delete(variable_annotation);
Delete(mname);
@@ -5121,8 +5124,11 @@ public:
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
- if (have_docstring(n))
- Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
+ if (have_docstring(n)) {
+ String *s = docstring(n, AUTODOC_VAR, tab4);
+ if (Len(s))
+ Printv(f_shadow, ", doc=", s, NIL);
+ }
Printv(f_shadow, ")\n", NIL);
}
String *getter = Getattr(n, "pybuiltin:getter");
From c8bec185541a5839a2a1728d3d83a180d4cd93ad Mon Sep 17 00:00:00 2001
From: luz paz
Date: Sun, 10 Apr 2022 11:49:43 -0400
Subject: [PATCH 409/662] Fix various typos
Found via `codespell -q 3 -L ans,anumber,ba,bae,chello,clos,cmo,coo,dout,fo,funktion,goin,inout,methid,nd,nin,nnumber,object,objekt,od,ois,packag,parm,parms,pres,statics,strack,struc,tempdate,te,thru,uint,upto,writen`
---
Examples/python/import_packages/from_init1/runme.py | 2 +-
Examples/python/import_packages/from_init2/runme.py | 2 +-
Examples/python/import_packages/from_init3/runme.py | 2 +-
Examples/python/import_packages/namespace_pkg/nonpkg.py | 2 +-
Examples/python/import_packages/namespace_pkg/normal.py | 2 +-
Examples/python/import_packages/namespace_pkg/nstest.py | 2 +-
Examples/python/import_packages/namespace_pkg/split.py | 2 +-
Examples/python/import_packages/namespace_pkg/zipsplit.py | 2 +-
Examples/python/import_packages/relativeimport1/runme.py | 2 +-
Examples/python/import_packages/relativeimport2/runme.py | 2 +-
Examples/python/import_packages/relativeimport3/runme.py | 2 +-
Examples/python/import_packages/same_modnames1/runme.py | 2 +-
Examples/python/import_packages/same_modnames2/runme.py | 2 +-
Examples/python/import_packages/split_modules/vanilla/runme.py | 2 +-
.../python/import_packages/split_modules/vanilla_split/runme.py | 2 +-
Examples/ruby/exceptproxy/example.i | 2 +-
Examples/test-suite/php/director_extend_runme.php | 2 +-
Source/CParse/parser.y | 2 +-
Source/Modules/r.cxx | 2 +-
19 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/Examples/python/import_packages/from_init1/runme.py b/Examples/python/import_packages/from_init1/runme.py
index c76716f16..1ed8898e4 100644
--- a/Examples/python/import_packages/from_init1/runme.py
+++ b/Examples/python/import_packages/from_init1/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/from_init2/runme.py b/Examples/python/import_packages/from_init2/runme.py
index c9c46a4da..100c97b9e 100644
--- a/Examples/python/import_packages/from_init2/runme.py
+++ b/Examples/python/import_packages/from_init2/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/from_init3/runme.py b/Examples/python/import_packages/from_init3/runme.py
index c9c46a4da..100c97b9e 100644
--- a/Examples/python/import_packages/from_init3/runme.py
+++ b/Examples/python/import_packages/from_init3/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/namespace_pkg/nonpkg.py b/Examples/python/import_packages/namespace_pkg/nonpkg.py
index 52be74db4..e87289089 100644
--- a/Examples/python/import_packages/namespace_pkg/nonpkg.py
+++ b/Examples/python/import_packages/namespace_pkg/nonpkg.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/normal.py b/Examples/python/import_packages/namespace_pkg/normal.py
index 0eb8f517c..f8fb025ad 100644
--- a/Examples/python/import_packages/namespace_pkg/normal.py
+++ b/Examples/python/import_packages/namespace_pkg/normal.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/nstest.py b/Examples/python/import_packages/namespace_pkg/nstest.py
index 4d618a6ad..0cd2a997d 100644
--- a/Examples/python/import_packages/namespace_pkg/nstest.py
+++ b/Examples/python/import_packages/namespace_pkg/nstest.py
@@ -6,7 +6,7 @@ import zipfile
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/split.py b/Examples/python/import_packages/namespace_pkg/split.py
index 9d786dc07..ed259b618 100644
--- a/Examples/python/import_packages/namespace_pkg/split.py
+++ b/Examples/python/import_packages/namespace_pkg/split.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/namespace_pkg/zipsplit.py b/Examples/python/import_packages/namespace_pkg/zipsplit.py
index 30434f9c0..474f2c742 100644
--- a/Examples/python/import_packages/namespace_pkg/zipsplit.py
+++ b/Examples/python/import_packages/namespace_pkg/zipsplit.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print(" Finished running: " + commandline)
diff --git a/Examples/python/import_packages/relativeimport1/runme.py b/Examples/python/import_packages/relativeimport1/runme.py
index 3073cb5a7..ff8ca0427 100644
--- a/Examples/python/import_packages/relativeimport1/runme.py
+++ b/Examples/python/import_packages/relativeimport1/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/relativeimport2/runme.py b/Examples/python/import_packages/relativeimport2/runme.py
index 9ab8d9471..35c57e10b 100644
--- a/Examples/python/import_packages/relativeimport2/runme.py
+++ b/Examples/python/import_packages/relativeimport2/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/relativeimport3/runme.py b/Examples/python/import_packages/relativeimport3/runme.py
index 3073cb5a7..ff8ca0427 100644
--- a/Examples/python/import_packages/relativeimport3/runme.py
+++ b/Examples/python/import_packages/relativeimport3/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/same_modnames1/runme.py b/Examples/python/import_packages/same_modnames1/runme.py
index 05846ed9d..41d84aa3d 100644
--- a/Examples/python/import_packages/same_modnames1/runme.py
+++ b/Examples/python/import_packages/same_modnames1/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/same_modnames2/runme.py b/Examples/python/import_packages/same_modnames2/runme.py
index 190dadc77..48c209b86 100644
--- a/Examples/python/import_packages/same_modnames2/runme.py
+++ b/Examples/python/import_packages/same_modnames2/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/split_modules/vanilla/runme.py b/Examples/python/import_packages/split_modules/vanilla/runme.py
index 0f7b8806b..723eb3aaa 100644
--- a/Examples/python/import_packages/split_modules/vanilla/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/python/import_packages/split_modules/vanilla_split/runme.py b/Examples/python/import_packages/split_modules/vanilla_split/runme.py
index 0f7b8806b..723eb3aaa 100644
--- a/Examples/python/import_packages/split_modules/vanilla_split/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla_split/runme.py
@@ -4,7 +4,7 @@ import sys
def run_except_on_windows(commandline, env=None):
if os.name != "nt" and sys.platform != "cygwin":
- # Strange failures on windows/cygin/mingw
+ # Strange failures on windows/cygwin/mingw
subprocess.check_call(commandline, env=env, shell=True)
print((" Finished running: " + commandline))
diff --git a/Examples/ruby/exceptproxy/example.i b/Examples/ruby/exceptproxy/example.i
index ad0c23acb..3a3077f8a 100644
--- a/Examples/ruby/exceptproxy/example.i
+++ b/Examples/ruby/exceptproxy/example.i
@@ -16,7 +16,7 @@
/* The EmptyError doesn't appear in a throw declaration, and hence
we need to tell SWIG that the dequeue method throws it. This can
- now be done via the %catchs feature. */
+ now be done via the %catches feature. */
%catches(FullError) *::enqueue;
%catches(EmptyError) *::dequeue();
diff --git a/Examples/test-suite/php/director_extend_runme.php b/Examples/test-suite/php/director_extend_runme.php
index 418985476..3c6dd6b1d 100644
--- a/Examples/test-suite/php/director_extend_runme.php
+++ b/Examples/test-suite/php/director_extend_runme.php
@@ -17,6 +17,6 @@ class MyObject extends SpObject{
$m = new MyObject();
check::equal($m->dummy(), 666, "1st call");
-check::equal($m->dummy(), 666, "2st call"); // Locked system
+check::equal($m->dummy(), 666, "2nd call"); // Locked system
check::done();
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 9ecb65ba1..1ae3a59db 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -25,7 +25,7 @@
%{
#define yylex yylex
-/* doh.h uses #pragma GCC posion with GCC to prevent direct calls to certain
+/* doh.h uses #pragma GCC poison with GCC to prevent direct calls to certain
* standard C library functions being introduced, but those cause errors due
* to checks like `#if defined YYMALLOC || defined malloc` in the bison
* template code. We can't easily arrange to include headers after that
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index 541e7e622..536ee1243 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -940,7 +940,7 @@ int R::OutputClassMethodsTable(File *) {
* The entries are indexed by _set and
* _get. Each entry is a List *.
- * out - the stram where the code is to be written. This is the S
+ * out - the stream where the code is to be written. This is the S
* code stream as we generate only S code here.
* --------------------------------------------------------------*/
From 962f0900018ecb10287b327d261e424fa5ccb755 Mon Sep 17 00:00:00 2001
From: Robin Stocker
Date: Mon, 11 Apr 2022 11:44:39 +1000
Subject: [PATCH 410/662] Fix Ruby 3.2 warning "undefining the allocator of
T_DATA class swig_runtime_data"
Ruby 3.2 (still in development) started warning about this, see
https://bugs.ruby-lang.org/issues/18007.
Note that the extension docs mention it in
https://ruby-doc.org/core-3.1.1/doc/extension_rdoc.html#label-C+struct+to+Ruby+object:
> The klass argument is the class for the object. The klass should
> derive from `rb_cObject`, and the allocator must be set by calling
> `rb_define_alloc_func` or `rb_undef_alloc_func`.
So in this case we call `rb_undef_alloc_func` to fix the warning.
Verified that this works in robinst/taglib-ruby#115.
Fixes #2257.
---
Lib/ruby/rubyrun.swg | 1 +
1 file changed, 1 insertion(+)
diff --git a/Lib/ruby/rubyrun.swg b/Lib/ruby/rubyrun.swg
index 7c94c4e12..e4c23bde5 100644
--- a/Lib/ruby/rubyrun.swg
+++ b/Lib/ruby/rubyrun.swg
@@ -413,6 +413,7 @@ SWIG_Ruby_SetModule(swig_module_info *pointer)
{
/* register a new class */
VALUE cl = rb_define_class("swig_runtime_data", rb_cObject);
+ rb_undef_alloc_func(cl);
/* create and store the structure pointer to a global variable */
swig_runtime_data_type_pointer = Data_Wrap_Struct(cl, 0, 0, pointer);
rb_define_readonly_variable("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, &swig_runtime_data_type_pointer);
From 822e51009ee03dcf3720112c68d98368bcf13200 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Tue, 12 Apr 2022 08:35:11 +1200
Subject: [PATCH 411/662] Add CHANGES entry for #2257/#2258
---
CHANGES.current | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGES.current b/CHANGES.current
index d41a4c235..234e730c3 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-04-11: robinst
+ #2257 Fix new Ruby 3.2 warning "undefining the allocator of T_DATA
+ class swig_runtime_data".
+
2022-04-07: olly
#1750 SWIG now recognises and ignores Doxygen group commands `@{` and `@}`.
From 6043554c38edc30cbe27ba632462f55fb702bb87 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Wed, 13 Apr 2022 11:14:29 +1200
Subject: [PATCH 412/662] configure.ac: Add missing shell quoting
Fixes "./configure[4896]: test: argument expected" on stderr.
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 3ea50e9c1..0d86e9ca9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,7 +59,7 @@ dnl To make configuring easier, check for a locally built PCRE using the Tools/p
if test x"${with_pcre}" = xyes ; then
AC_MSG_CHECKING([whether to use local PCRE2])
local_pcre_config=no
- if test -z $PCRE2_CONFIG; then
+ if test -z "$PCRE2_CONFIG"; then
if test -f `pwd`/pcre/pcre-swig-install/bin/pcre2-config; then
PCRE2_CONFIG=`pwd`/pcre/pcre-swig-install/bin/pcre2-config
local_pcre_config=$PCRE2_CONFIG
From fb4c69b4b02c1b3fac28624c16e684ae77de91fc Mon Sep 17 00:00:00 2001
From: Corey Minyard
Date: Fri, 18 Mar 2022 21:40:11 -0500
Subject: [PATCH 413/662] [Go] Add missing newlines for goin typemaps
In some cases the \n was missing from goin directives in some places.
Without this change, you will get
} swig_r = (int)(C....
in the output in some cases, and that won't compile in Go, it will
error with:
../gensio/gensio.go:1508:3: expected ';', found swig_r
It only did this on director callbacks with godirectorin, and only if
the virtual function wasn't assigned to zero. So the following will
fail:
class callbacks {
public:
virtual bool call1(int v, const char * const *strarray);
virtual ~callbacks() = default;
};
but the following won't:
class callbacks {
public:
virtual bool call1(int v, const char * const *strarray) = 0;
virtual ~callbacks() = default;
};
Add "\n" to the proper places to fix this.
---
Source/Modules/go.cxx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx
index 071d39ec7..d828b00aa 100644
--- a/Source/Modules/go.cxx
+++ b/Source/Modules/go.cxx
@@ -3518,7 +3518,7 @@ private:
goin = Copy(goin);
Replaceall(goin, "$input", ln);
Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, NULL);
+ Printv(f_go_wrappers, goin, "\n", NULL);
Delete(goin);
}
@@ -3772,7 +3772,7 @@ private:
goin = Copy(goin);
Replaceall(goin, "$input", ln);
Replaceall(goin, "$result", ivar);
- Printv(f_go_wrappers, goin, NULL);
+ Printv(f_go_wrappers, goin, "\n", NULL);
Delete(goin);
}
From 546763ffbc333b98808802fff0d601d018763d0c Mon Sep 17 00:00:00 2001
From: Corey Minyard
Date: Sun, 20 Mar 2022 15:04:27 -0500
Subject: [PATCH 414/662] [Go] Add an example for goin and godirectorin
Shows how to use a go directory for passing an NULL terminated argv type
array.
This also exercises the bug in the previous commit. That's why the
call1 function isn't assigned to zero, that the only case where that bug
happens.
Signed-off-by: Corey Minyard
---
Examples/go/check.list | 1 +
Examples/go/goin/Makefile | 18 ++++++
Examples/go/goin/example.i | 106 ++++++++++++++++++++++++++++++++++++
Examples/go/goin/index.html | 26 +++++++++
Examples/go/goin/runme.go | 38 +++++++++++++
Examples/go/index.html | 1 +
6 files changed, 190 insertions(+)
create mode 100644 Examples/go/goin/Makefile
create mode 100644 Examples/go/goin/example.i
create mode 100644 Examples/go/goin/index.html
create mode 100644 Examples/go/goin/runme.go
diff --git a/Examples/go/check.list b/Examples/go/check.list
index b3f34b306..6046c8310 100644
--- a/Examples/go/check.list
+++ b/Examples/go/check.list
@@ -12,3 +12,4 @@ reference
simple
template
variables
+goin
diff --git a/Examples/go/goin/Makefile b/Examples/go/goin/Makefile
new file mode 100644
index 000000000..f79b083cb
--- /dev/null
+++ b/Examples/go/goin/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIGEXE = $(TOP)/../swig
+SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
+CXXSRCS =
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+check: build
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
+
+build:
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean:
+ $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
diff --git a/Examples/go/goin/example.i b/Examples/go/goin/example.i
new file mode 100644
index 000000000..1d8289af8
--- /dev/null
+++ b/Examples/go/goin/example.i
@@ -0,0 +1,106 @@
+
+%module(directors="1") example
+
+%inline %{
+// Helper functions for converting string arrays
+#include
+void *alloc_ptr_array(unsigned int len)
+{
+ return calloc(len, sizeof(void *));
+}
+void set_ptr_array(void *ain, unsigned int pos, void *val)
+{
+ void **a = (void **) ain;
+ a[pos] = val;
+}
+void *get_ptr_array(void *ain, unsigned int pos)
+{
+ void **a = (void **) ain;
+ return a[pos];
+}
+void free_ptr_array(void *ain)
+{
+ void **a = (void **) ain;
+ unsigned int i;
+
+ if (!a)
+ return;
+ for (i = 0; a[i]; i++) {
+ free(a[i]);
+ }
+ free(a);
+}
+char *uintptr_to_string(void *in)
+{
+ return (char *) in;
+}
+void *string_to_uintptr(char *in)
+{
+ return strdup(in);
+}
+%}
+
+// These typemaps convert between an array of strings in Go and a
+// const char** that is NULL terminated in C++.
+%typemap(gotype) (const char * const *) "[]string";
+%typemap(imtype) (const char * const *) "uintptr";
+%typemap(goin) (const char * const *) {
+ if $input == nil || len($input) == 0 {
+ $result = 0
+ } else {
+ $result = Alloc_ptr_array(uint(len($input) + 1))
+ defer func() {
+ Free_ptr_array($result)
+ }()
+ var i uint
+ for i = 0; i < uint(len($input)); i++ {
+ Set_ptr_array($result, i, String_to_uintptr($input[i]))
+ }
+ }
+}
+%typemap(in) (const char * const *) {
+ $1 = (char **) $input;
+}
+%typemap(godirectorin) (const char * const *) {
+ if ($input == 0) {
+ $result = nil
+ } else {
+ var i uint
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ }
+ if i == 0 {
+ $result = nil
+ } else {
+ $result = make([]string, i)
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ $result[i] = Uintptr_to_string(v)
+ }
+ }
+ }
+}
+
+%feature("director") callbacks;
+
+%inline %{
+ class callbacks {
+ public:
+ virtual bool call1(int v, const char * const *strarray);
+ virtual ~callbacks() {}
+ };
+
+ bool check1(callbacks *c, int v, const char * const *strarray) {
+ return c->call1(v, strarray);
+ }
+
+ bool callbacks::call1(int v, const char * const *strarray) {
+ return false;
+ }
+%}
diff --git a/Examples/go/goin/index.html b/Examples/go/goin/index.html
new file mode 100644
index 000000000..852b068da
--- /dev/null
+++ b/Examples/go/goin/index.html
@@ -0,0 +1,26 @@
+
+
+SWIG:Examples:go:going
+
+
+
+
+
+SWIG/Examples/go/goin/
+
+
+Example of using goin and godirectorin
+
+
+This example converts between a Go []string and a "const char * const *"
+in C/C++. It does this for a director and for a normal call.
+
+
+
+
+
+
+
diff --git a/Examples/go/goin/runme.go b/Examples/go/goin/runme.go
new file mode 100644
index 000000000..dfc7b0936
--- /dev/null
+++ b/Examples/go/goin/runme.go
@@ -0,0 +1,38 @@
+package main
+
+import (
+ "fmt"
+ "swigtests/example"
+)
+
+type mycallbacks struct {
+ example.Callbacks
+}
+
+var tststrs = []string{ "A", "BCD", "EFGH" }
+var tstint int = 5
+
+func (v *mycallbacks) Call1(val int, strarray []string) bool {
+ var rv bool = true
+
+ for i, s := range strarray {
+ fmt.Printf("%d: %s\n", i, s)
+ if s != tststrs[i] {
+ fmt.Printf(" ***Mismatch, expected %s\n", tststrs[i])
+ rv = false
+ }
+ }
+ if val != tstint {
+ rv = false
+ }
+ return rv
+}
+
+func main() {
+ cbs := &mycallbacks{}
+ cbs.Callbacks = example.NewDirectorCallbacks(cbs)
+ worked := example.Check1(cbs, tstint, tststrs)
+ if !worked {
+ panic("Data mismatch")
+ }
+}
diff --git a/Examples/go/index.html b/Examples/go/index.html
index 467f4ecb7..370424c54 100644
--- a/Examples/go/index.html
+++ b/Examples/go/index.html
@@ -24,6 +24,7 @@ certain C declarations are turned into constants.
- callback. C++ callbacks using directors.
- extend. Polymorphism using directors.
- director. Example how to utilize the director feature.
+
- director. Example how to use goin and godirectorin.
Compilation Issues
From 3cc67d42f39b816e04d4d31fa624923c094a6ff0 Mon Sep 17 00:00:00 2001
From: Corey Minyard
Date: Mon, 18 Apr 2022 19:53:59 -0500
Subject: [PATCH 415/662] [Go] Add a test for godirectorin with const char **
This exercises a bug that was found with this fairly complex mapping, it
wasn't putting newlines in the proper place. A previous commit added
the newlines, this makes sure it doesn't happen again.
Signed-off-by: Corey Minyard
---
.../test-suite/go/go_director_inout_runme.go | 11 ++
Examples/test-suite/go_director_inout.i | 102 +++++++++++++++++-
2 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/Examples/test-suite/go/go_director_inout_runme.go b/Examples/test-suite/go/go_director_inout_runme.go
index f2be9d30b..55f32dfc3 100644
--- a/Examples/test-suite/go/go_director_inout_runme.go
+++ b/Examples/test-suite/go/go_director_inout_runme.go
@@ -34,6 +34,15 @@ func (p *GoMyClass) S3(s *string) {
*s = "R3"
}
+func (p *GoMyClass) S4(s []string) {
+ if s[0] != "T1" {
+ panic(s)
+ }
+ if s[1] != "T2" {
+ panic(s)
+ }
+}
+
func main() {
a := wrap.NewDirectorMyClass(&GoMyClass{})
m := map[string]interface{}{
@@ -56,6 +65,8 @@ func main() {
panic(str)
}
+ a.CallS4([]string{ "T1", "T2" })
+
a = wrap.NewDirectorMyClass(nil)
s = a.Adjust(m)
if s.Str != `{"first":"second"}` {
diff --git a/Examples/test-suite/go_director_inout.i b/Examples/test-suite/go_director_inout.i
index 38059ea40..b12e5da52 100644
--- a/Examples/test-suite/go_director_inout.i
+++ b/Examples/test-suite/go_director_inout.i
@@ -120,6 +120,92 @@ type GoRetStruct struct {
$1.assign(tmp->p, tmp->p + tmp->n);
}
+%inline %{
+// Helper functions for converting string arrays
+#include
+void *alloc_ptr_array(unsigned int len)
+{
+ return calloc(len, sizeof(void *));
+}
+void set_ptr_array(void *ain, unsigned int pos, void *val)
+{
+ void **a = (void **) ain;
+ a[pos] = val;
+}
+void *get_ptr_array(void *ain, unsigned int pos)
+{
+ void **a = (void **) ain;
+ return a[pos];
+}
+void free_ptr_array(void *ain)
+{
+ void **a = (void **) ain;
+ unsigned int i;
+
+ if (!a)
+ return;
+ for (i = 0; a[i]; i++) {
+ free(a[i]);
+ }
+ free(a);
+}
+char *uintptr_to_string(void *in)
+{
+ return (char *) in;
+}
+void *string_to_uintptr(char *in)
+{
+ return strdup(in);
+}
+%}
+
+// These typemaps convert between an array of strings in Go and a
+// const char** that is NULL terminated in C++.
+%typemap(gotype) (const char * const *) "[]string";
+%typemap(imtype) (const char * const *) "uintptr";
+%typemap(goin) (const char * const *) {
+ if $input == nil || len($input) == 0 {
+ $result = 0
+ } else {
+ $result = Alloc_ptr_array(uint(len($input) + 1))
+ defer func() {
+ Free_ptr_array($result)
+ }()
+ var i uint
+ for i = 0; i < uint(len($input)); i++ {
+ Set_ptr_array($result, i, String_to_uintptr($input[i]))
+ }
+ }
+}
+%typemap(in) (const char * const *) {
+ $1 = (char **) $input;
+}
+%typemap(godirectorin) (const char * const *) {
+ if ($input == 0) {
+ $result = nil
+ } else {
+ var i uint
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ }
+ if i == 0 {
+ $result = nil
+ } else {
+ $result = make([]string, i)
+ for i = 0; ; i++ {
+ var v uintptr = Get_ptr_array($input, i)
+ if v == 0 {
+ break
+ }
+ $result[i] = Uintptr_to_string(v)
+ }
+ }
+ }
+}
+
%feature("director") MyClass;
%inline
@@ -134,9 +220,23 @@ class MyClass {
return r;
}
- virtual void S1(std::string s) = 0;
+ void CallS4(const char * const *strarray);
+ virtual void S1(std::string s);
virtual void S2(std::string& s) = 0;
virtual void S3(std::string* s) = 0;
+ virtual void S4(const char * const *strarray);
};
+void MyClass::S1(std::string s) {
+ throw "Base S1 called!";
+}
+
+void MyClass::S4(const char * const *strarray) {
+ throw "Base S4 called!";
+}
+
+void MyClass::CallS4(const char * const *strarray) {
+ this->S4(strarray);
+}
+
%}
From 537669ba3dc97e0e6033160c9a736b63d0f9427f Mon Sep 17 00:00:00 2001
From: Corey Minyard
Date: Wed, 20 Apr 2022 17:54:15 -0500
Subject: [PATCH 416/662] CHANGES.current: Add an entry for the godirectorin
bug
Document what was fixed in the previous few changes.
Signed-off-by: Corey Minyard
---
CHANGES.current | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/CHANGES.current b/CHANGES.current
index 234e730c3..0c6db7c90 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,17 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-04-20: cminyard
+ Fix an issue where newlines were not properly generated
+ for godirectorin typemaps. If you have a virtual function
+ not assigned to zero, in some cases it won't generate a
+ newline and you will see errors:
+ example.go:1508:3: expected ';', found swig_r
+ when compiling the go code.
+
+ Also add an example of using goin and godirectorin and add
+ a test for this situation.
+
2022-04-11: robinst
#2257 Fix new Ruby 3.2 warning "undefining the allocator of T_DATA
class swig_runtime_data".
From f5934b099b6db3e5bde9f2745a7e58d4768b8e88 Mon Sep 17 00:00:00 2001
From: Kris Thielemans
Date: Thu, 21 Apr 2022 12:28:54 +0100
Subject: [PATCH 417/662] [Python] Replace tp_print with tp_vectorcall_offset
slot for Python 3.8
The tp_print slot is no longer supported and replaced with tp_vectorcall_offset.
The (printfunc) cast that we used caused problems on PyPy.
Fixes #2262
---
Lib/python/builtin.swg | 12 ++++++++++--
Lib/python/pyrun.swg | 18 +++++++++++++++---
Source/Modules/python.cxx | 4 ++++
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg
index ec092233d..5da8d6ae3 100644
--- a/Lib/python/builtin.swg
+++ b/Lib/python/builtin.swg
@@ -211,7 +211,11 @@ SwigPyStaticVar_Type(void) {
sizeof(PyGetSetDescrObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */
- 0, /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+ (printfunc)0, /*tp_print*/
+#else
+ (Py_ssize_t)0, /*tp_vectorcall_offset*/
+#endif
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
@@ -295,7 +299,11 @@ SwigPyObjectType(void) {
PyType_Type.tp_basicsize, /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
- 0, /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+ (printfunc)0, /*tp_print*/
+#else
+ (Py_ssize_t)0, /*tp_vectorcall_offset*/
+#endif
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg
index 081bb2cde..935885934 100644
--- a/Lib/python/pyrun.swg
+++ b/Lib/python/pyrun.swg
@@ -348,7 +348,11 @@ swig_varlink_type(void) {
sizeof(swig_varlinkobject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor) swig_varlink_dealloc, /* tp_dealloc */
- 0, /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+ (printfunc)0, /*tp_print*/
+#else
+ (Py_ssize_t)0, /*tp_vectorcall_offset*/
+#endif
(getattrfunc) swig_varlink_getattr, /* tp_getattr */
(setattrfunc) swig_varlink_setattr, /* tp_setattr */
0, /* tp_compare */
@@ -914,7 +918,11 @@ SwigPyObject_TypeOnce(void) {
sizeof(SwigPyObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)SwigPyObject_dealloc, /* tp_dealloc */
- 0, /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+ (printfunc)0, /*tp_print*/
+#else
+ (Py_ssize_t)0, /*tp_vectorcall_offset*/
+#endif
(getattrfunc)0, /* tp_getattr */
(setattrfunc)0, /* tp_setattr */
#if PY_VERSION_HEX >= 0x03000000
@@ -1090,7 +1098,11 @@ SwigPyPacked_TypeOnce(void) {
sizeof(SwigPyPacked), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)SwigPyPacked_dealloc, /* tp_dealloc */
- 0, /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+ (printfunc)0, /*tp_print*/
+#else
+ (Py_ssize_t)0, /*tp_vectorcall_offset*/
+#endif
(getattrfunc)0, /* tp_getattr */
(setattrfunc)0, /* tp_setattr */
#if PY_VERSION_HEX>=0x03000000
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index cd87984dc..7161c8e7d 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -4145,7 +4145,11 @@ public:
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");
+ Printv(f, "#if PY_VERSION_HEX < 0x030800b4\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc");
+ Printv(f, "#else\n", NIL);
+ printSlot(f, getSlot(n, "feature:python:tp_vectorcall_offset"), "tp_vectorcall_offset", "Py_ssize_t");
+ Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc");
printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc");
Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
From 8dc4e3a8cb063778255b03e02c246c8c641f6a43 Mon Sep 17 00:00:00 2001
From: Kris Thielemans
Date: Thu, 28 Apr 2022 08:00:42 +0100
Subject: [PATCH 418/662] fix white-space
---
Lib/python/builtin.swg | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg
index 5da8d6ae3..9dccd7e20 100644
--- a/Lib/python/builtin.swg
+++ b/Lib/python/builtin.swg
@@ -212,9 +212,9 @@ SwigPyStaticVar_Type(void) {
0, /* tp_itemsize */
(destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */
#if PY_VERSION_HEX < 0x030800b4
- (printfunc)0, /*tp_print*/
+ (printfunc)0, /* tp_print */
#else
- (Py_ssize_t)0, /*tp_vectorcall_offset*/
+ (Py_ssize_t)0, /* tp_vectorcall_offset */
#endif
0, /* tp_getattr */
0, /* tp_setattr */
@@ -300,9 +300,9 @@ SwigPyObjectType(void) {
0, /* tp_itemsize */
0, /* tp_dealloc */
#if PY_VERSION_HEX < 0x030800b4
- (printfunc)0, /*tp_print*/
+ (printfunc)0, /* tp_print */
#else
- (Py_ssize_t)0, /*tp_vectorcall_offset*/
+ (Py_ssize_t)0, /* tp_vectorcall_offset */
#endif
0, /* tp_getattr */
0, /* tp_setattr */
From ed42422d1c80deae1a6971cbb722f41123a4120d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 29 Apr 2022 18:13:21 +0100
Subject: [PATCH 419/662] Add support for wchar_t * and std::wstring Unicode
strings on Linux
Initial contributions for Linux provided in issue #1233, modified to work
on both Windows and Linux. Dual support is possible by detecting
the sizeof wchar_t which is different on each of these systems.
---
CHANGES.current | 3 +
.../test-suite/csharp/li_std_wstring_runme.cs | 70 +++++--
Examples/test-suite/li_std_wstring.h | 5 +
Examples/test-suite/li_std_wstring.i | 65 +++++-
Lib/csharp/std_wstring.i | 40 +++-
Lib/csharp/wchar.i | 188 ++++++++++++++++--
Lib/swigwarnings.swg | 1 +
Source/Include/swigwarn.h | 1 +
8 files changed, 327 insertions(+), 46 deletions(-)
create mode 100644 Examples/test-suite/li_std_wstring.h
diff --git a/CHANGES.current b/CHANGES.current
index 0c6db7c90..cfa0af2db 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -18,6 +18,9 @@ Version 4.1.0 (in progress)
Also add an example of using goin and godirectorin and add
a test for this situation.
+2022-04-29: jason-daly, JerryJoyce, wsfulton
+ [C#] #1233 Add wchar_t * and std::wstring Unicode string support on Linux.
+
2022-04-11: robinst
#2257 Fix new Ruby 3.2 warning "undefining the allocator of T_DATA
class swig_runtime_data".
diff --git a/Examples/test-suite/csharp/li_std_wstring_runme.cs b/Examples/test-suite/csharp/li_std_wstring_runme.cs
index d2927287f..059688a75 100644
--- a/Examples/test-suite/csharp/li_std_wstring_runme.cs
+++ b/Examples/test-suite/csharp/li_std_wstring_runme.cs
@@ -1,3 +1,6 @@
+// This file has a BOM for UTF-8
+// Notes for displaying UTF-8 properly in Windows: https://stackoverflow.com/questions/49476326/displaying-unicode-in-powershell
+
using System;
using li_std_wstringNamespace;
@@ -5,17 +8,38 @@ public class runme
{
static private void check_equal(char a, char b)
{
- if (a != b)
- throw new Exception("char failed '" + a + "' != '" + b + "'");
+ if (a != b)
+ throw new Exception("char failed '" + a + "' != '" + b + "'");
+ }
+
+ static private void display_bytes(string s)
+ {
+ Console.Write("[");
+ if (s != null)
+ {
+ foreach (char x in s)
+ {
+ int n = Convert.ToInt32(x);
+ Console.Write(n.ToString("X") + " ");
+ }
+ }
+ else
+ Console.Write("null");
+ Console.WriteLine("]");
}
static private void check_equal(string a, string b)
{
- if (a != b)
- throw new Exception("string failed '" + a + "' != '" + b + "'");
+ if (li_std_wstring.debug) {
+ Console.WriteLine("check_equal {0} {1}", a, b);
+ display_bytes(a);
+ display_bytes(b);
+ }
+ if (a != b)
+ throw new Exception("string failed '" + a + "' != '" + b + "'");
}
- static void Main()
+ static void Main()
{
char h = 'h';
check_equal(li_std_wstring.test_wcvalue(h), h);
@@ -30,6 +54,8 @@ public class runme
li_std_wstring.test_pointer(null);
li_std_wstring.test_const_pointer(null);
+ check_equal(li_std_wstring.test_ccvalue(null), null);
+
try {
li_std_wstring.test_value(null);
throw new Exception("NULL check failed");
@@ -37,8 +63,8 @@ public class runme
}
try {
- li_std_wstring.test_reference(null);
- throw new Exception("NULL check failed");
+ li_std_wstring.test_reference(null);
+ throw new Exception("NULL check failed");
} catch (ArgumentNullException e) {
if (!e.Message.Contains("type is null"))
throw new Exception("Missing text " + e);
@@ -54,13 +80,24 @@ public class runme
x = "hello";
check_equal(li_std_wstring.test_const_reference(x), x);
- /* Postpone, tricky, std::wstring portability problem.
+ /* Tricky, std::wstring portability problem.
* std::wstring is 2 bytes on Windows, 4 bytes on Linux, LPWSTR is 2 bytes.
- * .NET marshalling should work on Windows but not Linux.
- string s = "abc";
- if (!li_std_wstring.test_equal_abc(s))
- throw new Exception("Not equal " + s);
- */
+ */
+ string ss = "abc";
+ if (!li_std_wstring.test_equal_abc(ss))
+ throw new Exception("Not equal " + ss);
+
+ ss = "JP: 日本語";
+ if (!li_std_wstring.test_equal_jp(ss))
+ throw new Exception("Not equal " + ss);
+
+ ss = "DE: Kröpeliner Straße";
+ if (!li_std_wstring.test_equal_de(ss))
+ throw new Exception("Not equal " + ss);
+
+ ss = "RU: Война и мир";
+ if (!li_std_wstring.test_equal_ru(ss))
+ throw new Exception("Not equal " + ss);
try {
li_std_wstring.test_throw();
@@ -81,15 +118,22 @@ public class runme
check_equal(s.wchar_t_member, h);
s.wchar_t_ptr_member = x;
check_equal(s.wchar_t_ptr_member, "abc");
+ s.wchar_t_ptr_member = ss;
+ check_equal(s.wchar_t_ptr_member, ss);
{
// Unicode strings
+ // Strings below are UTF8 in this file, but .NET holds them internally as UTF16
+ // DE: https://www.utf8-chartable.de/
+ // RU: https://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024
string[] test_strings = {
"JP: 日本語", "DE: Kröpeliner Straße" , "RU: Война и мир", "EN: War and Peace"
};
foreach (string expected in test_strings)
{
+ if (li_std_wstring.debug)
+ Console.WriteLine("expected (C#): " + expected);
string received = li_std_wstring.test_value(expected);
check_equal(received, expected);
}
diff --git a/Examples/test-suite/li_std_wstring.h b/Examples/test-suite/li_std_wstring.h
new file mode 100644
index 000000000..a16b7cd30
--- /dev/null
+++ b/Examples/test-suite/li_std_wstring.h
@@ -0,0 +1,5 @@
+// This file has a BOM set to UTF-8, which is one way for Visual C++ to correctly interpet these strings
+// Alternatively, the /utf-8 command line option could be used
+#define JP_WSTRING L"JP: 日本語"
+#define DE_WSTRING L"DE: Kröpeliner Straße"
+#define RU_WSTRING L"RU: Война и мир"
\ No newline at end of file
diff --git a/Examples/test-suite/li_std_wstring.i b/Examples/test-suite/li_std_wstring.i
index a790ca7e0..1f5ddb458 100644
--- a/Examples/test-suite/li_std_wstring.i
+++ b/Examples/test-suite/li_std_wstring.i
@@ -3,44 +3,71 @@
// The languages below are yet to provide std_wstring.i
#if !(defined(SWIGD) || defined(SWIGGO) || defined(SWIGGUILE) || defined(SWIGJAVASCRIPT) || defined(SWIGLUA) || defined(SWIGMZSCHEME) || defined(SWIGOCAML) || defined(SWIGOCTAVE) || defined(SWIGPERL) || defined(SWIGPHP) || defined(SWIGR) || defined(SWIGSCILAB))
+%warnfilter(SWIGWARN_TYPEMAP_WCHARLEAK_MSG) wchar_t_const_ptr_member; // Setting a const wchar_t * variable may leak memory.
+
%include
+
// throw is invalid in C++17 and later, only SWIG to use it
#define TESTCASE_THROW1(T1) throw(T1)
%{
#define TESTCASE_THROW1(T1)
%}
+%{
+// Unicode strings are stored in li_std_wstring.h file which has the BOM appropriately set, primarily for Visual C++ to correctly interpret the wide strings
+#include "li_std_wstring.h"
+%}
+
%inline %{
#include
+#include
+
+bool debug = false;
+
+void show_wstring_bytes(const std::wstring &s) {
+ unsigned char *p = (unsigned char *)s.data();
+ size_t len = s.size()*sizeof(wchar_t);
+ std::wcout << L"s: " << /*s <<*/ L"[";
+ for (size_t i = 0; i
%}
+%fragment("Swig_csharp_UTF16ToWString", "header") %{
+/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
+static std::wstring Swig_csharp_UTF16ToWString(const wchar_t *str) {
+ if (sizeof(wchar_t) == 2) {
+ return std::wstring(str);
+ } else {
+ const unsigned short *pBegin((const unsigned short *)(str));
+ const unsigned short *ptr(pBegin);
+
+ while (*ptr != 0)
+ ++ptr;
+
+ std::wstring result;
+ result.reserve(ptr - pBegin);
+ while(pBegin != ptr)
+ result.push_back(*pBegin++);
+
+ return result;
+ }
+}
+%}
+
namespace std {
%naturalvar wstring;
@@ -31,22 +53,22 @@ class wstring;
%typemap(csdirectorin) wstring "$iminput"
%typemap(csdirectorout) wstring "$cscall"
-%typemap(in, canthrow=1) wstring
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") wstring
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- $1.assign($input); %}
-%typemap(out) wstring %{ $result = SWIG_csharp_wstring_callback($1.c_str()); %}
+ $1 = Swig_csharp_UTF16ToWString($input); %}
+%typemap(out) wstring %{ $result = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1.size()); %}
-%typemap(directorout, canthrow=1) wstring
+%typemap(directorout, canthrow=1) wstring
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
$result.assign($input); %}
-%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1.size()); %}
%typemap(csin) wstring "$csinput"
%typemap(csout, excode=SWIGEXCODE) wstring {
@@ -72,14 +94,14 @@ class wstring;
%typemap(csdirectorin) const wstring & "$iminput"
%typemap(csdirectorout) const wstring & "$cscall"
-%typemap(in, canthrow=1) const wstring &
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") const wstring &
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- std::wstring $1_str($input);
+ std::wstring $1_str(Swig_csharp_UTF16ToWString($input));
$1 = &$1_str; %}
-%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_callback($1->c_str()); %}
+%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_with_length_callback($1->c_str(), (int)$1->size()); %}
%typemap(csin) const wstring & "$csinput"
%typemap(csout, excode=SWIGEXCODE) const wstring & {
@@ -97,7 +119,7 @@ class wstring;
$1_str = $input;
$result = &$1_str; %}
-%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1->size()); %}
%typemap(csvarin, excode=SWIGEXCODE2) const wstring & %{
set {
diff --git a/Lib/csharp/wchar.i b/Lib/csharp/wchar.i
index 1ece767da..14879c80c 100644
--- a/Lib/csharp/wchar.i
+++ b/Lib/csharp/wchar.i
@@ -11,28 +11,49 @@
#if !defined(SWIG_CSHARP_NO_WSTRING_HELPER)
#if !defined(SWIG_CSHARP_WSTRING_HELPER_)
#define SWIG_CSHARP_WSTRING_HELPER_
+
+%fragment(""); // TODO: %fragment("") wchar_t * {
+ delete [] $1;
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,fragment="") wchar_t * {
+ delete [] $1;
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+#else
+%typemap(memberin,fragment="") wchar_t * {
+ free($1);
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,fragment="") wchar_t * {
+ free($1);
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+
+#endif
diff --git a/Lib/swigwarnings.swg b/Lib/swigwarnings.swg
index 34c98fbda..3f9ddcb58 100644
--- a/Lib/swigwarnings.swg
+++ b/Lib/swigwarnings.swg
@@ -52,6 +52,7 @@
%define SWIGWARN_TYPEMAP_CHARLEAK_MSG "451:Setting a const char * variable may leak memory." %enddef
%define SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG "454:Setting a pointer/reference variable may leak memory." %enddef
+%define SWIGWARN_TYPEMAP_WCHARLEAK_MSG "455:Setting a const wchar_t * variable may leak memory." %enddef
%define SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG "470:Thread/reentrant unsafe wrapping, consider returning by value instead." %enddef
%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG "473:Returning a pointer or reference in a director method is not recommended." %enddef
%define SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG "476:Initialization using std::initializer_list." %enddef
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
index 267b69c90..8755f2ab5 100644
--- a/Source/Include/swigwarn.h
+++ b/Source/Include/swigwarn.h
@@ -163,6 +163,7 @@
#define WARN_TYPEMAP_SWIGTYPE 452 /* No longer issued */
#define WARN_TYPEMAP_APPLY_UNDEF 453
#define WARN_TYPEMAP_SWIGTYPELEAK 454
+#define WARN_TYPEMAP_WCHARLEAK 455
#define WARN_TYPEMAP_IN_UNDEF 460
#define WARN_TYPEMAP_OUT_UNDEF 461
From 0fbd6cc364910a352ee01a90196f647b32076ef1 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 26 Apr 2022 21:27:15 +0100
Subject: [PATCH 420/662] wchar_t C# marshalling tweak
Use more appropriate unsigned short (2 byte type) pointer
for C# ctype instead of wchar_t pointer
---
Lib/csharp/std_wstring.i | 14 ++++++++------
Lib/csharp/wchar.i | 13 +++++++------
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index 8b38dd44c..e8b81bea7 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -2,7 +2,9 @@
* std_wstring.i
*
* Typemaps for std::wstring and const std::wstring&
- * These are mapped to a C# String and are passed around by value.
+ * std::wstring is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * std::wstring support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
*
* To use non-const std::wstring references use the following %apply. Note
* that they are passed by value.
@@ -17,11 +19,11 @@
%fragment("Swig_csharp_UTF16ToWString", "header") %{
/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
-static std::wstring Swig_csharp_UTF16ToWString(const wchar_t *str) {
+static std::wstring Swig_csharp_UTF16ToWString(const unsigned short *str) {
if (sizeof(wchar_t) == 2) {
- return std::wstring(str);
+ return std::wstring((wchar_t *)str);
} else {
- const unsigned short *pBegin((const unsigned short *)(str));
+ const unsigned short *pBegin(str);
const unsigned short *ptr(pBegin);
while (*ptr != 0)
@@ -44,7 +46,7 @@ namespace std {
class wstring;
// wstring
-%typemap(ctype, out="void *") wstring "wchar_t *"
+%typemap(ctype, out="void *") wstring "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
@@ -84,7 +86,7 @@ class wstring;
return $null; %}
// const wstring &
-%typemap(ctype, out="void *") const wstring & "wchar_t *"
+%typemap(ctype, out="void *") const wstring & "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
diff --git a/Lib/csharp/wchar.i b/Lib/csharp/wchar.i
index 14879c80c..c6720eb04 100644
--- a/Lib/csharp/wchar.i
+++ b/Lib/csharp/wchar.i
@@ -2,10 +2,11 @@
* wchar.i
*
* Typemaps for the wchar_t type
- * These are mapped to a C# String and are passed around by value.
+ * wchar_t * is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * wchar_t * support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
*
* Support code for wide strings can be turned off by defining SWIG_CSHARP_NO_WSTRING_HELPER
- *
* ----------------------------------------------------------------------------- */
#if !defined(SWIG_CSHARP_NO_WSTRING_HELPER)
@@ -101,14 +102,14 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStri
%fragment("Swig_csharp_UTF16ToWCharPtr", "header") %{
/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
-static wchar_t * Swig_csharp_UTF16ToWCharPtr(const wchar_t *str) {
+static wchar_t * Swig_csharp_UTF16ToWCharPtr(const unsigned short *str) {
if (sizeof(wchar_t) == 2) {
return (wchar_t *)str;
} else {
wchar_t *result = 0;
if (str) {
- const unsigned short *pBegin((const unsigned short *)(str));
+ const unsigned short *pBegin(str);
const unsigned short *pEnd(pBegin);
wchar_t *ptr = 0;
@@ -142,7 +143,7 @@ static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
}
%}
-%typemap(ctype, out="void *") wchar_t * "wchar_t *"
+%typemap(ctype, out="void *") wchar_t * "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
@@ -167,7 +168,7 @@ static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
%typemap(in, fragment="Swig_csharp_UTF16ToWCharPtr") wchar_t *
%{ $1 = Swig_csharp_UTF16ToWCharPtr($input); %}
-%typemap(out) wchar_t * %{ $result = $1 ? SWIG_csharp_wstring_callback((wchar_t *)$1) : 0; %}
+%typemap(out) wchar_t * %{ $result = $1 ? SWIG_csharp_wstring_callback($1) : 0; %}
%typemap(freearg, fragment="Swig_csharp_UTF16ToWCharPtrFree") wchar_t *
%{ Swig_csharp_UTF16ToWCharPtrFree($1); %}
From 79a9389355f4e42ca9866617bf22e1ccaf5547bb Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 27 Apr 2022 18:41:24 +0100
Subject: [PATCH 421/662] Add support for throwing wstring exceptions
Throw an ApplicationException for std::wstring and wchar_t * strings
---
.../test-suite/csharp/li_std_wstring_runme.cs | 18 +++++
Examples/test-suite/li_std_wstring.i | 18 ++++-
Lib/csharp/std_wstring.i | 6 +-
Lib/csharp/wchar.i | 71 ++++++++++++++++++-
4 files changed, 106 insertions(+), 7 deletions(-)
diff --git a/Examples/test-suite/csharp/li_std_wstring_runme.cs b/Examples/test-suite/csharp/li_std_wstring_runme.cs
index 059688a75..21c225e5f 100644
--- a/Examples/test-suite/csharp/li_std_wstring_runme.cs
+++ b/Examples/test-suite/csharp/li_std_wstring_runme.cs
@@ -105,6 +105,24 @@ public class runme
check_equal(e.Message, "throwing test_throw");
}
+ try {
+ li_std_wstring.test_throw_jp();
+ } catch (Exception e) {
+ check_equal(e.Message, "JP: 日本語");
+ }
+
+ try {
+ li_std_wstring.test_throw_ref_jp();
+ } catch (Exception e) {
+ check_equal(e.Message, "JP: 日本語");
+ }
+
+ try {
+ li_std_wstring.test_throw_wchar_t_ptr();
+ } catch (Exception e) {
+ check_equal(e.Message, "JP: 日本語");
+ }
+
x = "abc\0def";
// Unlike other languages, embedded NULL in std::string not supported
// check_equal(li_std_wstring.test_value(x), x);
diff --git a/Examples/test-suite/li_std_wstring.i b/Examples/test-suite/li_std_wstring.i
index 1f5ddb458..43031679a 100644
--- a/Examples/test-suite/li_std_wstring.i
+++ b/Examples/test-suite/li_std_wstring.i
@@ -103,9 +103,23 @@ bool test_equal_ru(const std::wstring &s) {
return test_equal(RU_WSTRING, s);
}
-void test_throw() TESTCASE_THROW1(std::wstring){
+void test_throw() TESTCASE_THROW1(std::wstring) {
static std::wstring x = L"throwing test_throw";
-
+ throw x;
+}
+
+void test_throw_wchar_t_ptr() TESTCASE_THROW1(std::wstring) {
+ static std::wstring x = JP_WSTRING;
+ throw x;
+}
+
+void test_throw_jp() TESTCASE_THROW1(std::wstring) {
+ static std::wstring x = JP_WSTRING;
+ throw x;
+}
+
+void test_throw_ref_jp() TESTCASE_THROW1(const std::wstring&) {
+ static std::wstring x = JP_WSTRING;
throw x;
}
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index e8b81bea7..6d2d52722 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -81,8 +81,7 @@ class wstring;
%typemap(typecheck) wstring = wchar_t *;
%typemap(throws, canthrow=1) wstring
-%{ std::string message($1.begin(), $1.end());
- SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.c_str(), (int)$1.size());
return $null; %}
// const wstring &
@@ -136,8 +135,7 @@ class wstring;
%typemap(typecheck) const wstring & = wchar_t *;
%typemap(throws, canthrow=1) const wstring &
-%{ std::string message($1.begin(), $1.end());
- SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.c_str(), (int)$1.size());
return $null; %}
}
diff --git a/Lib/csharp/wchar.i b/Lib/csharp/wchar.i
index c6720eb04..d0f1fe0f6 100644
--- a/Lib/csharp/wchar.i
+++ b/Lib/csharp/wchar.i
@@ -39,7 +39,7 @@ static void * SWIG_csharp_wstring_callback(const wchar_t *s) {
[global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringCallback_$module")]
public static extern void SWIGRegisterWStringCallback_$module(SWIGWStringDelegate wstringUTF16Delegate, SWIGWStringDelegate wstringUTF32Delegate);
- static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ public static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
}
@@ -72,6 +72,71 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStri
#endif // SWIG_CSHARP_WSTRING_HELPER_
#endif // SWIG_CSHARP_NO_WSTRING_HELPER
+#if !defined(SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER)
+#if !defined(SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_)
+#define SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+
+%insert(runtime) %{
+/* Callback for returning strings to C# without leaking memory */
+typedef void (SWIGSTDCALL* SWIG_CSharpWStringExceptionHelperCallback)(const wchar_t *, int length);
+static SWIG_CSharpWStringExceptionHelperCallback SWIG_csharp_ApplicationException_callback = NULL;
+%}
+
+%pragma(csharp) imclasscode=%{
+ protected class SWIGWStringExceptionHelper {
+
+ [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]
+ public delegate void SWIGWStringExceptionDelegate(global::System.IntPtr message, int length);
+ static SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF16);
+ static SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF32);
+
+ [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringExceptionCallback_$module")]
+ public static extern void SWIGRegisterWStringExceptionCallback_$module(SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate, SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate);
+
+ static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
+ }
+
+ public static string CreateWStringFromUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ if (length == 0)
+ return string.Empty;
+
+ byte[] buffer = new byte[length * 4];
+ global::System.Runtime.InteropServices.Marshal.Copy(cString, buffer, 0, buffer.Length);
+ byte[] utf8buffer = global::System.Text.Encoding.Convert(global::System.Text.Encoding.UTF32, global::System.Text.Encoding.UTF8, buffer);
+ return global::System.Text.Encoding.Default.GetString(utf8buffer);
+ }
+
+ static void SetPendingApplicationExceptionUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ string message = SWIGWStringHelper.CreateWStringFromUTF16(cString, length);
+ SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+ }
+
+ static void SetPendingApplicationExceptionUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ string message = SWIGWStringHelper.CreateWStringFromUTF32(cString, length);
+ SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+ }
+
+ static SWIGWStringExceptionHelper() {
+ SWIGRegisterWStringExceptionCallback_$module(applicationExceptionUTF16Delegate, applicationExceptionUTF32Delegate);
+ }
+ }
+
+ static protected SWIGWStringExceptionHelper swigWStringExceptionHelper = new SWIGWStringExceptionHelper();
+%}
+
+%insert(runtime) %{
+#ifdef __cplusplus
+extern "C"
+#endif
+SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringExceptionCallback_$module(SWIG_CSharpWStringExceptionHelperCallback callback_utf16, SWIG_CSharpWStringExceptionHelperCallback callback_utf32) {
+ SWIG_csharp_ApplicationException_callback = sizeof(wchar_t) == 2 ? callback_utf16 : callback_utf32;
+}
+%}
+
+#endif // SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+#endif // SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER
+
// wchar_t
%typemap(ctype) wchar_t "wchar_t"
@@ -175,6 +240,10 @@ static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
%typemap(typecheck) wchar_t * = char *;
+%typemap(throws, canthrow=1, fragment="") wchar_t *
+%{ SWIG_csharp_ApplicationException_callback($1, (int)wcslen($1));
+ return $null; %}
+
/* Default typemap for handling wchar_t * members (based on char * in swig.swg) */
From fc6269a3cad26acbb62f7eff8b3a218433fc5554 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 2 May 2022 21:25:58 +0100
Subject: [PATCH 422/662] GHA changes
octave-6.4 has disappeared - stop testing it.
ruby-2.6 allow to fail (for li_std_set), see issue #2115.
---
.github/workflows/ci.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f6fb3ec7a..4a62868c2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -96,7 +96,6 @@ jobs:
- SWIGLANG: octave
CPPSTD: c++11
- SWIGLANG: octave
- VER: '6.4'
CPPSTD: c++11
- SWIGLANG: perl5
- SWIGLANG: php
@@ -300,6 +299,9 @@ jobs:
GCC: 11
continue-on-error: true
os: ubuntu-18.04 # ocaml-4.08 in ubuntu-20.04 not yet working
+ # Currently broken
+ - SWIGLANG: ruby
+ VER: '2.6'
# Run all of them, as opposed to aborting when one fails
fail-fast: false
From 5b7447b20e9cbef3889a7e87d560c3f6a611ada6 Mon Sep 17 00:00:00 2001
From: tartanpaint <35690467+tartanpaint@users.noreply.github.com>
Date: Tue, 21 Jan 2020 15:27:25 +0000
Subject: [PATCH 423/662] Fix marshalling of std::wstring parameters in
directors
std::wstring parameters on SWIG directors were being truncated to a single character due to marshalling inconsistencies.
This patch applies the same MarshalAs(UnmanagedType.LPWStr) attribute to director delegate methods and allows std::wstrings to be successfully received in the C# code via director calls.
---
Lib/csharp/std_wstring.i | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index 6d2d52722..87c9a9f15 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -49,7 +49,9 @@ class wstring;
%typemap(ctype, out="void *") wstring "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+Â Â Â Â Â directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+Â Â Â Â Â directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) wstring "string"
%typemap(cstype) wstring "string"
%typemap(csdirectorin) wstring "$iminput"
@@ -88,7 +90,9 @@ class wstring;
%typemap(ctype, out="void *") const wstring & "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+Â Â Â Â Â directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+Â Â Â Â Â directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) const wstring & "string"
%typemap(cstype) const wstring & "string"
From 3377b63dad9d5f35cc711966a11f427b79a056e7 Mon Sep 17 00:00:00 2001
From: tartanpaint <35690467+tartanpaint@users.noreply.github.com>
Date: Wed, 22 Jan 2020 14:41:57 +0000
Subject: [PATCH 424/662] Fix line endings
---
Lib/csharp/std_wstring.i | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index 87c9a9f15..d45471014 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -50,8 +50,8 @@ class wstring;
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
-Â Â Â Â Â directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
-Â Â Â Â Â directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) wstring "string"
%typemap(cstype) wstring "string"
%typemap(csdirectorin) wstring "$iminput"
@@ -91,8 +91,8 @@ class wstring;
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
-Â Â Â Â Â directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
-Â Â Â Â Â directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) const wstring & "string"
%typemap(cstype) const wstring & "string"
From 9fd59650cf57c963311c18a779aacd949553520f Mon Sep 17 00:00:00 2001
From: tartanpaint <35690467+tartanpaint@users.noreply.github.com>
Date: Wed, 29 Jan 2020 09:00:59 +0000
Subject: [PATCH 425/662] Apply C# test updates for directors with std::wstring
supplied by wsfulton
---
Examples/test-suite/csharp/Makefile.in | 1 +
.../csharp/director_wstring_runme.cs | 41 +++++++++++++++++++
Examples/test-suite/director_wstring.i | 6 +++
3 files changed, 48 insertions(+)
create mode 100644 Examples/test-suite/csharp/director_wstring_runme.cs
diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in
index 74010c284..600c5953d 100644
--- a/Examples/test-suite/csharp/Makefile.in
+++ b/Examples/test-suite/csharp/Makefile.in
@@ -25,6 +25,7 @@ CPP_TEST_CASES = \
csharp_namespace_system_collision \
csharp_prepost \
csharp_typemaps \
+ director_wstring \
enum_thorough_simple \
enum_thorough_typesafe \
exception_partial_info \
diff --git a/Examples/test-suite/csharp/director_wstring_runme.cs b/Examples/test-suite/csharp/director_wstring_runme.cs
new file mode 100644
index 000000000..6f97dcb50
--- /dev/null
+++ b/Examples/test-suite/csharp/director_wstring_runme.cs
@@ -0,0 +1,41 @@
+using System;
+using director_wstringNamespace;
+
+public class runme
+{
+ static void Main()
+ {
+ runme r = new runme();
+ r.run();
+ }
+
+ void run()
+ {
+ director_wstring_B b = new director_wstring_B("hello");
+
+ b.get(0);
+ if (b.get_first() != "hello world!")
+ throw new ApplicationException("Incorrect get_first:" + b.get_first());
+
+ b.call_process_func();
+
+ if (b.smem != "hello")
+ throw new ApplicationException("Incorrect smem:" + b.smem);
+ }
+}
+
+class director_wstring_B : A
+{
+ public String smem;
+ public director_wstring_B(String first) : base(first)
+ {
+ }
+ public override String get_first()
+ {
+ return base.get_first() + " world!";
+ }
+ public override void process_text(String s)
+ {
+ this.smem = s;
+ }
+}
\ No newline at end of file
diff --git a/Examples/test-suite/director_wstring.i b/Examples/test-suite/director_wstring.i
index 17761ea59..73900ccf6 100644
--- a/Examples/test-suite/director_wstring.i
+++ b/Examples/test-suite/director_wstring.i
@@ -40,9 +40,15 @@ struct A
std::vector m_strings;
+#if !defined(SWIGCSHARP)
virtual void process_text(const wchar_t *text)
{
}
+#else
+ virtual void process_text(const std::wstring& text)
+ {
+ }
+#endif
virtual std::wstring multiple_params_val(const std::wstring& p1, const std::wstring& p2, std::wstring p3, std::wstring p4) const
{ return get_first(); }
From 751d443046ac5954ea64a169e6444363b65a8e80 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 4 May 2022 09:28:21 +0100
Subject: [PATCH 426/662] C# std::wstring director support
Updates for #1706
---
.../csharp/director_wstring_runme.cs | 21 +++++++++++++++++--
Examples/test-suite/director_wstring.i | 13 ++++++------
Lib/csharp/std_wstring.i | 6 +++---
3 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/Examples/test-suite/csharp/director_wstring_runme.cs b/Examples/test-suite/csharp/director_wstring_runme.cs
index 6f97dcb50..fcb6e7afa 100644
--- a/Examples/test-suite/csharp/director_wstring_runme.cs
+++ b/Examples/test-suite/csharp/director_wstring_runme.cs
@@ -17,10 +17,19 @@ public class runme
if (b.get_first() != "hello world!")
throw new ApplicationException("Incorrect get_first:" + b.get_first());
+ /*
b.call_process_func();
-
if (b.smem != "hello")
throw new ApplicationException("Incorrect smem:" + b.smem);
+ */
+
+ b.call_process_wstring_func();
+ if (b.smem != "hello (wstring)")
+ throw new ApplicationException("Incorrect smem:" + b.smem);
+
+ b.call_process_wstring_ref_func();
+ if (b.smem != "hello (wstring ref)")
+ throw new ApplicationException("Incorrect smem:" + b.smem);
}
}
@@ -38,4 +47,12 @@ class director_wstring_B : A
{
this.smem = s;
}
-}
\ No newline at end of file
+ public override void process_wstring_text(String s)
+ {
+ this.smem = s + " (wstring)";
+ }
+ public override void process_wstring_ref_text(String s)
+ {
+ this.smem = s + " (wstring ref)";
+ }
+}
diff --git a/Examples/test-suite/director_wstring.i b/Examples/test-suite/director_wstring.i
index 73900ccf6..10dd032d0 100644
--- a/Examples/test-suite/director_wstring.i
+++ b/Examples/test-suite/director_wstring.i
@@ -41,13 +41,12 @@ struct A
#if !defined(SWIGCSHARP)
- virtual void process_text(const wchar_t *text)
- {
- }
+ virtual void process_text(const wchar_t *text) {}
#else
- virtual void process_text(const std::wstring& text)
- {
- }
+// temp until wchar_t* fixed
+ virtual void process_text(std::wstring text) {}
+ virtual void process_wstring_text(std::wstring text) {}
+ virtual void process_wstring_ref_text(const std::wstring& text) {}
#endif
virtual std::wstring multiple_params_val(const std::wstring& p1, const std::wstring& p2, std::wstring p3, std::wstring p4) const
@@ -57,6 +56,8 @@ struct A
{ return get_first(); }
void call_process_func() { process_text(L"hello"); }
+ void call_process_wstring_func() { process_wstring_text(L"hello"); }
+ void call_process_wstring_ref_func() { process_wstring_ref_text(L"hello"); }
};
%}
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index d45471014..1d10ca808 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -70,7 +70,7 @@ class wstring;
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- $result.assign($input); %}
+ $result = Swig_csharp_UTF16ToWString($input); %}
%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1.size()); %}
@@ -121,10 +121,10 @@ class wstring;
}
/* possible thread/reentrant code problem */
static std::wstring $1_str;
- $1_str = $input;
+ $1_str = Swig_csharp_UTF16ToWString($input);
$result = &$1_str; %}
-%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1->size()); %}
+%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_with_length_callback($1.c_str(), (int)$1.size()); %}
%typemap(csvarin, excode=SWIGEXCODE2) const wstring & %{
set {
From bb39235c9ce53b8587a929c7e0f98beda2891be3 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 4 May 2022 19:33:47 +0100
Subject: [PATCH 427/662] Add C# wchar_t * director typemaps
More Python std::wstring directors Python testing
---
CHANGES.current | 3 +++
.../test-suite/csharp/director_wstring_runme.cs | 2 --
Examples/test-suite/director_wstring.i | 6 +-----
.../test-suite/python/director_wstring_runme.py | 16 ++++++++++++++++
Lib/csharp/wchar.i | 11 ++++++++++-
5 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index cfa0af2db..f14dc24ad 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-04: wsfulton
+ [C#] Add C# wchar_t * director typemaps
+
2022-04-20: cminyard
Fix an issue where newlines were not properly generated
for godirectorin typemaps. If you have a virtual function
diff --git a/Examples/test-suite/csharp/director_wstring_runme.cs b/Examples/test-suite/csharp/director_wstring_runme.cs
index fcb6e7afa..7258e7f94 100644
--- a/Examples/test-suite/csharp/director_wstring_runme.cs
+++ b/Examples/test-suite/csharp/director_wstring_runme.cs
@@ -17,11 +17,9 @@ public class runme
if (b.get_first() != "hello world!")
throw new ApplicationException("Incorrect get_first:" + b.get_first());
- /*
b.call_process_func();
if (b.smem != "hello")
throw new ApplicationException("Incorrect smem:" + b.smem);
- */
b.call_process_wstring_func();
if (b.smem != "hello (wstring)")
diff --git a/Examples/test-suite/director_wstring.i b/Examples/test-suite/director_wstring.i
index 10dd032d0..02df9d64c 100644
--- a/Examples/test-suite/director_wstring.i
+++ b/Examples/test-suite/director_wstring.i
@@ -39,15 +39,11 @@ struct A
std::vector m_strings;
+ virtual const wchar_t * wchar_out() { return L"ciao"; }
-#if !defined(SWIGCSHARP)
virtual void process_text(const wchar_t *text) {}
-#else
-// temp until wchar_t* fixed
- virtual void process_text(std::wstring text) {}
virtual void process_wstring_text(std::wstring text) {}
virtual void process_wstring_ref_text(const std::wstring& text) {}
-#endif
virtual std::wstring multiple_params_val(const std::wstring& p1, const std::wstring& p2, std::wstring p3, std::wstring p4) const
{ return get_first(); }
diff --git a/Examples/test-suite/python/director_wstring_runme.py b/Examples/test-suite/python/director_wstring_runme.py
index 5facc1f1d..659cf1854 100644
--- a/Examples/test-suite/python/director_wstring_runme.py
+++ b/Examples/test-suite/python/director_wstring_runme.py
@@ -12,6 +12,12 @@ class B(A):
def process_text(self, s):
self.smem = s
+ def process_wstring_text(self, s):
+ self.smem = s + " (wstring)"
+
+ def process_wstring_ref_text(self, s):
+ self.smem = s + " (wstring ref)"
+
b = B("hello")
@@ -24,3 +30,13 @@ b.call_process_func()
if b.smem != "hello":
raise RuntimeError("smem: {}".format(smem))
+
+b.call_process_wstring_func()
+
+if b.smem != "hello (wstring)":
+ raise RuntimeError("smem: {}".format(smem))
+
+b.call_process_wstring_ref_func()
+
+if b.smem != "hello (wstring ref)":
+ raise RuntimeError("smem: {}".format(smem))
diff --git a/Lib/csharp/wchar.i b/Lib/csharp/wchar.i
index d0f1fe0f6..2ada4df75 100644
--- a/Lib/csharp/wchar.i
+++ b/Lib/csharp/wchar.i
@@ -211,9 +211,13 @@ static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
%typemap(ctype, out="void *") wchar_t * "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) wchar_t * "string"
%typemap(cstype) wchar_t * "string"
+%typemap(csdirectorin) wchar_t * "$iminput"
+%typemap(csdirectorout) wchar_t * "$cscall"
%typemap(csin) wchar_t * "$csinput"
%typemap(csout, excode=SWIGEXCODE) wchar_t * {
@@ -238,6 +242,11 @@ static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
%typemap(freearg, fragment="Swig_csharp_UTF16ToWCharPtrFree") wchar_t *
%{ Swig_csharp_UTF16ToWCharPtrFree($1); %}
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) wchar_t *
+%{ $result = Swig_csharp_UTF16ToWCharPtr($input); %}
+
+%typemap(directorin) wchar_t * %{ $input = SWIG_csharp_wstring_with_length_callback($1, (int)wcslen($1)); %}
+
%typemap(typecheck) wchar_t * = char *;
%typemap(throws, canthrow=1, fragment="") wchar_t *
From fe2cdb1d90023a899161233ca83a5d58fd6d6dc3 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 4 May 2022 21:40:15 +0100
Subject: [PATCH 428/662] Add python 3.2 as allowed to fail
Seems broken atm
---
.github/workflows/ci.yml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4a62868c2..5cf11718e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -302,6 +302,11 @@ jobs:
# Currently broken
- SWIGLANG: ruby
VER: '2.6'
+ continue-on-error: true
+ - SWIGLANG: python
+ VER: '3.2'
+ os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
+ continue-on-error: true
# Run all of them, as opposed to aborting when one fails
fail-fast: false
From a3b49ef75ef1bbb9881ab593d34c00f174dcaeda Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Thu, 5 May 2022 08:42:02 +0100
Subject: [PATCH 429/662] GHA: continue-on-error corrections
---
.github/workflows/ci.yml | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5cf11718e..a03ca7459 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -116,6 +116,7 @@ jobs:
- SWIGLANG: python
VER: '3.2'
os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
+ continue-on-error: true # broken packages problem
- SWIGLANG: python
VER: '3.3'
os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
@@ -166,6 +167,7 @@ jobs:
VER: '2.5'
- SWIGLANG: ruby
VER: '2.6'
+ continue-on-error: true # Sometimes fails, see https://github.com/swig/swig/issues/2115
- SWIGLANG: ruby
VER: '2.7'
- SWIGLANG: ruby
@@ -299,14 +301,6 @@ jobs:
GCC: 11
continue-on-error: true
os: ubuntu-18.04 # ocaml-4.08 in ubuntu-20.04 not yet working
- # Currently broken
- - SWIGLANG: ruby
- VER: '2.6'
- continue-on-error: true
- - SWIGLANG: python
- VER: '3.2'
- os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
- continue-on-error: true
# Run all of them, as opposed to aborting when one fails
fail-fast: false
From f029beffe8e86b1b6e8f27b8dcc0514b99fa8bac Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 6 May 2022 08:06:26 +0100
Subject: [PATCH 430/662] Ruby li_std_set test failure workaround
Prevent GC from collecting "hello" string in testcase
as workaround to prevent GC occasionally causing segfault.
Issue #2115
---
.github/workflows/ci.yml | 1 -
Examples/test-suite/ruby/li_std_set_runme.rb | 8 ++++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a03ca7459..60791155c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -167,7 +167,6 @@ jobs:
VER: '2.5'
- SWIGLANG: ruby
VER: '2.6'
- continue-on-error: true # Sometimes fails, see https://github.com/swig/swig/issues/2115
- SWIGLANG: ruby
VER: '2.7'
- SWIGLANG: ruby
diff --git a/Examples/test-suite/ruby/li_std_set_runme.rb b/Examples/test-suite/ruby/li_std_set_runme.rb
index efc163bee..455a1706e 100644
--- a/Examples/test-suite/ruby/li_std_set_runme.rb
+++ b/Examples/test-suite/ruby/li_std_set_runme.rb
@@ -56,11 +56,15 @@ m.value == 'c'
s = LanguageSet.new
s.insert([1,2])
s.insert(1)
-s.insert("hello")
+# There is a reference count issue that needs fixing, see https://github.com/swig/swig/issues/2115
+# Workaround is to create hello variable containing a string and use it instead of just "hello"
+hello = "hello"
+s.insert(hello)
#s.to_a == [1,[1,2],'hello'] # sort order: s.sort {|a,b| a.hash <=> b.hash}
# Test above is flawed as LanguageSet sorts by each element's hash, so the order will change from one invocation to the next. Sort a conversion to array instead.
+GC.start
sa = s.to_a.sort { |x, y| x.to_s <=> y.to_s }
-sa == [1,[1,2],'hello']
+sa == [1,[1,2],hello]
EOF
From f3ee3f2b126999bfc290733cbde84ab3d92e4e7f Mon Sep 17 00:00:00 2001
From: Konrad Eisele
Date: Mon, 26 Mar 2012 11:36:00 +0000
Subject: [PATCH 431/662] Add argcargv.i to Lua
Found in https://stackoverflow.com/questions/9860362/swig-lua-call-mint-argv-char-argc
---
Lib/lua/argcargv.i | 58 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 Lib/lua/argcargv.i
diff --git a/Lib/lua/argcargv.i b/Lib/lua/argcargv.i
new file mode 100644
index 000000000..670ce4a80
--- /dev/null
+++ b/Lib/lua/argcargv.i
@@ -0,0 +1,58 @@
+/* ------------------------------------------------------------
+ * --- Argc & Argv ---
+ * ------------------------------------------------------------
+ *
+ * Use it as follow:
+ *
+ * %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+ * extern int mainApp(size_t argc, const char **argv);
+ *
+ * then in the lua:
+ *
+ * args = { "arg0", "arg1" }
+ * mainApp(args);
+ *
+ * ------------------------------------------------------------ */
+
+%{
+SWIGINTERN int SWIG_argv_size(lua_State* L, int index) {
+ int n=0;
+ while(1){
+ lua_rawgeti(L,index,n+1);
+ if (lua_isnil(L,-1))
+ break;
+ ++n;
+ lua_pop(L,1);
+ }
+ lua_pop(L,1);
+ return n;
+}
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+ if (lua_istable(L,$input)) {
+ int i, size = SWIG_argv_size(L,$input);
+ $1 = ($1_ltype) size;
+ $2 = (char **) malloc((size+1)*sizeof(char *));
+ for (i = 0; i < size; i++) {
+ lua_rawgeti(L,$input,i+1);
+ if (lua_isnil(L,-1))
+ break;
+ $2[i] = (char *)lua_tostring(L, -1);
+ lua_pop(L,1);
+ }
+ $2[i]=NULL;
+ } else {
+ $1 = 0; $2 = 0;
+ lua_pushstring(L,"Expecting argv array");
+ lua_error(L);
+ }
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ $1 = lua_istable(L,$input);
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ free((char *) $2);
+}
From 72f7b829353cd2cd2bba2116cf6d961972d8d58a Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 6 May 2022 18:44:02 +0100
Subject: [PATCH 432/662] Correct warning message for wchar_t * typemaps
Use separate warning for char * and wchar_t * typemaps
SWIGWARN_TYPEMAP_CHARLEAK_MSG and SWIGWARN_TYPEMAP_WCHARLEAK_MSG
---
Lib/javascript/jsc/javascriptstrings.swg | 2 ++
Lib/typemaps/string.swg | 1 +
Lib/typemaps/strings.swg | 13 ++++++++++---
Lib/typemaps/wstring.swg | 1 +
4 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg
index 55c8e4b98..5c8081a82 100644
--- a/Lib/javascript/jsc/javascriptstrings.swg
+++ b/Lib/javascript/jsc/javascriptstrings.swg
@@ -75,6 +75,7 @@ SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t siz
}
%define %_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -166,6 +167,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
%_typemap_string(StringCode,
Char,
+ WarningLeakMsg,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
SWIG_CharPtrLen,
diff --git a/Lib/typemaps/string.swg b/Lib/typemaps/string.swg
index 4b7072365..72f4aa5b5 100644
--- a/Lib/typemaps/string.swg
+++ b/Lib/typemaps/string.swg
@@ -30,6 +30,7 @@ SWIG_strnlen(const char* s, size_t maxlen)
%include
%typemaps_string(%checkcode(STRING), %checkcode(CHAR),
+ SWIGWARN_TYPEMAP_CHARLEAK_MSG,
char, Char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize,
strlen, SWIG_strnlen,
"", CHAR_MIN, CHAR_MAX)
diff --git a/Lib/typemaps/strings.swg b/Lib/typemaps/strings.swg
index 87e97dd74..e8ed401b0 100644
--- a/Lib/typemaps/strings.swg
+++ b/Lib/typemaps/strings.swg
@@ -19,6 +19,7 @@
%define %_typemap_string(StringCode,
Char,
+ WarningLeakMsg,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
SWIG_CharPtrLen,
@@ -86,7 +87,7 @@
}
}
-%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=WarningLeakMsg) const Char * {
Char *cptr = 0; size_t csize = 0; int alloc = SWIG_NEWOBJ;
int res = SWIG_AsCharPtrAndSize($input, &cptr, &csize, &alloc);
if (!SWIG_IsOK(res)) {
@@ -117,7 +118,7 @@
}
}
-%typemap(memberin,noblock=1,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(memberin,noblock=1,warning=WarningLeakMsg) const Char * {
if ($input) {
size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1;
$1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
@@ -138,7 +139,7 @@
}
}
-%typemap(globalin,noblock=1,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(globalin,noblock=1,warning=WarningLeakMsg) const Char * {
if ($input) {
size_t size = SWIG_CharPtrLen($input) + 1;
$1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
@@ -501,6 +502,7 @@
#ifndef %_typemap2_string
%define %_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -591,6 +593,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
%_typemap_string(StringCode,
Char,
+ WarningLeakMsg,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
SWIG_CharPtrLen,
@@ -609,6 +612,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
* ------------------------------------------------------------ */
%define %typemaps_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -616,6 +620,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
SWIG_CharBufLen,
FragLimits, CHAR_MIN, CHAR_MAX)
%_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -631,6 +636,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
* ------------------------------------------------------------ */
%define %typemaps_string_alloc(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
@@ -640,6 +646,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
SWIG_DeleteCharArray,
FragLimits, CHAR_MIN, CHAR_MAX)
%_typemap2_string(StringCode, CharCode,
+ WarningLeakMsg,
Char, CharName,
SWIG_AsCharPtrAndSize,
SWIG_FromCharPtrAndSize,
diff --git a/Lib/typemaps/wstring.swg b/Lib/typemaps/wstring.swg
index cd409d1ce..d99c0bb38 100644
--- a/Lib/typemaps/wstring.swg
+++ b/Lib/typemaps/wstring.swg
@@ -31,6 +31,7 @@ SWIG_wcsnlen(const wchar_t* s, size_t maxlen)
%include
%typemaps_string(%checkcode(UNISTRING), %checkcode(UNICHAR),
+ SWIGWARN_TYPEMAP_WCHARLEAK_MSG,
wchar_t, WChar, SWIG_AsWCharPtrAndSize, SWIG_FromWCharPtrAndSize,
wcslen, SWIG_wcsnlen,
"", WCHAR_MIN, WCHAR_MAX)
From 464d548d7173d964b028941400b7e6a740fb7f94 Mon Sep 17 00:00:00 2001
From: Erez Geva
Date: Fri, 6 May 2022 20:36:57 +0200
Subject: [PATCH 433/662] Add argcargv.i to more languages: Perl 5, Tcl, PHP
Signed-off-by: Erez Geva
---
Lib/perl5/argcargv.i | 31 +++++++++++++++++++++++++++++++
Lib/php/argcargv.i | 40 ++++++++++++++++++++++++++++++++++++++++
Lib/tcl/argcargv.i | 28 ++++++++++++++++++++++++++++
3 files changed, 99 insertions(+)
create mode 100644 Lib/perl5/argcargv.i
create mode 100644 Lib/php/argcargv.i
create mode 100644 Lib/tcl/argcargv.i
diff --git a/Lib/perl5/argcargv.i b/Lib/perl5/argcargv.i
new file mode 100644
index 000000000..de7b626e0
--- /dev/null
+++ b/Lib/perl5/argcargv.i
@@ -0,0 +1,31 @@
+/* ------------------------------------------------------------
+ * --- Argc & Argv ---
+ * ------------------------------------------------------------ */
+
+%typemap(default) (int ARGC, char **ARGV) {
+ $1 = 0; $2 = NULL;
+}
+
+%typemap(in) (int ARGC, char **ARGV) {
+ int i;
+ I32 len;
+ AV *av = (AV *)SvRV($input);
+ if (SvTYPE(av) != SVt_PVAV) {
+ SWIG_croak("in method '$symname', Expecting reference to argv array");
+ goto fail;
+ }
+ len = av_len(av) + 1;
+ $1 = ($1_ltype) len;
+ $2 = (char **) malloc((len+1)*sizeof(char *));
+ for (i = 0; i < len; i++) {
+ SV **tv = av_fetch(av, i, 0);
+ $2[i] = SvPV_nolen(*tv);
+ }
+ $2[i] = NULL;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
diff --git a/Lib/php/argcargv.i b/Lib/php/argcargv.i
new file mode 100644
index 000000000..14b0cf2c9
--- /dev/null
+++ b/Lib/php/argcargv.i
@@ -0,0 +1,40 @@
+/* ------------------------------------------------------------
+ * --- Argc & Argv ---
+ * ------------------------------------------------------------ */
+
+%typemap(default) (int ARGC, char **ARGV) {
+ $1 = 0; $2 = NULL;
+}
+
+%typemap(in) (int ARGC, char **ARGV) {
+ int len, i;
+ zval *val;
+ zend_array *ar;
+ if (Z_TYPE($input) != IS_ARRAY) {
+ SWIG_PHP_Error(E_ERROR, "Type error in '$symname'. Expected array");
+ goto fail;
+ }
+ ar = Z_ARR($input);
+ len = zend_array_count(ar);
+ $1 = ($1_ltype) len;
+ $2 = (char **) malloc((len+1)*sizeof(char *));
+ i = 0;
+ ZEND_HASH_FOREACH_VAL(ar, val) {
+ if (Z_TYPE(*val) != IS_STRING) {
+ SWIG_PHP_Error(E_ERROR, "Array must use strings only, in '$symname'.");
+ goto fail;
+ }
+ if (i == len) {
+ SWIG_PHP_Error(E_ERROR, "Array is bigger than zend report in '$symname'.");
+ goto fail;
+ }
+ $2[i++] = Z_STRVAL(*val);
+ } ZEND_HASH_FOREACH_END();
+ $2[i] = NULL;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
diff --git a/Lib/tcl/argcargv.i b/Lib/tcl/argcargv.i
new file mode 100644
index 000000000..e43f2e657
--- /dev/null
+++ b/Lib/tcl/argcargv.i
@@ -0,0 +1,28 @@
+/* ------------------------------------------------------------
+ * --- Argc & Argv ---
+ * ------------------------------------------------------------ */
+
+%typemap(default) (int ARGC, char **ARGV) {
+ $1 = 0; $2 = NULL;
+}
+
+%typemap(in) (int ARGC, char **ARGV) {
+ int i, nitems;
+ Tcl_Obj **listobjv;
+ if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
+ SWIG_exception_fail(SWIG_ValueError, "in method '$symname', Expecting list of argv");
+ goto fail;
+ }
+ $1 = ($1_ltype) nitems;
+ $2 = (char **) malloc((nitems+1)*sizeof(char *));
+ for (i = 0; i < nitems; i++) {
+ $2[i] = Tcl_GetStringFromObj(listobjv[i], NULL);
+ }
+ $2[i] = NULL;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
From 72bb68d556e306b2faa54db7769f518e039f34f4 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 May 2022 06:22:25 +0100
Subject: [PATCH 434/662] Visual C++ warning fix in Python < 3.2 builtin
wrappers
Fixes:
warning C4311: 'type cast': pointer truncation from 'void *' to 'long'
warning C4302: 'type cast': truncation from 'void *' to 'long'
---
Lib/python/builtin.swg | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg
index 9dccd7e20..f31fccf1e 100644
--- a/Lib/python/builtin.swg
+++ b/Lib/python/builtin.swg
@@ -6,7 +6,11 @@ SWIGINTERN Py_hash_t
SwigPyObject_hash(PyObject *obj) {
SwigPyObject *sobj = (SwigPyObject *)obj;
void *ptr = sobj->ptr;
+#if PY_VERSION_HEX < 0x03020000
+ return (Py_hash_t)(Py_ssize_t)ptr;
+#else
return (Py_hash_t)ptr;
+#endif
}
SWIGINTERN Py_hash_t
From fd846be18bdaa7dda8f24e01aa24f73568a23a23 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 May 2022 07:09:44 +0100
Subject: [PATCH 435/662] Remove some usage of strdup
To fix visual c++ warning:
warning C4996: 'strdup': The POSIX name for this item is deprecated.
---
Doc/Manual/Varargs.html | 8 ++++++--
Examples/python/multimap/example.i | 8 +++++---
Examples/test-suite/python_varargs_typemap.i | 14 +++++++++-----
3 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index 620f2e5a0..80e391e49 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -512,7 +512,7 @@ like this:
%typemap(in) (...)(char *vargs[10]) {
int i;
- int argc;
+ Py_ssize_t argc;
for (i = 0; i < 10; i++) vargs[i] = 0;
argc = PyTuple_Size(varargs);
if (argc > 10) {
@@ -523,6 +523,7 @@ like this:
PyObject *pyobj = PyTuple_GetItem(varargs, i);
char *str = 0;
%#if PY_VERSION_HEX>=0x03000000
+ const char *strtmp = 0;
PyObject *pystr;
if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
@@ -532,7 +533,10 @@ like this:
if (!pystr) {
SWIG_fail;
}
- str = strdup(PyBytes_AsString(pystr));
+ strtmp = PyBytes_AsString(pystr);
+ str = (char *)malloc(strlen(strtmp) + 1);
+ if (str)
+ strcpy(str, strtmp);
Py_DECREF(pystr);
%#else
if (!PyString_Check(pyobj)) {
diff --git a/Examples/python/multimap/example.i b/Examples/python/multimap/example.i
index 3ff5d52c0..7087d426b 100644
--- a/Examples/python/multimap/example.i
+++ b/Examples/python/multimap/example.i
@@ -39,12 +39,14 @@ extern int gcd(int x, int y);
%#if PY_VERSION_HEX >= 0x03000000
{
PyObject *utf8str = PyUnicode_AsUTF8String(s);
- const char *cstr;
+ const char *strtmp = 0;
if (!utf8str) {
SWIG_fail;
}
- cstr = PyBytes_AsString(utf8str);
- $2[i] = strdup(cstr);
+ strtmp = PyBytes_AsString(utf8str);
+ $2[i] = (char *)malloc(strlen(strtmp) + 1);
+ if ($2[i])
+ strcpy($2[i], strtmp);
Py_DECREF(utf8str);
}
%#else
diff --git a/Examples/test-suite/python_varargs_typemap.i b/Examples/test-suite/python_varargs_typemap.i
index d809bf1fa..65ce72f43 100644
--- a/Examples/test-suite/python_varargs_typemap.i
+++ b/Examples/test-suite/python_varargs_typemap.i
@@ -17,21 +17,25 @@
PyObject *pyobj = PyTuple_GetItem(varargs, i);
char *str = 0;
%#if PY_VERSION_HEX>=0x03000000
+ const char *strtmp = 0;
PyObject *pystr;
if (!PyUnicode_Check(pyobj)) {
- PyErr_SetString(PyExc_ValueError, "Expected a string");
- SWIG_fail;
+ PyErr_SetString(PyExc_ValueError, "Expected a string");
+ SWIG_fail;
}
pystr = PyUnicode_AsUTF8String(pyobj);
if (!pystr) {
SWIG_fail;
}
- str = strdup(PyBytes_AsString(pystr));
+ strtmp = PyBytes_AsString(pystr);
+ str = (char *)malloc(strlen(strtmp) + 1);
+ if (str)
+ strcpy(str, strtmp);
Py_DECREF(pystr);
%#else
if (!PyString_Check(pyobj)) {
- PyErr_SetString(PyExc_ValueError, "Expected a string");
- SWIG_fail;
+ PyErr_SetString(PyExc_ValueError, "Expected a string");
+ SWIG_fail;
}
str = PyString_AsString(pyobj);
%#endif
From a598abe23d9c52686992a60e3608395e3c1689fc Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 May 2022 08:16:48 +0100
Subject: [PATCH 436/662] Java wstring throws typemap improvements
Unicode still not working, but works now for ASCII charset.
---
Lib/java/std_wstring.i | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/Lib/java/std_wstring.i b/Lib/java/std_wstring.i
index 3e462256a..efa9e63b8 100644
--- a/Lib/java/std_wstring.i
+++ b/Lib/java/std_wstring.i
@@ -88,9 +88,12 @@ class wstring;
//%typemap(typecheck) wstring = wchar_t *;
%typemap(throws) wstring
-%{ std::string message($1.begin(), $1.end());
- SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
- return $null; %}
+%{std::string message($1.size(), '\0');
+ for (size_t i = 0; i < $1.size(); ++i) {
+ message[i] = (char)$1[i];
+ }
+ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
+ return $null; %}
// const wstring &
%typemap(jni) const wstring & "jstring"
@@ -166,9 +169,12 @@ class wstring;
//%typemap(typecheck) const wstring & = wchar_t *;
%typemap(throws) const wstring &
-%{ std::string message($1.begin(), $1.end());
- SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
- return $null; %}
+%{std::string message($1.size(), '\0');
+ for (size_t i = 0; i < $1.size(); ++i) {
+ message[i] = (char)$1[i];
+ }
+ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
+ return $null; %}
}
From 15d69ec2704cf331b7e6cab006924ecbd8b1ea23 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 May 2022 08:17:48 +0100
Subject: [PATCH 437/662] Add runme.class file to Java test-suite clean
---
Examples/test-suite/java/Makefile.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in
index 7a34f587b..43695ce69 100644
--- a/Examples/test-suite/java/Makefile.in
+++ b/Examples/test-suite/java/Makefile.in
@@ -133,6 +133,7 @@ run_testcase = \
@if [ -d $(JAVA_PACKAGE) ]; then \
rm -rf $(JAVA_PACKAGE); \
fi
+ @rm -f $*_runme.class
clean:
@rm -f *.class hs_err*.log
From 06cd77834c4d4d91e30c6c8e08e363f89c64e5c5 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 May 2022 08:38:35 +0100
Subject: [PATCH 438/662] Add PyPy fix to changes file
---
CHANGES.current | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGES.current b/CHANGES.current
index f14dc24ad..a8975a03f 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-07: KrisThielemans
+ [Python] Fix "too many initializers for 'PyHeapTypeObject'" errors
+ using PyPy 3.8 and later.
+
2022-05-04: wsfulton
[C#] Add C# wchar_t * director typemaps
From 69dba70319ec9dbcdb65171f71f76c6f1f60cf79 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 May 2022 09:34:53 +0100
Subject: [PATCH 439/662] Visual C++ warning fix
---
Source/Modules/interface.cxx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx
index 76734dca1..c0c059019 100644
--- a/Source/Modules/interface.cxx
+++ b/Source/Modules/interface.cxx
@@ -148,7 +148,7 @@ void Swig_interface_propagate_methods(Node *n) {
process_interface_name(n);
collect_interface_base_classes(n);
List *methods = collect_interface_methods(n);
- bool is_interface = GetFlag(n, "feature:interface");
+ bool is_interface = GetFlag(n, "feature:interface") ? true : false;
for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
if (!is_interface && GetFlag(mi.item, "abstract"))
continue;
From 6939d91e4c6ea1f205574b85190a70b9c0db7bee Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 7 May 2022 09:36:26 +0100
Subject: [PATCH 440/662] Header file tidyup
Fix Visual C++ warning in scilab.cxx:
warning C4996: 'strtok': This function or variable may be unsafe.
---
Source/Modules/csharp.cxx | 2 +-
Source/Modules/guile.cxx | 1 -
Source/Modules/java.cxx | 2 +-
Source/Modules/mzscheme.cxx | 1 -
Source/Modules/ocaml.cxx | 1 -
Source/Modules/php.cxx | 1 -
Source/Modules/python.cxx | 5 ++---
Source/Modules/scilab.cxx | 2 +-
Source/Modules/utils.cxx | 2 +-
9 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index 7f19070ee..d393ad1d6 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -12,8 +12,8 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-#include // for INT_MAX
#include "cparse.h"
+#include // for INT_MAX
#include
/* Hash type used for upcalls from C/C++ */
diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx
index c30bf06f0..c70896af8 100644
--- a/Source/Modules/guile.cxx
+++ b/Source/Modules/guile.cxx
@@ -12,7 +12,6 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-
#include
// Note string broken in half for compilers that can't handle long strings
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index ae1e0fc2c..558231cf8 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -12,8 +12,8 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-#include // for INT_MAX
#include "cparse.h"
+#include // for INT_MAX
#include
#include "javadoc.h"
diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx
index 8080b93c0..64b699336 100644
--- a/Source/Modules/mzscheme.cxx
+++ b/Source/Modules/mzscheme.cxx
@@ -12,7 +12,6 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-
#include
static const char *usage = "\
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
index 6e45309e8..97bb8cc17 100644
--- a/Source/Modules/ocaml.cxx
+++ b/Source/Modules/ocaml.cxx
@@ -12,7 +12,6 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-
#include
static const char *usage = "\
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 8d937e9b2..d61f6e428 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -13,7 +13,6 @@
*/
#include "swigmod.h"
-
#include
#include
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 7161c8e7d..9aac91601 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -12,13 +12,12 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
-#include
#include "cparse.h"
+#include
#include
#include
-#include "pydoc.h"
-
#include
+#include "pydoc.h"
#define PYSHADOW_MEMBER 0x2
#define WARN_PYTHON_MULTIPLE_INH 405
diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx
index 1731b218c..8c5536486 100644
--- a/Source/Modules/scilab.cxx
+++ b/Source/Modules/scilab.cxx
@@ -11,9 +11,9 @@
* Scilab language module for SWIG.
* --------------------------------------------------------------------------*/
+#include "swigmod.h"
#include
#include
-#include "swigmod.h"
static const int SCILAB_IDENTIFIER_NAME_CHAR_MAX = 24;
diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx
index 2964ed3a6..0c1f87d19 100644
--- a/Source/Modules/utils.cxx
+++ b/Source/Modules/utils.cxx
@@ -11,7 +11,7 @@
* Various utility functions.
* ----------------------------------------------------------------------------- */
-#include
+#include "swigmod.h"
int is_public(Node *n) {
String *access = Getattr(n, "access");
From ca6a73277b7f48ce4cf9d30d7bff7813f3685684 Mon Sep 17 00:00:00 2001
From: Heinrich Schuchardt
Date: Mon, 9 May 2022 19:53:20 +0200
Subject: [PATCH 441/662] Python: define PY_SSIZE_T_CLEAN
It is recommended to always define PY_SSIZE_T_CLEAN before including
Python.h. Cf. https://docs.python.org/3/c-api/intro.html
This avoids errors like:
SystemError: PY_SSIZE_T_CLEAN macro must be defined for '#' formats
Signed-off-by: Heinrich Schuchardt
---
Lib/python/embed.i | 4 +++-
Lib/python/pyruntime.swg | 3 +++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/Lib/python/embed.i b/Lib/python/embed.i
index efd048789..95225e2de 100644
--- a/Lib/python/embed.i
+++ b/Lib/python/embed.i
@@ -29,7 +29,9 @@ As far as I know, this module is C++ safe.
#endif
%wrapper %{
-
+#ifndef PY_SSIZE_T_CLEAN
+#define PY_SSIZE_T_CLEAN
+#endif
#include
#ifdef __cplusplus
diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg
index 843fa6ce1..9b516ebaa 100644
--- a/Lib/python/pyruntime.swg
+++ b/Lib/python/pyruntime.swg
@@ -11,6 +11,9 @@
# include
#endif
+#ifndef PY_SSIZE_T_CLEAN
+#define PY_SSIZE_T_CLEAN
+#endif
#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
/* Use debug wrappers with the Python release dll */
# undef _DEBUG
From 5851eb09a2f6f8cfa3fe6946782900b40ec12842 Mon Sep 17 00:00:00 2001
From: Erez Geva
Date: Tue, 10 May 2022 20:13:55 +0200
Subject: [PATCH 442/662] Add Lua test for argcargv.i
Signed-off-by: Erez Geva
---
.../test-suite/lua/argcargvtest_runme.lua | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 Examples/test-suite/lua/argcargvtest_runme.lua
diff --git a/Examples/test-suite/lua/argcargvtest_runme.lua b/Examples/test-suite/lua/argcargvtest_runme.lua
new file mode 100644
index 000000000..7f213665d
--- /dev/null
+++ b/Examples/test-suite/lua/argcargvtest_runme.lua
@@ -0,0 +1,26 @@
+require("import") -- the import fn
+import("argcargvtest") -- import lib
+v = argcargvtest
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+largs = {"hi", "hola", "hello"}
+assert(v.mainc(largs) == 3, "bad main typemap")
+
+targs = {"hi", "hola"}
+assert(v.mainv(targs, 1) == "hola", "bad main typemap")
+
+targs = {"hi", "hola"}
+assert(v.mainv(targs, 1) == "hola", "bad main typemap")
+
+errorVal = 0
+function try()
+ mainv("hello", 1)
+ errorVal = 1
+end
+assert(not pcall(try) and errorVal == 0, "bad main typemap")
+
+v.initializeApp(largs)
From b88fe498cab92e18ad0a7b12e5ca9a49d4ac4ec0 Mon Sep 17 00:00:00 2001
From: Erez Geva
Date: Wed, 11 May 2022 01:10:12 +0200
Subject: [PATCH 443/662] Fix argcargv.i in Perl5, Tcl, PHP Add missing type
map for type check. Add testing of argcargv.i for Perl5, Tcl, PHP and Ruby.
Signed-off-by: Erez Geva
---
.../test-suite/perl5/argcargvtest_runme.pl | 20 ++++++++++++
.../test-suite/php/argcargvtest_runme.php | 29 +++++++++++++++++
.../test-suite/ruby/argcargvtest_runme.rb | 32 +++++++++++++++++++
.../test-suite/tcl/argcargvtest_runme.tcl | 28 ++++++++++++++++
Lib/perl5/argcargv.i | 5 +++
Lib/php/argcargv.i | 4 +++
Lib/tcl/argcargv.i | 5 +++
7 files changed, 123 insertions(+)
create mode 100644 Examples/test-suite/perl5/argcargvtest_runme.pl
create mode 100644 Examples/test-suite/php/argcargvtest_runme.php
create mode 100644 Examples/test-suite/ruby/argcargvtest_runme.rb
create mode 100644 Examples/test-suite/tcl/argcargvtest_runme.tcl
diff --git a/Examples/test-suite/perl5/argcargvtest_runme.pl b/Examples/test-suite/perl5/argcargvtest_runme.pl
new file mode 100644
index 000000000..c4157ebf4
--- /dev/null
+++ b/Examples/test-suite/perl5/argcargvtest_runme.pl
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+use Test::More tests => 8;
+BEGIN { use_ok('argcargvtest') }
+require_ok('argcargvtest');
+
+my $largs = ["hi", "hola", "hello"];
+is(argcargvtest::mainc($largs), 3, "test main typemap 1");
+
+my $targs = ["hi", "hola"];
+is(argcargvtest::mainv($targs, 1), "hola", "test main typemap 2");
+
+my $errorVal = 0;
+my $ret = eval qq(argcargvtest::mainv("hello", 1); \$errorVal = 1;);
+is($ret, undef, "test main typemap 3");
+is($errorVal, 0, "test main typemap 4");
+
+is(argcargvtest::initializeApp($largs), undef, "test main typemap 5");
+
+ok(1, "done");
diff --git a/Examples/test-suite/php/argcargvtest_runme.php b/Examples/test-suite/php/argcargvtest_runme.php
new file mode 100644
index 000000000..4a675d0ed
--- /dev/null
+++ b/Examples/test-suite/php/argcargvtest_runme.php
@@ -0,0 +1,29 @@
+ e
+ $ret = 1
+end
+
+if $error == 1 or $ret != 1
+ raise RuntimeError, "bad main typemap"
+end
+
+initializeApp($largs)
diff --git a/Examples/test-suite/tcl/argcargvtest_runme.tcl b/Examples/test-suite/tcl/argcargvtest_runme.tcl
new file mode 100644
index 000000000..14c0e92cb
--- /dev/null
+++ b/Examples/test-suite/tcl/argcargvtest_runme.tcl
@@ -0,0 +1,28 @@
+if [ catch { load ./argcargvtest[info sharedlibextension] argcargvtest} err_msg ] {
+ puts stderr "Could not load shared object:\n$err_msg"
+}
+
+set largs {hi hola hello}
+if {[mainc $largs] != 3} {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+set targs {hi hola}
+if {[mainv $targs 1] != "hola"} {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+set targs " hi hola "
+if {[mainv $targs 1] != "hola"} {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+if { ! [ catch { mainv("hello", 1) } ] } {
+ puts stderr "bad main typemap"
+ exit 1
+}
+
+initializeApp $largs
diff --git a/Lib/perl5/argcargv.i b/Lib/perl5/argcargv.i
index de7b626e0..5c3968e37 100644
--- a/Lib/perl5/argcargv.i
+++ b/Lib/perl5/argcargv.i
@@ -24,6 +24,11 @@
$2[i] = NULL;
}
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ AV *av = (AV *)SvRV($input);
+ $1 = SvTYPE(av) == SVt_PVAV;
+}
+
%typemap(freearg) (int ARGC, char **ARGV) {
if ($2 != NULL) {
free((void *)$2);
diff --git a/Lib/php/argcargv.i b/Lib/php/argcargv.i
index 14b0cf2c9..15a86a942 100644
--- a/Lib/php/argcargv.i
+++ b/Lib/php/argcargv.i
@@ -33,6 +33,10 @@
$2[i] = NULL;
}
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ $1 = Z_TYPE($input) == IS_ARRAY;
+}
+
%typemap(freearg) (int ARGC, char **ARGV) {
if ($2 != NULL) {
free((void *)$2);
diff --git a/Lib/tcl/argcargv.i b/Lib/tcl/argcargv.i
index e43f2e657..bcc3dc8a9 100644
--- a/Lib/tcl/argcargv.i
+++ b/Lib/tcl/argcargv.i
@@ -21,6 +21,11 @@
$2[i] = NULL;
}
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ int len;
+ $1 = Tcl_ListObjLength(interp, $input, &len) == TCL_OK;
+}
+
%typemap(freearg) (int ARGC, char **ARGV) {
if ($2 != NULL) {
free((void *)$2);
From 0307d0732c7c7c682d2b5542475f6171d287f7a2 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 15 May 2022 18:21:59 +0100
Subject: [PATCH 444/662] Typemaps for (int ARGC, char **ARGV) fixup
The default typemap should not be in this library file - this is for
users to add in if they want C default argument support.
---
Examples/test-suite/argcargvtest.i | 2 ++
Lib/perl5/argcargv.i | 4 ----
Lib/php/argcargv.i | 4 ----
Lib/tcl/argcargv.i | 4 ----
4 files changed, 2 insertions(+), 12 deletions(-)
diff --git a/Examples/test-suite/argcargvtest.i b/Examples/test-suite/argcargvtest.i
index ed5aa0985..d87ce6871 100644
--- a/Examples/test-suite/argcargvtest.i
+++ b/Examples/test-suite/argcargvtest.i
@@ -1,8 +1,10 @@
%module argcargvtest
+#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGOCTAVE) && !defined(SWIGR) && !defined(SWIGSCILAB)
%include
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+#endif
%inline %{
diff --git a/Lib/perl5/argcargv.i b/Lib/perl5/argcargv.i
index 5c3968e37..7ab7b66b7 100644
--- a/Lib/perl5/argcargv.i
+++ b/Lib/perl5/argcargv.i
@@ -2,10 +2,6 @@
* --- Argc & Argv ---
* ------------------------------------------------------------ */
-%typemap(default) (int ARGC, char **ARGV) {
- $1 = 0; $2 = NULL;
-}
-
%typemap(in) (int ARGC, char **ARGV) {
int i;
I32 len;
diff --git a/Lib/php/argcargv.i b/Lib/php/argcargv.i
index 15a86a942..e5625c2ca 100644
--- a/Lib/php/argcargv.i
+++ b/Lib/php/argcargv.i
@@ -2,10 +2,6 @@
* --- Argc & Argv ---
* ------------------------------------------------------------ */
-%typemap(default) (int ARGC, char **ARGV) {
- $1 = 0; $2 = NULL;
-}
-
%typemap(in) (int ARGC, char **ARGV) {
int len, i;
zval *val;
diff --git a/Lib/tcl/argcargv.i b/Lib/tcl/argcargv.i
index bcc3dc8a9..0fb1c8af9 100644
--- a/Lib/tcl/argcargv.i
+++ b/Lib/tcl/argcargv.i
@@ -2,10 +2,6 @@
* --- Argc & Argv ---
* ------------------------------------------------------------ */
-%typemap(default) (int ARGC, char **ARGV) {
- $1 = 0; $2 = NULL;
-}
-
%typemap(in) (int ARGC, char **ARGV) {
int i, nitems;
Tcl_Obj **listobjv;
From e4cdf9d98fe0cfc271192b9702cca1d9bcbe4549 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 15 May 2022 18:32:53 +0100
Subject: [PATCH 445/662] argcargv.i cosmetic updates
---
Lib/lua/argcargv.i | 25 ++++++++++++-------------
Lib/perl5/argcargv.i | 2 +-
Lib/php/argcargv.i | 2 +-
Lib/python/argcargv.i | 13 +++++--------
Lib/ruby/argcargv.i | 13 +++++--------
Lib/tcl/argcargv.i | 2 +-
6 files changed, 25 insertions(+), 32 deletions(-)
diff --git a/Lib/lua/argcargv.i b/Lib/lua/argcargv.i
index 670ce4a80..376d346d8 100644
--- a/Lib/lua/argcargv.i
+++ b/Lib/lua/argcargv.i
@@ -1,17 +1,16 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
- * ------------------------------------------------------------
- *
- * Use it as follow:
- *
- * %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
- * extern int mainApp(size_t argc, const char **argv);
- *
- * then in the lua:
- *
- * args = { "arg0", "arg1" }
- * mainApp(args);
- *
+ * SWIG library containing argc and argv multi-argument typemaps
+
+ Use it as follows:
+
+ %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+ extern int mainApp(size_t argc, const char **argv);
+
+ then from lua:
+
+ args = { "arg0", "arg1" }
+ mainApp(args);
+
* ------------------------------------------------------------ */
%{
diff --git a/Lib/perl5/argcargv.i b/Lib/perl5/argcargv.i
index 7ab7b66b7..48a6047b8 100644
--- a/Lib/perl5/argcargv.i
+++ b/Lib/perl5/argcargv.i
@@ -1,5 +1,5 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
+ * SWIG library containing argc and argv multi-argument typemaps
* ------------------------------------------------------------ */
%typemap(in) (int ARGC, char **ARGV) {
diff --git a/Lib/php/argcargv.i b/Lib/php/argcargv.i
index e5625c2ca..e0093c214 100644
--- a/Lib/php/argcargv.i
+++ b/Lib/php/argcargv.i
@@ -1,5 +1,5 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
+ * SWIG library containing argc and argv multi-argument typemaps
* ------------------------------------------------------------ */
%typemap(in) (int ARGC, char **ARGV) {
diff --git a/Lib/python/argcargv.i b/Lib/python/argcargv.i
index 717fe7334..419803a81 100644
--- a/Lib/python/argcargv.i
+++ b/Lib/python/argcargv.i
@@ -1,13 +1,10 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
+ * SWIG library containing argc and argv multi-argument typemaps
* ------------------------------------------------------------ */
%fragment("SWIG_AsArgcArgv","header",fragment="SWIG_AsCharPtrAndSize") {
SWIGINTERN int
-SWIG_AsArgcArgv(PyObject *input,
- swig_type_info *ppchar_info,
- size_t *argc, char ***argv, int *owner)
-{
+SWIG_AsArgcArgv(PyObject *input, swig_type_info *ppchar_info, size_t *argc, char ***argv, int *owner) {
void *vptr;
int res = SWIG_ConvertPtr(input, &vptr, ppchar_info, 0);
if (!SWIG_IsOK(res)) {
@@ -51,7 +48,7 @@ SWIG_AsArgcArgv(PyObject *input,
} else {
/* seems dangerous, but the user asked for it... */
size_t i = 0;
- if (argv) { while (*argv[i] != 0) ++i;}
+ if (argv) { while (*argv[i] != 0) ++i;}
if (argc) *argc = i;
if (owner) *owner = 0;
return SWIG_OK;
@@ -66,10 +63,10 @@ SWIG_AsArgcArgv(PyObject *input,
%typemap(in,noblock=0,fragment="SWIG_AsArgcArgv") (int ARGC, char **ARGV) (int res,char **argv = 0, size_t argc = 0, int owner= 0) {
res = SWIG_AsArgcArgv($input, $descriptor(char**), &argc, &argv, &owner);
- if (!SWIG_IsOK(res)) {
+ if (!SWIG_IsOK(res)) {
$1 = 0; $2 = 0;
%argument_fail(SWIG_TypeError, "int ARGC, char **ARGV", $symname, $argnum);
- } else {
+ } else {
$1 = %static_cast(argc,$1_ltype);
$2 = %static_cast(argv, $2_ltype);
}
diff --git a/Lib/ruby/argcargv.i b/Lib/ruby/argcargv.i
index fc0bc406a..330221a05 100644
--- a/Lib/ruby/argcargv.i
+++ b/Lib/ruby/argcargv.i
@@ -1,21 +1,18 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
- * ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
- Use it as follow:
+ Use it as follows:
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
%inline %{
- int mainApp(size_t argc, const char **argv)
+ int mainApp(size_t argc, const char **argv)
{
return argc;
}
- then in the ruby side:
+ then from ruby:
args = ["asdf", "asdf2"]
mainApp(args);
@@ -31,7 +28,7 @@
VALUE *ptr = RARRAY_PTR($input);
for (i=0; i < size; i++, ptr++) {
$2[i]= StringValuePtr(*ptr);
- }
+ }
$2[i]=NULL;
} else {
$1 = 0; $2 = 0;
diff --git a/Lib/tcl/argcargv.i b/Lib/tcl/argcargv.i
index 0fb1c8af9..bbe149ef0 100644
--- a/Lib/tcl/argcargv.i
+++ b/Lib/tcl/argcargv.i
@@ -1,5 +1,5 @@
/* ------------------------------------------------------------
- * --- Argc & Argv ---
+ * SWIG library containing argc and argv multi-argument typemaps
* ------------------------------------------------------------ */
%typemap(in) (int ARGC, char **ARGV) {
From 6860e2bc03dc2a46de0989dc938bffe63eb0694b Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 15 May 2022 19:12:39 +0100
Subject: [PATCH 446/662] Document argc argv library
---
CHANGES.current | 6 +++++
Doc/Manual/Contents.html | 1 +
Doc/Manual/Library.html | 50 ++++++++++++++++++++++++++++++++++++----
Lib/lua/argcargv.i | 2 +-
Lib/ruby/argcargv.i | 7 +++---
5 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index f14dc24ad..3818bdf0b 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-15: erezgeva, eiselekd
+ [Lua, Perl, PHP, Tcl] #2275 #2276 Add argcargv.i library containing
+ (int ARGC, char **ARGV) multi-argument typemaps.
+
+ Document this library in Typemaps.html.
+
2022-05-04: wsfulton
[C#] Add C# wchar_t * director typemaps
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 57ef77087..dfa9f6101 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -419,6 +419,7 @@
The %include directive and library search path
C arrays and pointers
+- argcargv.i
- cpointer.i
- carrays.i
- cmalloc.i
diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html
index 0efb8fb0f..3ecfc3a39 100644
--- a/Doc/Manual/Library.html
+++ b/Doc/Manual/Library.html
@@ -14,6 +14,7 @@
- The %include directive and library search path
- C arrays and pointers
+- argcargv.i
- cpointer.i
- carrays.i
- cmalloc.i
@@ -115,7 +116,48 @@ pointers as class-like objects. Since these functions provide direct access to
memory, their use is potentially unsafe and you should exercise caution.
-
+
+
+
+
+The argcargv.i library is a simple library providing multi-argument typemaps for handling C
+argc argv command line argument C string arrays.
+The argc parameter contains the argument count and argv contains the argument vector array.
+
+
+
+This library provides the following multi-argument typemap:
+
+
+
+(int ARGC, char **ARGV)
+
+
+
+Apply this multi-argument typemap to your use case, for example:
+
+
+
+
+%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+
+int mainApp(size_t argc, const char **argv);
+
+
+
+
+then from Ruby:
+
+
+
+
+$args = ["myarg1", "myarg2"]
+mainApp(args);
+
+
+
+
+
@@ -331,7 +373,7 @@ In this example, the function int_to_uint() would be used to cast type
Note: When working with simple pointers, typemaps can often be used to provide more seamless operation.
-
+
@@ -510,7 +552,7 @@ used with types of char or char *.
SWIG's default handling of these types is to handle them as character strings and the two macros do not do enough to change this.
-
+
@@ -671,7 +713,7 @@ Now, in a script:
-
+
diff --git a/Lib/lua/argcargv.i b/Lib/lua/argcargv.i
index 376d346d8..94cc8ed42 100644
--- a/Lib/lua/argcargv.i
+++ b/Lib/lua/argcargv.i
@@ -9,7 +9,7 @@
then from lua:
args = { "arg0", "arg1" }
- mainApp(args);
+ mainApp(args)
* ------------------------------------------------------------ */
diff --git a/Lib/ruby/argcargv.i b/Lib/ruby/argcargv.i
index 330221a05..24df9c94a 100644
--- a/Lib/ruby/argcargv.i
+++ b/Lib/ruby/argcargv.i
@@ -7,15 +7,14 @@
%inline %{
- int mainApp(size_t argc, const char **argv)
- {
+ int mainApp(size_t argc, const char **argv) {
return argc;
}
then from ruby:
- args = ["asdf", "asdf2"]
- mainApp(args);
+ $args = ["asdf", "asdf2"]
+ mainApp(args)
* ------------------------------------------------------------ */
From 35ec8ca210b1db7c32a58decd219d4ec652a4cdb Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 15 May 2022 19:49:59 +0100
Subject: [PATCH 447/662] Add argcargv test case to test-suite
---
Examples/test-suite/common.mk | 1 +
.../test-suite/octave/argcargvtest_runme.m | 29 -------------------
Examples/test-suite/python/Makefile.in | 1 -
3 files changed, 1 insertion(+), 30 deletions(-)
delete mode 100644 Examples/test-suite/octave/argcargvtest_runme.m
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 57e663878..69f38113f 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -117,6 +117,7 @@ CPP_TEST_CASES += \
anonymous_bitfield \
apply_signed_char \
apply_strings \
+ argcargvtest \
argout \
array_member \
array_typedef_memberin \
diff --git a/Examples/test-suite/octave/argcargvtest_runme.m b/Examples/test-suite/octave/argcargvtest_runme.m
deleted file mode 100644
index f246dd9db..000000000
--- a/Examples/test-suite/octave/argcargvtest_runme.m
+++ /dev/null
@@ -1,29 +0,0 @@
-argcargvtest
-
-largs={'hi','hola','hello'};
-if (mainc(largs) != 3)
- error("bad main typemap");
-endif
-
-targs={'hi','hola'};
-if (mainv(targs,1) != 'hola')
- error("bad main typemap");
-endif
-
-targs={'hi', 'hola'};
-if (mainv(targs,1) != 'hola')
- error("bad main typemap");
-endif
-
-try
- error_flag = 0;
- mainv('hello',1);
- error_flag = 1;
-catch
-end_try_catch
-if (error_flag)
- error("bad main typemap")
-endif
-
-
-initializeApp(largs);
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index c061f903a..ddcd4afe9 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -20,7 +20,6 @@ top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPP_TEST_CASES += \
- argcargvtest \
callback \
complextest \
director_stl \
From 96337b266ccba153c9278f63186d8aff74662a55 Mon Sep 17 00:00:00 2001
From: Xavier Delacour
Date: Sat, 1 Mar 2008 23:35:44 +0000
Subject: [PATCH 448/662] Octave argcargvtest
---
.../test-suite/octave/argcargvtest_runme.m | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 Examples/test-suite/octave/argcargvtest_runme.m
diff --git a/Examples/test-suite/octave/argcargvtest_runme.m b/Examples/test-suite/octave/argcargvtest_runme.m
new file mode 100644
index 000000000..f246dd9db
--- /dev/null
+++ b/Examples/test-suite/octave/argcargvtest_runme.m
@@ -0,0 +1,29 @@
+argcargvtest
+
+largs={'hi','hola','hello'};
+if (mainc(largs) != 3)
+ error("bad main typemap");
+endif
+
+targs={'hi','hola'};
+if (mainv(targs,1) != 'hola')
+ error("bad main typemap");
+endif
+
+targs={'hi', 'hola'};
+if (mainv(targs,1) != 'hola')
+ error("bad main typemap");
+endif
+
+try
+ error_flag = 0;
+ mainv('hello',1);
+ error_flag = 1;
+catch
+end_try_catch
+if (error_flag)
+ error("bad main typemap")
+endif
+
+
+initializeApp(largs);
From 34221f223aef65896eb0e631a0fd2f608d98fa4e Mon Sep 17 00:00:00 2001
From: Erez Geva
Date: Sat, 21 May 2022 20:47:50 +0200
Subject: [PATCH 449/662] Add Octave argcargv.i
Signed-off-by: Erez Geva
---
Examples/test-suite/argcargvtest.i | 2 +-
Lib/octave/argcargv.i | 33 ++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 Lib/octave/argcargv.i
diff --git a/Examples/test-suite/argcargvtest.i b/Examples/test-suite/argcargvtest.i
index d87ce6871..3ba79d860 100644
--- a/Examples/test-suite/argcargvtest.i
+++ b/Examples/test-suite/argcargvtest.i
@@ -1,6 +1,6 @@
%module argcargvtest
-#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGOCTAVE) && !defined(SWIGR) && !defined(SWIGSCILAB)
+#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGR) && !defined(SWIGSCILAB)
%include
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
diff --git a/Lib/octave/argcargv.i b/Lib/octave/argcargv.i
new file mode 100644
index 000000000..3da37a9a5
--- /dev/null
+++ b/Lib/octave/argcargv.i
@@ -0,0 +1,33 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%typemap(in) (int ARGC, char **ARGV) {
+ if ($input.is_scalar_type()) {
+ $1 = 0; $2 = NULL;
+ %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' is not a list", $symname, $argnum);
+ }
+ octave_value_list list = $input.list_value();
+ int i, len = list.length();
+ $1 = ($1_ltype) len;
+ $2 = (char **) malloc((len+1)*sizeof(char *));
+ for (i = 0; i < len; i++) {
+ if(!list(i).is_string()) {
+ $1 = 0;
+ %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' use a non-string", $symname, $argnum);
+ }
+ $2[i] = (char *)list(i).string_value().c_str();
+ }
+ $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ const octave_value& ov = $input;
+ $1 = !ov.is_scalar_type();
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ if ($2 != NULL) {
+ free((void *)$2);
+ }
+}
From c359f57442ce5dbdd373442855fe1992a7e0b764 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 23 May 2022 08:50:38 +0100
Subject: [PATCH 450/662] Better Octave typecheck for argc argv typemaps
---
Lib/octave/argcargv.i | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/Lib/octave/argcargv.i b/Lib/octave/argcargv.i
index 3da37a9a5..8d455e586 100644
--- a/Lib/octave/argcargv.i
+++ b/Lib/octave/argcargv.i
@@ -4,15 +4,15 @@
%typemap(in) (int ARGC, char **ARGV) {
if ($input.is_scalar_type()) {
- $1 = 0; $2 = NULL;
- %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' is not a list", $symname, $argnum);
+ $1 = 0; $2 = NULL;
+ %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' is not a list", $symname, $argnum);
}
octave_value_list list = $input.list_value();
int i, len = list.length();
$1 = ($1_ltype) len;
$2 = (char **) malloc((len+1)*sizeof(char *));
for (i = 0; i < len; i++) {
- if(!list(i).is_string()) {
+ if (!list(i).is_string()) {
$1 = 0;
%argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' use a non-string", $symname, $argnum);
}
@@ -22,8 +22,19 @@
}
%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ $1 = 0;
const octave_value& ov = $input;
- $1 = !ov.is_scalar_type();
+ if (!ov.is_scalar_type()) {
+ octave_value_list list = ov.list_value();
+ int i, len = list.length();
+ $1 = 1;
+ for (i = 0; i < len; i++) {
+ if (!list(i).is_string()) {
+ $1 = 0;
+ break;
+ }
+ }
+ }
}
%typemap(freearg) (int ARGC, char **ARGV) {
From d5d58918661312857b3cd5985d9b46463cad21cc Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 23 May 2022 08:54:40 +0100
Subject: [PATCH 451/662] Remove ocaml from argcargv testing
---
Examples/test-suite/argcargvtest.i | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Examples/test-suite/argcargvtest.i b/Examples/test-suite/argcargvtest.i
index 3ba79d860..5711441d9 100644
--- a/Examples/test-suite/argcargvtest.i
+++ b/Examples/test-suite/argcargvtest.i
@@ -1,6 +1,6 @@
%module argcargvtest
-#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGR) && !defined(SWIGSCILAB)
+#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGOCAML) && !defined(SWIGR) && !defined(SWIGSCILAB)
%include
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
From 1ad77e8c9b955dfbf4c7b48890dcf49278b1e422 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 23 May 2022 08:59:13 +0100
Subject: [PATCH 452/662] Add octave argc argv to readme file
---
CHANGES.current | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGES.current b/CHANGES.current
index 32ccc4fc9..4a3bd7d98 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -8,7 +8,7 @@ Version 4.1.0 (in progress)
===========================
2022-05-15: erezgeva, eiselekd
- [Lua, Perl, PHP, Tcl] #2275 #2276 Add argcargv.i library containing
+ [Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing
(int ARGC, char **ARGV) multi-argument typemaps.
Document this library in Typemaps.html.
From b58c554cdee28b1c79ad8a097da63751a237faee Mon Sep 17 00:00:00 2001
From: Joachim Kuebart
Date: Fri, 13 Aug 2021 17:26:57 +0200
Subject: [PATCH 453/662] Java: Option to detach from the JVM in the thread
destructor.
---
CHANGES.current | 10 ++++++++++
Lib/java/director.swg | 28 +++++++++++++++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/CHANGES.current b/CHANGES.current
index 4a3bd7d98..9d804f53b 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,16 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-23: jkuebart
+ [Java] On some versions of Android, specifically Android 6,
+ detaching the current thread from the JVM after every invocation
+ causes a memory leak.
+
+ Offer SWIG_JAVA_DETACH_ON_THREAD_END to configure a behaviour
+ where the JVM is only detached in the thread destructor.
+
+ See https://developer.android.com/training/articles/perf-jni#threads.
+
2022-05-15: erezgeva, eiselekd
[Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing
(int ARGC, char **ARGV) multi-argument typemaps.
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index e911a3da7..f7c4f2d8a 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -51,6 +51,22 @@ SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
#endif
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+#include
+namespace {
+
+ void detach(void* jvm) {
+ static_cast(jvm)->DetachCurrentThread();
+ }
+
+ pthread_key_t detachKey;
+ void makeDetachKey() {
+ pthread_key_create(&detachKey, detach);
+ }
+
+}
+#endif
+
namespace Swig {
/* Java object wrapper */
@@ -201,9 +217,19 @@ namespace Swig {
#else
director_->swig_jvm_->AttachCurrentThread(jenv, &args);
#endif
+
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+ // At least on Android 6, detaching after every call causes a memory leak.
+ // Instead, register a thread desructor and detach only when the thread ends.
+ // See https://developer.android.com/training/articles/perf-jni#threads
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+ pthread_once(&once, makeDetachKey);
+ pthread_setspecific(detachKey, director->swig_jvm_);
+#endif
}
~JNIEnvWrapper() {
-#if !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
+#if !defined(SWIG_JAVA_DETACH_ON_THREAD_END) && !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
// Some JVMs, eg jdk-1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call.
// However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak.
if (env_status == JNI_EDETACHED)
From 36dc81808bc5c5e98ad78142b60a4268125a378e Mon Sep 17 00:00:00 2001
From: Joachim Kuebart
Date: Tue, 24 May 2022 14:34:09 +0200
Subject: [PATCH 454/662] Java: Move auxiliary methods into JObjectWrapper.
---
Lib/java/director.swg | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index f7c4f2d8a..70f4c561c 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -53,18 +53,6 @@ SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
#include
-namespace {
-
- void detach(void* jvm) {
- static_cast(jvm)->DetachCurrentThread();
- }
-
- pthread_key_t detachKey;
- void makeDetachKey() {
- pthread_key_create(&detachKey, detach);
- }
-
-}
#endif
namespace Swig {
@@ -149,6 +137,19 @@ namespace Swig {
}
}
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+ static void detach(void* jvm) {
+ static_cast(jvm)->DetachCurrentThread();
+ }
+
+ static void makeDetachKey() {
+ pthread_key_create(&detach_key_, detach);
+ }
+
+ /* thread-local key to register a destructor */
+ static pthread_key_t detach_key_;
+#endif
+
private:
/* pointer to Java object */
jobject jthis_;
@@ -156,6 +157,10 @@ namespace Swig {
bool weak_global_;
};
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+ pthread_key_t JObjectWrapper::detach_key_;
+#endif
+
/* Local JNI reference deleter */
class LocalRefGuard {
JNIEnv *jenv_;
@@ -224,8 +229,8 @@ namespace Swig {
// See https://developer.android.com/training/articles/perf-jni#threads
static pthread_once_t once = PTHREAD_ONCE_INIT;
- pthread_once(&once, makeDetachKey);
- pthread_setspecific(detachKey, director->swig_jvm_);
+ pthread_once(&once, JObjectWrapper::makeDetachKey);
+ pthread_setspecific(JObjectWrapper::detach_key_, director->swig_jvm_);
#endif
}
~JNIEnvWrapper() {
From 34a27359ae44b4f694c1c7ff4c33f18094526ba9 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Thu, 26 May 2022 08:44:51 +0100
Subject: [PATCH 455/662] Final tidy up for improved C#
SwigDerviedClassHasMethod implementation
---
CHANGES.current | 4 ++++
Examples/test-suite/csharp/director_basic_runme.cs | 2 +-
Examples/test-suite/director_basic.i | 5 +++--
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 4a3bd7d98..e2f9d9ff0 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-26: rokups
+ [C#] #1323 Modify SwigDerivedClassHasMethod for a more efficient director
+ implementation when calling virtual methods that are not overidden.
+
2022-05-15: erezgeva, eiselekd
[Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing
(int ARGC, char **ARGV) multi-argument typemaps.
diff --git a/Examples/test-suite/csharp/director_basic_runme.cs b/Examples/test-suite/csharp/director_basic_runme.cs
index de299b145..a81f27ef3 100644
--- a/Examples/test-suite/csharp/director_basic_runme.cs
+++ b/Examples/test-suite/csharp/director_basic_runme.cs
@@ -50,7 +50,7 @@ public class runme
myNewBar.x = 10;
// Low level implementation check
-// my.testSwigDerivedClassHasMethod();
+ my.testSwigDerivedClassHasMethod();
// These should not call the C# implementations as they are not overridden
int v;
diff --git a/Examples/test-suite/director_basic.i b/Examples/test-suite/director_basic.i
index 23d910324..abb1a3d13 100644
--- a/Examples/test-suite/director_basic.i
+++ b/Examples/test-suite/director_basic.i
@@ -71,11 +71,12 @@
%}
%typemap(cscode) MyClass %{
+ // low level implementation check for checking MyOverriddenClass
public void testSwigDerivedClassHasMethod() {
if (SwigDerivedClassHasMethod("nonVirtual", swigMethodTypes3))
- throw new global::System.Exception("non-overriding non-virtual method would be when connecting director");
+ throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding non-virtual method (nonVirtual)");
if (SwigDerivedClassHasMethod("nonOverride", swigMethodTypes4))
- throw new global::System.Exception("non-overriding virtual method would be when connecting director");
+ throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding method (nonOverride)");
}
%}
From abc8e0bb277f7a54ff4ee209845dde910d267819 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 27 May 2022 18:58:04 +0100
Subject: [PATCH 456/662] Define PY_SSIZE_T_CLEAN macro
before #include "Python.h" as recommended in Python 3.7 and later.
Issue #2277
---
CHANGES.current | 11 +++++++++++
Lib/python/embed.i | 2 +-
Lib/python/pyruntime.swg | 2 +-
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index a8975a03f..a950b930f 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,17 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-27: xypron
+ [Python] #2277 Define PY_SSIZE_T_CLEAN macro before #include "Python.h" as
+ recommended in Python 3.7 and later.
+
+ To avoid this macro definition, add the following to your interface file so
+ that SWIG_NO_PY_SSIZE_T_CLEAN is defined at the beginning of the C++ wrappers:
+
+ %begin %{
+ #define SWIG_NO_PY_SSIZE_T_CLEAN
+ %}
+
2022-05-07: KrisThielemans
[Python] Fix "too many initializers for 'PyHeapTypeObject'" errors
using PyPy 3.8 and later.
diff --git a/Lib/python/embed.i b/Lib/python/embed.i
index 95225e2de..34cb9b92a 100644
--- a/Lib/python/embed.i
+++ b/Lib/python/embed.i
@@ -29,7 +29,7 @@ As far as I know, this module is C++ safe.
#endif
%wrapper %{
-#ifndef PY_SSIZE_T_CLEAN
+#ifndef SWIG_NO_PY_SSIZE_T_CLEAN
#define PY_SSIZE_T_CLEAN
#endif
#include
diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg
index 9b516ebaa..b1033dfbc 100644
--- a/Lib/python/pyruntime.swg
+++ b/Lib/python/pyruntime.swg
@@ -11,7 +11,7 @@
# include
#endif
-#ifndef PY_SSIZE_T_CLEAN
+#ifndef SWIG_NO_PY_SSIZE_T_CLEAN
#define PY_SSIZE_T_CLEAN
#endif
#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
From 8e3f0fd793afc17d293ee9533030b05e43548661 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 27 May 2022 20:01:57 +0100
Subject: [PATCH 457/662] Suppress -Wregister gcc warnings in Python.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Such as:
/usr/include/python2.7/unicodeobject.h:534:24: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
Closes #2227
---
Lib/python/embed.i | 12 ++++++++++++
Lib/python/pyruntime.swg | 12 ++++++++++++
2 files changed, 24 insertions(+)
diff --git a/Lib/python/embed.i b/Lib/python/embed.i
index 34cb9b92a..505dd9b57 100644
--- a/Lib/python/embed.i
+++ b/Lib/python/embed.i
@@ -32,8 +32,20 @@ As far as I know, this module is C++ safe.
#ifndef SWIG_NO_PY_SSIZE_T_CLEAN
#define PY_SSIZE_T_CLEAN
#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus) && __cplusplus >=201703L
+#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */
+#endif
+#endif
+
#include
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
+
#ifdef __cplusplus
extern "C"
#endif
diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg
index b1033dfbc..74669a74f 100644
--- a/Lib/python/pyruntime.swg
+++ b/Lib/python/pyruntime.swg
@@ -14,6 +14,14 @@
#ifndef SWIG_NO_PY_SSIZE_T_CLEAN
#define PY_SSIZE_T_CLEAN
#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus) && __cplusplus >=201703L
+#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */
+#endif
+#endif
+
#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
/* Use debug wrappers with the Python release dll */
# undef _DEBUG
@@ -22,6 +30,10 @@
#else
# include
#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
%}
%insert(runtime) "swigrun.swg"; /* SWIG API */
From aef97a57833410ca521360437b78d315029bfabc Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 28 May 2022 10:22:34 +0100
Subject: [PATCH 458/662] Cosmetic tidyup in SWIG_JAVA_DETACH_ON_THREAD_END
code
---
Lib/java/director.swg | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index 70f4c561c..536513557 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -138,11 +138,11 @@ namespace Swig {
}
#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
- static void detach(void* jvm) {
- static_cast(jvm)->DetachCurrentThread();
+ static void detach(void *jvm) {
+ static_cast(jvm)->DetachCurrentThread();
}
- static void makeDetachKey() {
+ static void make_detach_key() {
pthread_key_create(&detach_key_, detach);
}
@@ -229,7 +229,7 @@ namespace Swig {
// See https://developer.android.com/training/articles/perf-jni#threads
static pthread_once_t once = PTHREAD_ONCE_INIT;
- pthread_once(&once, JObjectWrapper::makeDetachKey);
+ pthread_once(&once, JObjectWrapper::make_detach_key);
pthread_setspecific(JObjectWrapper::detach_key_, director->swig_jvm_);
#endif
}
From 62e0685df61bd636cb101eb58a27e0e14074b0c2 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 30 May 2022 19:00:04 +0100
Subject: [PATCH 459/662] Test and document imfuncname special variable
expansion
---
CHANGES.current | 4 ++++
Doc/Manual/Java.html | 3 ++-
.../java/java_typemaps_proxy_runme.java | 9 +++++++++
Examples/test-suite/java_typemaps_proxy.i | 17 +++++++++++++++++
4 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/CHANGES.current b/CHANGES.current
index 46c567a02..95114d3f6 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-30: LindleyF
+ [Java] #2042 Add new special variable expansion: $imfuncname.
+ Expands to the function name called in the intermediary class.
+
2022-02-02: olly
[Ruby] https://sourceforge.net/p/swig/bugs/1136/ Fix remove of prefix
from method name to only remove it at the start.
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html
index 03e3c9124..4a4b1750f 100644
--- a/Doc/Manual/Java.html
+++ b/Doc/Manual/Java.html
@@ -6441,7 +6441,8 @@ unless the jniclassname attribute is specified in the
diff --git a/Examples/test-suite/java/java_typemaps_proxy_runme.java b/Examples/test-suite/java/java_typemaps_proxy_runme.java
index 67a083114..0caeb1c65 100644
--- a/Examples/test-suite/java/java_typemaps_proxy_runme.java
+++ b/Examples/test-suite/java/java_typemaps_proxy_runme.java
@@ -76,6 +76,15 @@ public class java_typemaps_proxy_runme {
java_typemaps_proxyJNI.Without_member_method(nullPtr, nullPtr);
java_typemaps_proxyJNI.delete_Without(nullPtr);
java_typemaps_proxyJNI.global_method_without(nullPtr);
+
+ // $imfuncname substitution
+ ProxyA pa = new ProxyA();
+ if (pa.imfuncname_test() != 123)
+ throw new RuntimeException("imfuncname_test is not 123");
+ if (ProxyA.imfuncname_static_test() != 234)
+ throw new RuntimeException("imfuncname_test is not 234");
+ if (java_typemaps_proxy.imfuncname_global_test() != 345)
+ throw new RuntimeException("imfuncname_test is not 345");
}
}
diff --git a/Examples/test-suite/java_typemaps_proxy.i b/Examples/test-suite/java_typemaps_proxy.i
index 3e9b18335..b20dd385b 100644
--- a/Examples/test-suite/java_typemaps_proxy.i
+++ b/Examples/test-suite/java_typemaps_proxy.i
@@ -127,3 +127,20 @@ void global_method_constwithout(const ConstWithout *p) {}
%}
+// $imfuncname substitution
+%typemap(javaout) int imfuncname_test {
+ return $moduleJNI.$imfuncname(swigCPtr, this) + 123;
+ }
+%typemap(javaout) int imfuncname_static_test {
+ return $moduleJNI.$imfuncname() + 234;
+ }
+%typemap(javaout) int imfuncname_global_test {
+ return $moduleJNI.$imfuncname() + 345;
+ }
+%inline %{
+struct ProxyA {
+ int imfuncname_test() { return 0; }
+ static int imfuncname_static_test() { return 0; }
+};
+int imfuncname_global_test() { return 0; }
+%}
From 954f29b032dfc0ef04e4b0ef0871b04a30068b6b Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 30 May 2022 19:43:04 +0100
Subject: [PATCH 460/662] Add special variable imfuncname expansion for C# and
D
Same functionality as Java
---
CHANGES.current | 4 ++
Doc/Manual/CSharp.html | 6 +++
Doc/Manual/D.html | 6 +++
.../csharp/csharp_typemaps_runme.cs | 16 ++++++++
Examples/test-suite/csharp_typemaps.i | 39 +++++++++++++++++++
Source/Modules/csharp.cxx | 6 +++
Source/Modules/d.cxx | 2 +
7 files changed, 79 insertions(+)
diff --git a/CHANGES.current b/CHANGES.current
index 95114d3f6..5e496424c 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-05-30: wsfulton
+ [C#, D] Add new special variable expansion: $imfuncname.
+ Expands to the function name called in the intermediary class.
+
2022-05-30: LindleyF
[Java] #2042 Add new special variable expansion: $imfuncname.
Expands to the function name called in the intermediary class.
diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html
index fe8f7c4bd..405868b5c 100644
--- a/Doc/Manual/CSharp.html
+++ b/Doc/Manual/CSharp.html
@@ -550,6 +550,12 @@ This special variable expands to the intermediary class name. For C# this is usu
unless the imclassname attribute is specified in the %module directive.
+
+$imfuncname
+This special variable expands to the name of the function in the intermediary class that will be used in $imcall.
+Like, $imcall, this special variable is only expanded in the "csout", "csvarin" and "csvarout" typemaps.
+
+
The directory Examples/csharp has a number of simple examples.
Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C#
diff --git a/Doc/Manual/D.html b/Doc/Manual/D.html
index f9f2d53ca..99ee027a1 100644
--- a/Doc/Manual/D.html
+++ b/Doc/Manual/D.html
@@ -267,6 +267,12 @@ SomeClass bar() {
+
$imfuncname
+
+This special variable expands to the name of the function in the intermediary class that will be used in $imcall.
+Like, $imcall, this special variable is only expanded in the "dout" typemap.
+
+
$importtype(SomeDType)
This macro is used in the dimports typemap if a dependency on another D type generated by SWIG is added by a custom typemap.
diff --git a/Examples/test-suite/csharp/csharp_typemaps_runme.cs b/Examples/test-suite/csharp/csharp_typemaps_runme.cs
index 846644f09..a9119a0c3 100644
--- a/Examples/test-suite/csharp/csharp_typemaps_runme.cs
+++ b/Examples/test-suite/csharp/csharp_typemaps_runme.cs
@@ -107,6 +107,22 @@ public class TestThread {
Console.Error.WriteLine("Test failed (thread " + threadId + "): " + e.Message);
Failed = true;
}
+
+ // $imfuncname substitution
+ ProxyA pa = new ProxyA();
+ if (pa.imfuncname_test() != 123)
+ throw new ApplicationException("imfuncname_test is not 123");
+ if (ProxyA.imfuncname_static_test() != 234)
+ throw new ApplicationException("imfuncname_test is not 234");
+ if (csharp_typemaps.imfuncname_global_test() != 345)
+ throw new ApplicationException("imfuncname_test is not 345");
+
+ pa.variab = 1000;
+ if (pa.variab != 1000 + 111 + 222)
+ throw new ApplicationException("pa.variab is not 1333");
+ csharp_typemaps.global_variab = 1000;
+ if (csharp_typemaps.global_variab != 1000 + 333 + 444)
+ throw new ApplicationException("csharp_typemaps.variab is not 1777");
}
}
diff --git a/Examples/test-suite/csharp_typemaps.i b/Examples/test-suite/csharp_typemaps.i
index dc5b40c02..a73f01c44 100644
--- a/Examples/test-suite/csharp_typemaps.i
+++ b/Examples/test-suite/csharp_typemaps.i
@@ -136,3 +136,42 @@ namespace Glob {
bool MVar::svar = false;
%}
+// $imfuncname substitution
+%typemap(csout) int imfuncname_test {
+ return $modulePINVOKE.$imfuncname(swigCPtr) + 123;
+ }
+%typemap(csout) int imfuncname_static_test {
+ return $modulePINVOKE.$imfuncname() + 234;
+ }
+%typemap(csout) int imfuncname_global_test {
+ return $modulePINVOKE.$imfuncname() + 345;
+ }
+
+%typemap(csvarout, excode=SWIGEXCODE2) int variab %{
+ get {
+ int ret = $modulePINVOKE.$imfuncname(swigCPtr) + 222;$excode
+ return ret;
+ } %}
+%typemap(csvarin, excode=SWIGEXCODE2) int variab %{
+ set {
+ $modulePINVOKE.$imfuncname(swigCPtr, value + 111);$excode
+ } %}
+
+%typemap(csvarout, excode=SWIGEXCODE2) int global_variab %{
+ get {
+ int ret = $modulePINVOKE.$imfuncname() + 333;$excode
+ return ret;
+ } %}
+%typemap(csvarin, excode=SWIGEXCODE2) int global_variab %{
+ set {
+ $modulePINVOKE.$imfuncname(value + 444);$excode
+ } %}
+%inline %{
+struct ProxyA {
+ int imfuncname_test() { return 0; }
+ static int imfuncname_static_test() { return 0; }
+ int variab;
+};
+int imfuncname_global_test() { return 0; }
+int global_variab;
+%}
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index edb79e13e..f2f48d707 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -2572,6 +2572,7 @@ public:
} else {
Replaceall(imcall, "$imfuncname", intermediary_function_name);
}
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -2615,6 +2616,7 @@ public:
if ((tm = Swig_typemap_lookup("csvarin", variable_parm, "", 0))) {
substituteClassname(cvariable_type, tm);
Replaceall(tm, "$csinput", "value");
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarin", variable_parm);
Printf(proxy_class_code, "%s", tm);
@@ -2629,6 +2631,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarout", n);
Printf(proxy_class_code, "%s", tm);
@@ -3141,6 +3144,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -3179,6 +3183,7 @@ public:
if ((tm = Getattr(p, "tmap:csvarin"))) {
substituteClassname(pt, tm);
Replaceall(tm, "$csinput", "value");
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarin", p);
Printf(module_class_code, "%s", tm);
@@ -3193,6 +3198,7 @@ public:
else
Replaceall(tm, "$owner", "false");
substituteClassname(t, tm);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
excodeSubstitute(n, tm, "csvarout", n);
Printf(module_class_code, "%s", tm);
diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx
index b7283eac2..9d716f433 100644
--- a/Source/Modules/d.cxx
+++ b/Source/Modules/d.cxx
@@ -2898,6 +2898,7 @@ private:
} else {
Replaceall(imcall, "$imfuncname", intermediary_function_name);
}
+ Replaceall(tm, "$imfuncname", intermediary_function_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
@@ -3100,6 +3101,7 @@ private:
else
Replaceall(tm, "$owner", "false");
replaceClassname(tm, t);
+ Replaceall(tm, "$imfuncname", overloaded_name);
Replaceall(tm, "$imcall", imcall);
} else {
Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
From 5afc8138427080f0fc9973afd645d1b2bdf5f3d8 Mon Sep 17 00:00:00 2001
From: Seth R Johnson
Date: Thu, 2 Jun 2022 18:29:56 -0400
Subject: [PATCH 461/662] Fix whitespace and memory leak
---
Source/Swig/typemap.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index 8e2657583..c66b93ee6 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -537,24 +537,24 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) {
Replace(nkey, "tmap:", "", DOH_REPLACE_ANY);
Setattr(deferred_add, nkey, sm1);
}
- Delete(nkey);
}
+ Delete(nkey);
}
}
/* After assembling the key/item pairs, add the resulting typemaps */
for (ki = First(deferred_add); ki.key; ki = Next(ki)) {
- Hash *sm1 = ki.item;
- String *src_str = ParmList_str_multibrackets(src);
- String *dest_str = ParmList_str_multibrackets(dest);
- String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
+ Hash *sm1 = ki.item;
+ String *src_str = ParmList_str_multibrackets(src);
+ String *dest_str = ParmList_str_multibrackets(dest);
+ String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
- typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive);
+ typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive);
- Delete(source_directive);
- Delete(dest_str);
- Delete(src_str);
- }
+ Delete(source_directive);
+ Delete(dest_str);
+ Delete(src_str);
+ }
Delete(deferred_add);
}
Delete(ssig);
From 28036e5a16028a13aa2715274ca1425408438d17 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 1 Jun 2022 22:11:18 +0100
Subject: [PATCH 462/662] Documentation for attribute support in $typemap.
---
CHANGES.current | 19 +++++++++++++++++++
Doc/Manual/Contents.html | 1 +
Doc/Manual/Typemaps.html | 36 ++++++++++++++++++++++++++++++++----
3 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 68f7daa54..35b0f7ee2 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,25 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-06-04: sethrj
+ Enhance $typemap to support typemap attributes.
+
+ $typemap(method:attribute, typepattern)
+
+ For example:
+
+ %typemap(cstype, out="object") XClass "XClass"
+ %typemap(cscode) BarClass %{
+ $typemap(cstype:out, XClass) bar() {
+ return null;
+ }
+
+ which expands to
+
+ object bar() {
+ return null;
+ }
+
2022-05-30: wsfulton
[C#, D] Add new special variable expansion: $imfuncname.
Expands to the function name called in the intermediary class.
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index dfa9f6101..6f48360fd 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -524,6 +524,7 @@
Special variables and typemap attributes
Special variables combined with special variable macros
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
index 614c446e7..28f9d51ad 100644
--- a/Doc/Manual/Typemaps.html
+++ b/Doc/Manual/Typemaps.html
@@ -48,6 +48,7 @@
Special variables and typemap attributes
Special variables combined with special variable macros
@@ -2457,13 +2458,40 @@ The result is the following expansion
+
+
+
-The first argument, the typemap method, can look up the attribute of a
-typemap by appending a colon and the keyword. For example,
-$typemap(directorin:descriptor, $type) would be replaced by "D" if type is a double.
+An enhanced version of $typemap provides access to typemap attributes by
+appending a colon and the attribute name after the method name. In the example below,
+"cstype" is the typemap method and "out" is the typemap attribute.
+
+
+
+%typemap(cstype, out="object") XClass "XClass"
+%typemap(cscode) BarClass %{
+ $typemap(cstype:out, XClass) bar()
+ {
+ return null;
+ }
+
+
-New in SWIG 4.1.
+which expands to
+
+
+
+ object bar()
+ {
+ return null;
+ }
+
+
+
+
+Compatibility note: Support for typemap attributes in $typemap
+was introduced in SWIG-4.1.0.
From 6254de05efbb7e8969b0507ebc84b675a35d93ee Mon Sep 17 00:00:00 2001
From: Seth R Johnson
Date: Fri, 3 Jun 2022 06:50:25 -0400
Subject: [PATCH 463/662] Avoid emitting locals duiring keyword typemap lookup
---
Source/Swig/typemap.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index c66b93ee6..2f9c06000 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -2101,8 +2101,9 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
}
found_colon = Strchr(tmap_method, ':');
if (found_colon) {
+ /* Substitute from a keyword argument to a typemap. Avoid emitting local variables from the attached typemap by passing NULL for the file. */
String *temp_tmap_method = NewStringWithSize(Char(tmap_method), found_colon - Char(tmap_method));
- Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, f);
+ Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, NULL);
Delete(temp_tmap_method);
} else {
Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
From a1b45a8333621c671bef178929c2b1c4f6950069 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Wed, 8 Jun 2022 13:00:53 +1200
Subject: [PATCH 464/662] [php] Add runme.php for two more testcases
---
.../php/director_exception_catches_runme.php | 26 +++++++++++++++++++
.../php/director_exception_nothrow_runme.php | 23 ++++++++++++++++
2 files changed, 49 insertions(+)
create mode 100644 Examples/test-suite/php/director_exception_catches_runme.php
create mode 100644 Examples/test-suite/php/director_exception_nothrow_runme.php
diff --git a/Examples/test-suite/php/director_exception_catches_runme.php b/Examples/test-suite/php/director_exception_catches_runme.php
new file mode 100644
index 000000000..51c5663d5
--- /dev/null
+++ b/Examples/test-suite/php/director_exception_catches_runme.php
@@ -0,0 +1,26 @@
+getMessage(), "Testing exception thrown in description()", "Unexpected exception message: ".$e->getMessage());
+}
+
+check::done();
diff --git a/Examples/test-suite/php/director_exception_nothrow_runme.php b/Examples/test-suite/php/director_exception_nothrow_runme.php
new file mode 100644
index 000000000..2bc4a0c4a
--- /dev/null
+++ b/Examples/test-suite/php/director_exception_nothrow_runme.php
@@ -0,0 +1,23 @@
+pang(), "MyBar::pang()", "MyBar::pang() not called as expected");
+$b = new Bar();
+check::equal($b->pang(), "Bar::pang()", "Bar::pang() not called as expected");
+
+check::done();
From 97a109ecc9bc6f6cd8575b052d753ad78c2b96bd Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Wed, 8 Jun 2022 17:41:00 +1200
Subject: [PATCH 465/662] WIP: Refactor pararent class tracking
---
Source/Modules/php.cxx | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index d61f6e428..72a2508f1 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -63,6 +63,7 @@ static String *pragma_phpinfo;
static String *pragma_version;
static String *class_name = NULL;
+static String *base_class = NULL;
static String *destructor_action = NULL;
static String *magic_set = NULL;
static String *magic_get = NULL;
@@ -923,9 +924,10 @@ public:
return n && Getattr(n, "classtype") != NULL;
}
- void generate_magic_property_methods(Node *class_node, String *base_class) {
- if (Equal(base_class, "Exception") || !is_class_wrapped(base_class)) {
- base_class = NULL;
+ void generate_magic_property_methods(Node *class_node) {
+ String *swig_base = base_class;
+ if (Equal(swig_base, "Exception") || !is_class_wrapped(swig_base)) {
+ swig_base = NULL;
}
static bool generated_magic_arginfo = false;
@@ -976,8 +978,8 @@ public:
"}\n", NIL);
}
Printf(f->code, "} else {\n");
- if (base_class) {
- Printf(f->code, "PHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class);
+ if (swig_base) {
+ Printf(f->code, "PHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
} else {
Printf(f->code, "add_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n}\n");
}
@@ -1008,8 +1010,8 @@ public:
Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
Printf(f->code, "if(arg->newobject) {\nRETVAL_LONG(1);\n}\nelse {\nRETVAL_LONG(0);\n}\n}\n\n");
Printf(f->code, "else {\n");
- if (base_class) {
- Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class);
+ if (swig_base) {
+ Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
} else {
// __get is only called if the property isn't set on the zend_object.
Printf(f->code, "RETVAL_NULL();\n}\n");
@@ -1041,8 +1043,8 @@ public:
Append(f->code, magic_isset);
}
Printf(f->code, "else {\n");
- if (base_class) {
- Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, base_class);
+ if (swig_base) {
+ Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
} else {
// __isset is only called if the property isn't set on the zend_object.
Printf(f->code, "RETVAL_FALSE;\n}\n");
@@ -1586,9 +1588,9 @@ public:
virtual int classHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
- String *base_class = NULL;
class_name = symname;
+ base_class = NULL;
destructor_action = NULL;
Printf(all_cs_entry, "static const zend_function_entry class_%s_functions[] = {\n", class_name);
@@ -1799,10 +1801,11 @@ public:
Printf(s_oinit, "#endif\n");
Printf(s_oinit, "\n");
- generate_magic_property_methods(n, base_class);
+ generate_magic_property_methods(n);
Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
class_name = NULL;
+ base_class = NULL;
return SWIG_OK;
}
From d7ed1a8b97cb0c4e3c27167a85d165990f15ca31 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 9 Jun 2022 09:06:12 +1200
Subject: [PATCH 466/662] [php] Eliminate sprintf to temp buffer to create ZVAL
Use zend_strpprintf() which handles this more cleanly without risk of
buffer overflow and without a fixed length limit.
---
Lib/php/php.swg | 16 ++++------------
Lib/php/typemaps.i | 24 ++++++------------------
Source/Modules/php.cxx | 4 +---
3 files changed, 11 insertions(+), 33 deletions(-)
diff --git a/Lib/php/php.swg b/Lib/php/php.swg
index bf388a75a..ffcffde70 100644
--- a/Lib/php/php.swg
+++ b/Lib/php/php.swg
@@ -240,9 +240,7 @@
if ((long long)LONG_MIN <= $1 && $1 <= (long long)LONG_MAX) {
RETVAL_LONG((long)($1));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)$1);
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)$1));
}
%}
%typemap(out, phptype="int|string") unsigned long long
@@ -250,9 +248,7 @@
if ($1 <= (unsigned long long)LONG_MAX) {
RETVAL_LONG((long)($1));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)$1);
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)$1));
}
%}
@@ -286,9 +282,7 @@
if ((long long)LONG_MIN <= *$1 && *$1 <= (long long)LONG_MAX) {
RETVAL_LONG((long)(*$1));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)(*$1));
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)(*$1)));
}
%}
%typemap(out, phptype="int|string") const unsigned long long &
@@ -296,9 +290,7 @@
if (*$1 <= (unsigned long long)LONG_MAX) {
RETVAL_LONG((long)(*$1));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)(*$1));
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)(*$1)));
}
%}
diff --git a/Lib/php/typemaps.i b/Lib/php/typemaps.i
index 321b1202c..2f7819097 100644
--- a/Lib/php/typemaps.i
+++ b/Lib/php/typemaps.i
@@ -122,9 +122,7 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= temp$argnum && temp$argnum <= (long long)LONG_MAX) {
ZVAL_LONG(&o, (long)temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)temp$argnum);
- ZVAL_STRING(&o, temp);
+ ZVAL_NEW_STR(&o, zend_strpprintf(0, "%lld", (long long)temp$argnum));
}
t_output_helper($result, &o);
}
@@ -138,9 +136,7 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= lvalue$argnum && lvalue$argnum <= (long long)LONG_MAX) {
ZVAL_LONG(&$arg, (long)temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)lvalue$argnum);
- ZVAL_STRING(&$arg, temp);
+ ZVAL_NEW_STR(&$arg, zend_strpprintf(0, "%lld", (long long)lvalue$argnum));
}
%}
%typemap(argout) long long &OUTPUT
@@ -148,9 +144,7 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= *arg$argnum && *arg$argnum <= (long long)LONG_MAX) {
ZVAL_LONG($result, (long)(*arg$argnum));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)(*arg$argnum));
- ZVAL_STRING($result, temp);
+ ZVAL_NEW_STR($result, zend_strpprintf(0, "%lld", (long long)(*arg$argnum)));
}
%}
@@ -161,9 +155,7 @@ INT_TYPEMAP(unsigned long long);
if (temp$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG(&o, temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)temp$argnum);
- ZVAL_STRING(&o, temp);
+ ZVAL_NEW_STR(&o, zend_strpprintf(0, "%llu", (unsigned long long)temp$argnum));
}
t_output_helper($result, &o);
}
@@ -177,9 +169,7 @@ INT_TYPEMAP(unsigned long long);
if (lvalue$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG($arg, (long)(lvalue$argnum));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)lvalue$argnum);
- ZVAL_STRING((*$arg), temp);
+ ZVAL_NEW_STR((*$arg), zend_strpprintf(0, "%llu", (unsigned long long)lvalue$argnum));
}
%}
%typemap(argout) unsigned long long &OUTPUT
@@ -187,9 +177,7 @@ INT_TYPEMAP(unsigned long long);
if (*arg$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG($result, (long)(*arg$argnum));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)(*arg$argnum));
- ZVAL_STRING($result, temp);
+ ZVAL_NEW_STR($result, zend_strpprintf(0, "%llu", (unsigned long long)(*arg$argnum)));
}
%}
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 72a2508f1..56152712d 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -151,14 +151,12 @@ static void SwigPHP_emit_pointer_type_registrations() {
Printf(s_wrappers, "static int swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
Append(s_wrappers, "#endif\n");
Printf(s_wrappers, " if (type == IS_STRING) {\n");
- Printf(s_wrappers, " char buf[80];\n");
Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n");
Printf(s_wrappers, " swig_object_wrapper *obj = SWIG_Z_FETCH_OBJ_P(z);\n");
Append(s_wrappers, "#else\n");
Printf(s_wrappers, " swig_object_wrapper *obj = swig_php_fetch_object(zobj);\n");
Append(s_wrappers, "#endif\n");
- Printv(s_wrappers, " sprintf(buf, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject);\n", NIL);
- Printf(s_wrappers, " ZVAL_STRING(retval, buf);\n");
+ Printv(s_wrappers, " ZVAL_NEW_STR(retval, zend_strpprintf(0, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject));\n", NIL);
Printf(s_wrappers, " return SUCCESS;\n");
Printf(s_wrappers, " }\n");
Printf(s_wrappers, " return FAILURE;\n");
From a8994d418648372d0fb3dda579783d154ae6ec9d Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 9 Jun 2022 12:49:30 +1200
Subject: [PATCH 467/662] Rename zend_types to be clearer
It's actually tracking pointer types which aren't wrapped as classes.
---
Source/Modules/php.cxx | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 56152712d..7b4d823fa 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -102,7 +102,7 @@ static String *swig_wrapped_interface_ce() {
static Hash *arginfo_used;
/* Track non-class pointer types we need to to wrap */
-static Hash *zend_types = 0;
+static Hash *raw_pointer_types = 0;
static int shadow = 1;
@@ -124,10 +124,10 @@ extern "C" {
}
static void SwigPHP_emit_pointer_type_registrations() {
- if (!zend_types)
+ if (!raw_pointer_types)
return;
- Iterator ki = First(zend_types);
+ Iterator ki = First(raw_pointer_types);
if (!ki.key)
return;
@@ -2381,9 +2381,9 @@ void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute
// fails at runtime and the error isn't very helpful). We could
// check the condition
//
- // zend_types && Getattr(zend_types, SwigType_manglestr(type))
+ // raw_pointer_types && Getattr(raw_pointer_types, SwigType_manglestr(type))
//
- // except that zend_types may not have been fully filled in when
+ // except that raw_pointer_types may not have been fully filled in when
// we are called.
Append(merge_list, NewStringf("SWIG\\%s", SwigType_manglestr(type)));
}
@@ -2402,10 +2402,10 @@ extern "C" {
static void typetrace(const SwigType *ty, String *mangled, String *clientdata) {
if (maininstance->classLookup(ty) == NULL) {
// a non-class pointer
- if (!zend_types) {
- zend_types = NewHash();
+ if (!raw_pointer_types) {
+ raw_pointer_types = NewHash();
}
- Setattr(zend_types, mangled, mangled);
+ Setattr(raw_pointer_types, mangled, mangled);
}
if (r_prevtracefunc)
(*r_prevtracefunc) (ty, mangled, clientdata);
From a277748870199ccdc63b852369fcd07625bf0c20 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 9 Jun 2022 14:39:51 +1200
Subject: [PATCH 468/662] Fix PHP parameter type declarations compatibility
Ensure PHP parameter type declarations are compatible with those for
the same method in any classes we inherit from.
See #2151
---
.../test-suite/php/director_classes_runme.php | 79 +++++++++++++
Source/Modules/php.cxx | 111 ++++++++++++------
2 files changed, 156 insertions(+), 34 deletions(-)
create mode 100644 Examples/test-suite/php/director_classes_runme.php
diff --git a/Examples/test-suite/php/director_classes_runme.php b/Examples/test-suite/php/director_classes_runme.php
new file mode 100644
index 000000000..6a1d8a557
--- /dev/null
+++ b/Examples/test-suite/php/director_classes_runme.php
@@ -0,0 +1,79 @@
+set($base);
+ $dh = new DoubleHolder(444.555);
+ check::equal($caller->ValCall($dh)->val, $dh->val, "$bname.Val");
+ check::equal($caller->RefCall($dh)->val, $dh->val, "$bname.Ref");
+ check::equal($caller->PtrCall($dh)->val, $dh->val, "$bname.Ptr");
+ check::equal($caller->ConstPtrRefCall($dh)->val, $dh->val, "$bname.ConstPtrRef");
+ check::equal($caller->FullyOverloadedCall(1),
+ "${bname}::FullyOverloaded(int)",
+ "$bname.FullyOverloaded(int)");
+ check::equal($caller->FullyOverloadedCall(false),
+ "${bname}::FullyOverloaded(bool)",
+ "$bname.FullyOverloaded(bool)");
+ // This next one is TODO for Perl with PerlDerived.
+ check::equal($caller->SemiOverloadedCall(-678),
+ "${bname}::SemiOverloaded(int)",
+ "$bname.SemiOverloaded(int)");
+ check::equal($caller->SemiOverloadedCall(false),
+ "Base::SemiOverloaded(bool)",
+ "$bname.SemiOverloaded(bool)");
+ check::equal($caller->DefaultParmsCall(10, 2.2),
+ "${bname}::DefaultParms(int, double)",
+ "$bname.DefaultParms(int, double)");
+ check::equal($caller->DefaultParmsCall(10),
+ "${bname}::DefaultParms(int)",
+ "$bname.DefaultParms(int)");
+ $caller->reset();
+}
+
+check::done();
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 7b4d823fa..71e196b1e 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -185,10 +185,27 @@ static void SwigPHP_emit_pointer_type_registrations() {
}
}
+static Hash *create_php_type_flags() {
+ Hash *h = NewHash();
+ Setattr(h, "array", "MAY_BE_ARRAY");
+ Setattr(h, "bool", "MAY_BE_BOOL");
+ Setattr(h, "callable", "MAY_BE_CALLABLE");
+ Setattr(h, "float", "MAY_BE_DOUBLE");
+ Setattr(h, "int", "MAY_BE_LONG");
+ Setattr(h, "iterable", "MAY_BE_ITERABLE");
+ Setattr(h, "mixed", "MAY_BE_MIXED");
+ Setattr(h, "null", "MAY_BE_NULL");
+ Setattr(h, "object", "MAY_BE_OBJECT");
+ Setattr(h, "resource", "MAY_BE_RESOURCE");
+ Setattr(h, "string", "MAY_BE_STRING");
+ Setattr(h, "void", "MAY_BE_VOID");
+ return h;
+}
+
+static Hash *php_type_flags = create_php_type_flags();
+
// Class encapsulating the machinery to add PHP type declarations.
class PHPTypes {
- Hash *phptypes;
-
// List with an entry for each parameter and one for the return type.
//
// We assemble the types in here before emitting them so for an overloaded
@@ -201,26 +218,14 @@ class PHPTypes {
List *byref;
public:
- PHPTypes() : phptypes(NewHash()), merged_types(NULL), byref(NULL) {
- Setattr(phptypes, "array", "MAY_BE_ARRAY");
- Setattr(phptypes, "bool", "MAY_BE_BOOL");
- Setattr(phptypes, "callable", "MAY_BE_CALLABLE");
- Setattr(phptypes, "float", "MAY_BE_DOUBLE");
- Setattr(phptypes, "int", "MAY_BE_LONG");
- Setattr(phptypes, "iterable", "MAY_BE_ITERABLE");
- Setattr(phptypes, "mixed", "MAY_BE_MIXED");
- Setattr(phptypes, "null", "MAY_BE_NULL");
- Setattr(phptypes, "object", "MAY_BE_OBJECT");
- Setattr(phptypes, "resource", "MAY_BE_RESOURCE");
- Setattr(phptypes, "string", "MAY_BE_STRING");
- Setattr(phptypes, "void", "MAY_BE_VOID");
- }
+ PHPTypes() : merged_types(NewList()), byref(NULL) { }
- void reset() {
+ PHPTypes(const PHPTypes *o)
+ : merged_types(Copy(o->merged_types)), byref(Copy(o->byref)) { }
+
+ ~PHPTypes() {
Delete(merged_types);
- merged_types = NewList();
Delete(byref);
- byref = NULL;
}
// key is 0 for return type, or >= 1 for parameters numbered from 1
@@ -238,7 +243,7 @@ public:
// Skip duplicates when merging.
continue;
}
- String *c = Getattr(phptypes, i.item);
+ String *c = Getattr(php_type_flags, i.item);
if (c) {
if (Len(result) > 0) Append(result, "|");
Append(result, c);
@@ -272,9 +277,18 @@ public:
}
};
-class PHP : public Language {
- PHPTypes phptypes;
+static PHPTypes *phptypes = NULL;
+// Track if the current phptypes is for a non-class function.
+static PHPTypes *non_class_phptypes = NULL;
+
+// class + ":" + method -> PHPTypes*
+static Hash *all_phptypes = NewHash();
+
+// php_class_name -> php_parent_class_name
+static Hash *php_parent_class = NewHash();
+
+class PHP : public Language {
public:
PHP() {
director_language = 1;
@@ -728,7 +742,7 @@ public:
// it inherits from is directed, which is what we care about here.
// Using (!is_member_director(n)) would get it wrong for testcase
// director_frob.
- out_phptype = phptypes.get_phptype(0, out_phpclasses);
+ out_phptype = phptypes->get_phptype(0, out_phpclasses);
}
}
@@ -763,17 +777,17 @@ public:
String *phpclasses = NewStringEmpty();
String *phptype = NULL;
if (GetFlag(n, "feature:php:type")) {
- phptype = phptypes.get_phptype(param_count, phpclasses);
+ phptype = phptypes->get_phptype(param_count, phpclasses);
}
int byref;
if (!dispatch) {
byref = GetFlag(p, "tmap:in:byref");
- if (byref) phptypes.set_byref(param_count);
+ if (byref) phptypes->set_byref(param_count);
} else {
// If any overload takes a particular parameter by reference then the
// dispatch function also needs to take that parameter by reference.
- byref = phptypes.get_byref(param_count);
+ byref = phptypes->get_byref(param_count);
}
// FIXME: Should we be doing byref for return value as well?
@@ -1141,12 +1155,6 @@ public:
return SWIG_ERROR;
}
- if (!Getattr(n, "sym:previousSibling")) {
- // First function of an overloaded group or a function which isn't part
- // of a group so reset the phptype information.
- phptypes.reset();
- }
-
if (constructor) {
wname = NewString("__construct");
} else if (wrapperType == membervar) {
@@ -1197,6 +1205,40 @@ public:
return SWIG_OK;
}
+ if (!Getattr(n, "sym:previousSibling")) {
+ // First function of an overloaded group or a function which isn't part
+ // of a group so reset the phptype information.
+ if (non_class_phptypes) {
+ delete non_class_phptypes;
+ non_class_phptypes = NULL;
+ }
+ phptypes = NULL;
+
+ if (class_name) {
+ // See if there's a parent class which implements this method, and if
+ // so copy the PHPTypes of that method as a starting point as we need
+ // to be compatible with it (whether it is virtual or not).
+ String *parent = class_name;
+ while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+ String *key = NewStringf("%s:%s", parent, wname);
+ PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key);
+ Delete(key);
+ if (p) {
+ phptypes = new PHPTypes(p);
+ break;
+ }
+ }
+ }
+ if (!phptypes) {
+ phptypes = new PHPTypes();
+ }
+ if (class_name) {
+ SetVoid(all_phptypes, NewStringf("%s:%s", class_name, wname), phptypes);
+ } else {
+ non_class_phptypes = phptypes;
+ }
+ }
+
f = NewWrapper();
if (static_getter) {
@@ -1313,7 +1355,7 @@ public:
continue;
}
- phptypes.process_phptype(p, i + 1, "tmap:in:phptype");
+ phptypes->process_phptype(p, i + 1, "tmap:in:phptype");
String *source = NewStringf("args[%d]", i);
Replaceall(tm, "$input", source);
@@ -1399,7 +1441,7 @@ public:
}
emit_return_variable(n, d, f);
- phptypes.process_phptype(n, 0, "tmap:out:phptype");
+ phptypes->process_phptype(n, 0, "tmap:out:phptype");
if (outarg) {
Printv(f->code, outarg, NIL);
@@ -1643,6 +1685,7 @@ public:
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
} else if (is_class_wrapped(base_class)) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
+ Setattr(php_parent_class, class_name, base_class);
} else {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
}
From d43d62cd7abac737bb5e8d73afa319ba579030e0 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 9 Jun 2022 17:55:09 +1200
Subject: [PATCH 469/662] Revert "Fix PHP parameter type declarations
compatibility"
I missed that this change breaks cpp_static, which seems to be to do
with handling the combined getter and setter we emit for static
member variables. Reverting while I figure out how to handle that.
This reverts commit a277748870199ccdc63b852369fcd07625bf0c20.
---
.../test-suite/php/director_classes_runme.php | 79 -------------
Source/Modules/php.cxx | 111 ++++++------------
2 files changed, 34 insertions(+), 156 deletions(-)
delete mode 100644 Examples/test-suite/php/director_classes_runme.php
diff --git a/Examples/test-suite/php/director_classes_runme.php b/Examples/test-suite/php/director_classes_runme.php
deleted file mode 100644
index 6a1d8a557..000000000
--- a/Examples/test-suite/php/director_classes_runme.php
+++ /dev/null
@@ -1,79 +0,0 @@
-set($base);
- $dh = new DoubleHolder(444.555);
- check::equal($caller->ValCall($dh)->val, $dh->val, "$bname.Val");
- check::equal($caller->RefCall($dh)->val, $dh->val, "$bname.Ref");
- check::equal($caller->PtrCall($dh)->val, $dh->val, "$bname.Ptr");
- check::equal($caller->ConstPtrRefCall($dh)->val, $dh->val, "$bname.ConstPtrRef");
- check::equal($caller->FullyOverloadedCall(1),
- "${bname}::FullyOverloaded(int)",
- "$bname.FullyOverloaded(int)");
- check::equal($caller->FullyOverloadedCall(false),
- "${bname}::FullyOverloaded(bool)",
- "$bname.FullyOverloaded(bool)");
- // This next one is TODO for Perl with PerlDerived.
- check::equal($caller->SemiOverloadedCall(-678),
- "${bname}::SemiOverloaded(int)",
- "$bname.SemiOverloaded(int)");
- check::equal($caller->SemiOverloadedCall(false),
- "Base::SemiOverloaded(bool)",
- "$bname.SemiOverloaded(bool)");
- check::equal($caller->DefaultParmsCall(10, 2.2),
- "${bname}::DefaultParms(int, double)",
- "$bname.DefaultParms(int, double)");
- check::equal($caller->DefaultParmsCall(10),
- "${bname}::DefaultParms(int)",
- "$bname.DefaultParms(int)");
- $caller->reset();
-}
-
-check::done();
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 71e196b1e..7b4d823fa 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -185,27 +185,10 @@ static void SwigPHP_emit_pointer_type_registrations() {
}
}
-static Hash *create_php_type_flags() {
- Hash *h = NewHash();
- Setattr(h, "array", "MAY_BE_ARRAY");
- Setattr(h, "bool", "MAY_BE_BOOL");
- Setattr(h, "callable", "MAY_BE_CALLABLE");
- Setattr(h, "float", "MAY_BE_DOUBLE");
- Setattr(h, "int", "MAY_BE_LONG");
- Setattr(h, "iterable", "MAY_BE_ITERABLE");
- Setattr(h, "mixed", "MAY_BE_MIXED");
- Setattr(h, "null", "MAY_BE_NULL");
- Setattr(h, "object", "MAY_BE_OBJECT");
- Setattr(h, "resource", "MAY_BE_RESOURCE");
- Setattr(h, "string", "MAY_BE_STRING");
- Setattr(h, "void", "MAY_BE_VOID");
- return h;
-}
-
-static Hash *php_type_flags = create_php_type_flags();
-
// Class encapsulating the machinery to add PHP type declarations.
class PHPTypes {
+ Hash *phptypes;
+
// List with an entry for each parameter and one for the return type.
//
// We assemble the types in here before emitting them so for an overloaded
@@ -218,14 +201,26 @@ class PHPTypes {
List *byref;
public:
- PHPTypes() : merged_types(NewList()), byref(NULL) { }
+ PHPTypes() : phptypes(NewHash()), merged_types(NULL), byref(NULL) {
+ Setattr(phptypes, "array", "MAY_BE_ARRAY");
+ Setattr(phptypes, "bool", "MAY_BE_BOOL");
+ Setattr(phptypes, "callable", "MAY_BE_CALLABLE");
+ Setattr(phptypes, "float", "MAY_BE_DOUBLE");
+ Setattr(phptypes, "int", "MAY_BE_LONG");
+ Setattr(phptypes, "iterable", "MAY_BE_ITERABLE");
+ Setattr(phptypes, "mixed", "MAY_BE_MIXED");
+ Setattr(phptypes, "null", "MAY_BE_NULL");
+ Setattr(phptypes, "object", "MAY_BE_OBJECT");
+ Setattr(phptypes, "resource", "MAY_BE_RESOURCE");
+ Setattr(phptypes, "string", "MAY_BE_STRING");
+ Setattr(phptypes, "void", "MAY_BE_VOID");
+ }
- PHPTypes(const PHPTypes *o)
- : merged_types(Copy(o->merged_types)), byref(Copy(o->byref)) { }
-
- ~PHPTypes() {
+ void reset() {
Delete(merged_types);
+ merged_types = NewList();
Delete(byref);
+ byref = NULL;
}
// key is 0 for return type, or >= 1 for parameters numbered from 1
@@ -243,7 +238,7 @@ public:
// Skip duplicates when merging.
continue;
}
- String *c = Getattr(php_type_flags, i.item);
+ String *c = Getattr(phptypes, i.item);
if (c) {
if (Len(result) > 0) Append(result, "|");
Append(result, c);
@@ -277,18 +272,9 @@ public:
}
};
-static PHPTypes *phptypes = NULL;
-
-// Track if the current phptypes is for a non-class function.
-static PHPTypes *non_class_phptypes = NULL;
-
-// class + ":" + method -> PHPTypes*
-static Hash *all_phptypes = NewHash();
-
-// php_class_name -> php_parent_class_name
-static Hash *php_parent_class = NewHash();
-
class PHP : public Language {
+ PHPTypes phptypes;
+
public:
PHP() {
director_language = 1;
@@ -742,7 +728,7 @@ public:
// it inherits from is directed, which is what we care about here.
// Using (!is_member_director(n)) would get it wrong for testcase
// director_frob.
- out_phptype = phptypes->get_phptype(0, out_phpclasses);
+ out_phptype = phptypes.get_phptype(0, out_phpclasses);
}
}
@@ -777,17 +763,17 @@ public:
String *phpclasses = NewStringEmpty();
String *phptype = NULL;
if (GetFlag(n, "feature:php:type")) {
- phptype = phptypes->get_phptype(param_count, phpclasses);
+ phptype = phptypes.get_phptype(param_count, phpclasses);
}
int byref;
if (!dispatch) {
byref = GetFlag(p, "tmap:in:byref");
- if (byref) phptypes->set_byref(param_count);
+ if (byref) phptypes.set_byref(param_count);
} else {
// If any overload takes a particular parameter by reference then the
// dispatch function also needs to take that parameter by reference.
- byref = phptypes->get_byref(param_count);
+ byref = phptypes.get_byref(param_count);
}
// FIXME: Should we be doing byref for return value as well?
@@ -1155,6 +1141,12 @@ public:
return SWIG_ERROR;
}
+ if (!Getattr(n, "sym:previousSibling")) {
+ // First function of an overloaded group or a function which isn't part
+ // of a group so reset the phptype information.
+ phptypes.reset();
+ }
+
if (constructor) {
wname = NewString("__construct");
} else if (wrapperType == membervar) {
@@ -1205,40 +1197,6 @@ public:
return SWIG_OK;
}
- if (!Getattr(n, "sym:previousSibling")) {
- // First function of an overloaded group or a function which isn't part
- // of a group so reset the phptype information.
- if (non_class_phptypes) {
- delete non_class_phptypes;
- non_class_phptypes = NULL;
- }
- phptypes = NULL;
-
- if (class_name) {
- // See if there's a parent class which implements this method, and if
- // so copy the PHPTypes of that method as a starting point as we need
- // to be compatible with it (whether it is virtual or not).
- String *parent = class_name;
- while ((parent = Getattr(php_parent_class, parent)) != NULL) {
- String *key = NewStringf("%s:%s", parent, wname);
- PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key);
- Delete(key);
- if (p) {
- phptypes = new PHPTypes(p);
- break;
- }
- }
- }
- if (!phptypes) {
- phptypes = new PHPTypes();
- }
- if (class_name) {
- SetVoid(all_phptypes, NewStringf("%s:%s", class_name, wname), phptypes);
- } else {
- non_class_phptypes = phptypes;
- }
- }
-
f = NewWrapper();
if (static_getter) {
@@ -1355,7 +1313,7 @@ public:
continue;
}
- phptypes->process_phptype(p, i + 1, "tmap:in:phptype");
+ phptypes.process_phptype(p, i + 1, "tmap:in:phptype");
String *source = NewStringf("args[%d]", i);
Replaceall(tm, "$input", source);
@@ -1441,7 +1399,7 @@ public:
}
emit_return_variable(n, d, f);
- phptypes->process_phptype(n, 0, "tmap:out:phptype");
+ phptypes.process_phptype(n, 0, "tmap:out:phptype");
if (outarg) {
Printv(f->code, outarg, NIL);
@@ -1685,7 +1643,6 @@ public:
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
} else if (is_class_wrapped(base_class)) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
- Setattr(php_parent_class, class_name, base_class);
} else {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
}
From 2de2efb0bbbd982c22db41d184404357e7b5009c Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 9 Jun 2022 14:39:51 +1200
Subject: [PATCH 470/662] Fix PHP parameter type declarations compatibility
Ensure PHP parameter type declarations are compatible with those for
the same method in any classes we inherit from.
See #2151
---
.../test-suite/php/director_classes_runme.php | 79 ++++++++++++
Source/Modules/php.cxx | 113 ++++++++++++------
2 files changed, 157 insertions(+), 35 deletions(-)
create mode 100644 Examples/test-suite/php/director_classes_runme.php
diff --git a/Examples/test-suite/php/director_classes_runme.php b/Examples/test-suite/php/director_classes_runme.php
new file mode 100644
index 000000000..6a1d8a557
--- /dev/null
+++ b/Examples/test-suite/php/director_classes_runme.php
@@ -0,0 +1,79 @@
+set($base);
+ $dh = new DoubleHolder(444.555);
+ check::equal($caller->ValCall($dh)->val, $dh->val, "$bname.Val");
+ check::equal($caller->RefCall($dh)->val, $dh->val, "$bname.Ref");
+ check::equal($caller->PtrCall($dh)->val, $dh->val, "$bname.Ptr");
+ check::equal($caller->ConstPtrRefCall($dh)->val, $dh->val, "$bname.ConstPtrRef");
+ check::equal($caller->FullyOverloadedCall(1),
+ "${bname}::FullyOverloaded(int)",
+ "$bname.FullyOverloaded(int)");
+ check::equal($caller->FullyOverloadedCall(false),
+ "${bname}::FullyOverloaded(bool)",
+ "$bname.FullyOverloaded(bool)");
+ // This next one is TODO for Perl with PerlDerived.
+ check::equal($caller->SemiOverloadedCall(-678),
+ "${bname}::SemiOverloaded(int)",
+ "$bname.SemiOverloaded(int)");
+ check::equal($caller->SemiOverloadedCall(false),
+ "Base::SemiOverloaded(bool)",
+ "$bname.SemiOverloaded(bool)");
+ check::equal($caller->DefaultParmsCall(10, 2.2),
+ "${bname}::DefaultParms(int, double)",
+ "$bname.DefaultParms(int, double)");
+ check::equal($caller->DefaultParmsCall(10),
+ "${bname}::DefaultParms(int)",
+ "$bname.DefaultParms(int)");
+ $caller->reset();
+}
+
+check::done();
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 7b4d823fa..bbdd95249 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -185,10 +185,27 @@ static void SwigPHP_emit_pointer_type_registrations() {
}
}
+static Hash *create_php_type_flags() {
+ Hash *h = NewHash();
+ Setattr(h, "array", "MAY_BE_ARRAY");
+ Setattr(h, "bool", "MAY_BE_BOOL");
+ Setattr(h, "callable", "MAY_BE_CALLABLE");
+ Setattr(h, "float", "MAY_BE_DOUBLE");
+ Setattr(h, "int", "MAY_BE_LONG");
+ Setattr(h, "iterable", "MAY_BE_ITERABLE");
+ Setattr(h, "mixed", "MAY_BE_MIXED");
+ Setattr(h, "null", "MAY_BE_NULL");
+ Setattr(h, "object", "MAY_BE_OBJECT");
+ Setattr(h, "resource", "MAY_BE_RESOURCE");
+ Setattr(h, "string", "MAY_BE_STRING");
+ Setattr(h, "void", "MAY_BE_VOID");
+ return h;
+}
+
+static Hash *php_type_flags = create_php_type_flags();
+
// Class encapsulating the machinery to add PHP type declarations.
class PHPTypes {
- Hash *phptypes;
-
// List with an entry for each parameter and one for the return type.
//
// We assemble the types in here before emitting them so for an overloaded
@@ -201,26 +218,14 @@ class PHPTypes {
List *byref;
public:
- PHPTypes() : phptypes(NewHash()), merged_types(NULL), byref(NULL) {
- Setattr(phptypes, "array", "MAY_BE_ARRAY");
- Setattr(phptypes, "bool", "MAY_BE_BOOL");
- Setattr(phptypes, "callable", "MAY_BE_CALLABLE");
- Setattr(phptypes, "float", "MAY_BE_DOUBLE");
- Setattr(phptypes, "int", "MAY_BE_LONG");
- Setattr(phptypes, "iterable", "MAY_BE_ITERABLE");
- Setattr(phptypes, "mixed", "MAY_BE_MIXED");
- Setattr(phptypes, "null", "MAY_BE_NULL");
- Setattr(phptypes, "object", "MAY_BE_OBJECT");
- Setattr(phptypes, "resource", "MAY_BE_RESOURCE");
- Setattr(phptypes, "string", "MAY_BE_STRING");
- Setattr(phptypes, "void", "MAY_BE_VOID");
- }
+ PHPTypes() : merged_types(NewList()), byref(NULL) { }
- void reset() {
+ PHPTypes(const PHPTypes *o)
+ : merged_types(Copy(o->merged_types)), byref(Copy(o->byref)) { }
+
+ ~PHPTypes() {
Delete(merged_types);
- merged_types = NewList();
Delete(byref);
- byref = NULL;
}
// key is 0 for return type, or >= 1 for parameters numbered from 1
@@ -238,7 +243,7 @@ public:
// Skip duplicates when merging.
continue;
}
- String *c = Getattr(phptypes, i.item);
+ String *c = Getattr(php_type_flags, i.item);
if (c) {
if (Len(result) > 0) Append(result, "|");
Append(result, c);
@@ -272,9 +277,18 @@ public:
}
};
-class PHP : public Language {
- PHPTypes phptypes;
+static PHPTypes *phptypes = NULL;
+// Track if the current phptypes is for a non-class function.
+static PHPTypes *non_class_phptypes = NULL;
+
+// class + ":" + method -> PHPTypes*
+static Hash *all_phptypes = NewHash();
+
+// php_class_name -> php_parent_class_name
+static Hash *php_parent_class = NewHash();
+
+class PHP : public Language {
public:
PHP() {
director_language = 1;
@@ -728,7 +742,7 @@ public:
// it inherits from is directed, which is what we care about here.
// Using (!is_member_director(n)) would get it wrong for testcase
// director_frob.
- out_phptype = phptypes.get_phptype(0, out_phpclasses);
+ out_phptype = phptypes->get_phptype(0, out_phpclasses);
}
}
@@ -763,17 +777,17 @@ public:
String *phpclasses = NewStringEmpty();
String *phptype = NULL;
if (GetFlag(n, "feature:php:type")) {
- phptype = phptypes.get_phptype(param_count, phpclasses);
+ phptype = phptypes->get_phptype(param_count, phpclasses);
}
int byref;
if (!dispatch) {
byref = GetFlag(p, "tmap:in:byref");
- if (byref) phptypes.set_byref(param_count);
+ if (byref) phptypes->set_byref(param_count);
} else {
// If any overload takes a particular parameter by reference then the
// dispatch function also needs to take that parameter by reference.
- byref = phptypes.get_byref(param_count);
+ byref = phptypes->get_byref(param_count);
}
// FIXME: Should we be doing byref for return value as well?
@@ -1141,12 +1155,6 @@ public:
return SWIG_ERROR;
}
- if (!Getattr(n, "sym:previousSibling")) {
- // First function of an overloaded group or a function which isn't part
- // of a group so reset the phptype information.
- phptypes.reset();
- }
-
if (constructor) {
wname = NewString("__construct");
} else if (wrapperType == membervar) {
@@ -1197,6 +1205,40 @@ public:
return SWIG_OK;
}
+ if (!Getattr(n, "sym:previousSibling") && !static_getter) {
+ // First function of an overloaded group or a function which isn't part
+ // of a group so reset the phptype information.
+ if (non_class_phptypes) {
+ delete non_class_phptypes;
+ non_class_phptypes = NULL;
+ }
+ phptypes = NULL;
+
+ if (class_name) {
+ // See if there's a parent class which implements this method, and if
+ // so copy the PHPTypes of that method as a starting point as we need
+ // to be compatible with it (whether it is virtual or not).
+ String *parent = class_name;
+ while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+ String *key = NewStringf("%s:%s", parent, wname);
+ PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key);
+ Delete(key);
+ if (p) {
+ phptypes = new PHPTypes(p);
+ break;
+ }
+ }
+ }
+ if (!phptypes) {
+ phptypes = new PHPTypes();
+ }
+ if (class_name) {
+ SetVoid(all_phptypes, NewStringf("%s:%s", class_name, wname), phptypes);
+ } else {
+ non_class_phptypes = phptypes;
+ }
+ }
+
f = NewWrapper();
if (static_getter) {
@@ -1313,7 +1355,7 @@ public:
continue;
}
- phptypes.process_phptype(p, i + 1, "tmap:in:phptype");
+ phptypes->process_phptype(p, i + 1, "tmap:in:phptype");
String *source = NewStringf("args[%d]", i);
Replaceall(tm, "$input", source);
@@ -1399,7 +1441,7 @@ public:
}
emit_return_variable(n, d, f);
- phptypes.process_phptype(n, 0, "tmap:out:phptype");
+ phptypes->process_phptype(n, 0, "tmap:out:phptype");
if (outarg) {
Printv(f->code, outarg, NIL);
@@ -1450,7 +1492,7 @@ public:
dispatchFunction(n, constructor);
}
} else {
- if (!static_getter) {
+ if (!static_setter) {
create_command(class_name, wname, n, false, modes);
}
}
@@ -1643,6 +1685,7 @@ public:
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
} else if (is_class_wrapped(base_class)) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
+ Setattr(php_parent_class, class_name, base_class);
} else {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
}
From 14df91f8a0e47ce403593b6571c5fa935d1be3cf Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Fri, 10 Jun 2022 12:01:23 +1200
Subject: [PATCH 471/662] Fix new director_classes_runme.php for PHP7
---
.../test-suite/php/director_classes_runme.php | 75 +++++++++++++------
1 file changed, 53 insertions(+), 22 deletions(-)
diff --git a/Examples/test-suite/php/director_classes_runme.php b/Examples/test-suite/php/director_classes_runme.php
index 6a1d8a557..0901107f7 100644
--- a/Examples/test-suite/php/director_classes_runme.php
+++ b/Examples/test-suite/php/director_classes_runme.php
@@ -8,30 +8,61 @@ check::classes(array('director_classes', 'Base', 'BaseClass', 'Caller', 'Derived
// New vars
check::globals(array('PrintDebug'));
-class PHPDerived extends Base {
- function Val(DoubleHolder $x) { return $x; }
- function Ref(DoubleHolder $x) { return $x; }
- function Ptr(?DoubleHolder $x) { var_dump($x); return $x; }
- function ConstPtrRef(?DoubleHolder $x) { return $x; }
- function FullyOverloaded($x) {
- $rv = parent::FullyOverloaded($x);
- $rv = preg_replace('/Base/', 'PHPDerived', $rv);
- return $rv;
- }
- function SemiOverloaded($x) {
- # this is going to be awkward because we can't really
- # semi-overload in PHP, but we can sort of fake it.
- if (!is_int($x)) {
- return parent::SemiOverloaded($x);
+if (PHP_MAJOR_VERSION < 8) {
+ // Without type declarations since we don't generate them for PHP < 8
+ // and we need to be compatible with method declarations in Base.
+ class PHPDerived extends Base {
+ function Val($x) { return $x; }
+ function Ref($x) { return $x; }
+ function Ptr($x) { var_dump($x); return $x; }
+ function ConstPtrRef($x) { return $x; }
+ function FullyOverloaded($x) {
+ $rv = parent::FullyOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function SemiOverloaded($x) {
+ # this is going to be awkward because we can't really
+ # semi-overload in PHP, but we can sort of fake it.
+ if (!is_int($x)) {
+ return parent::SemiOverloaded($x);
+ }
+ $rv = parent::SemiOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function DefaultParms($x, $y = 1.1) {
+ $rv = parent::DefaultParms($x, $y);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
}
- $rv = parent::SemiOverloaded($x);
- $rv = preg_replace('/Base/', 'PHPDerived', $rv);
- return $rv;
}
- function DefaultParms(int $x, float $y = 1.1) {
- $rv = parent::DefaultParms($x, $y);
- $rv = preg_replace('/Base/', 'PHPDerived', $rv);
- return $rv;
+} else {
+ class PHPDerived extends Base {
+ function Val(DoubleHolder $x) { return $x; }
+ function Ref(DoubleHolder $x) { return $x; }
+ function Ptr(?DoubleHolder $x) { var_dump($x); return $x; }
+ function ConstPtrRef(?DoubleHolder $x) { return $x; }
+ function FullyOverloaded($x) {
+ $rv = parent::FullyOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function SemiOverloaded($x) {
+ # this is going to be awkward because we can't really
+ # semi-overload in PHP, but we can sort of fake it.
+ if (!is_int($x)) {
+ return parent::SemiOverloaded($x);
+ }
+ $rv = parent::SemiOverloaded($x);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
+ function DefaultParms(int $x, float $y = 1.1) {
+ $rv = parent::DefaultParms($x, $y);
+ $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+ return $rv;
+ }
}
}
From b7f82d78e924d24aa79b27bbdba51c88c7f596ca Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Fri, 10 Jun 2022 13:38:00 +1200
Subject: [PATCH 472/662] Fix director_classes_runme.php for PHP 7.0
PHP 7.0 fails to parse `?` before a parameter type (meaning Nullable in
newer versions), so just omit these parameter type declarations in
the testcase until we drop PHP 7.0 support.
Also drop some `var_dump($x);` left over from debugging this testcase.
---
Examples/test-suite/php/director_classes_runme.php | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/Examples/test-suite/php/director_classes_runme.php b/Examples/test-suite/php/director_classes_runme.php
index 0901107f7..f50544024 100644
--- a/Examples/test-suite/php/director_classes_runme.php
+++ b/Examples/test-suite/php/director_classes_runme.php
@@ -14,7 +14,7 @@ if (PHP_MAJOR_VERSION < 8) {
class PHPDerived extends Base {
function Val($x) { return $x; }
function Ref($x) { return $x; }
- function Ptr($x) { var_dump($x); return $x; }
+ function Ptr($x) { return $x; }
function ConstPtrRef($x) { return $x; }
function FullyOverloaded($x) {
$rv = parent::FullyOverloaded($x);
@@ -41,8 +41,12 @@ if (PHP_MAJOR_VERSION < 8) {
class PHPDerived extends Base {
function Val(DoubleHolder $x) { return $x; }
function Ref(DoubleHolder $x) { return $x; }
- function Ptr(?DoubleHolder $x) { var_dump($x); return $x; }
- function ConstPtrRef(?DoubleHolder $x) { return $x; }
+ // PHP 7.0 fails to parse the `?` - revert once we drop 7.0 support:
+ // function Ptr(?DoubleHolder $x) { return $x; }
+ function Ptr($x) { return $x; }
+ // PHP 7.0 fails to parse the `?` - revert once we drop 7.0 support:
+ // function ConstPtrRef(?DoubleHolder $x) { return $x; }
+ function ConstPtrRef($x) { return $x; }
function FullyOverloaded($x) {
$rv = parent::FullyOverloaded($x);
$rv = preg_replace('/Base/', 'PHPDerived', $rv);
From 2df27036b71ef1fbb3b6a701450fa3e06a18381b Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 9 Jun 2022 17:42:21 +1200
Subject: [PATCH 473/662] [php] Skip directorout typemap if PHP exception
pending
Otherwise can end up with a second PHP exception if the directorout
typemap doesn't accept PHP Null. `SWIG_fail` in this case results
in us returning to PHP which then propagates the pending exception.
This commit fixes a failure in smoketest.php in Xapian's PHP bindings,
but I've not managed to come up with a reproducer which works for
SWIG's testsuite.
---
Source/Modules/php.cxx | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index bbdd95249..faf4fe070 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -2249,11 +2249,13 @@ public:
if (tm)
tm = Copy(tm);
}
- if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
- Replaceall(tm, "$error", "EG(exception)");
- Printv(w->code, Str(tm), "\n", NIL);
+ if (!tm || Len(tm) == 0 || Equal(tm, "1")) {
+ // Skip marshalling the return value as there isn't one.
+ tm = NewString("if ($error) SWIG_fail;");
}
- Append(w->code, "}\n");
+
+ Replaceall(tm, "$error", "EG(exception)");
+ Printv(w->code, Str(tm), "\n}\n{\n", NIL);
Delete(tm);
/* marshal return value from PHP to C/C++ type */
@@ -2301,6 +2303,8 @@ public:
}
}
+ Append(w->code, "}\n");
+
Delete(cleanup);
Delete(outarg);
}
From c95df57976f0d64392565b1ce06496a7fc12f9fe Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Sun, 12 Jun 2022 09:22:27 +1200
Subject: [PATCH 474/662] [php] Fix missing parameter type declarations
In some cases of overloaded functions the parameter type information was
missing for some or all parameters.
See #2151
---
.../test-suite/php/default_args_runme.php | 141 ++++++++++++++++++
Source/Modules/php.cxx | 41 ++---
2 files changed, 154 insertions(+), 28 deletions(-)
create mode 100644 Examples/test-suite/php/default_args_runme.php
diff --git a/Examples/test-suite/php/default_args_runme.php b/Examples/test-suite/php/default_args_runme.php
new file mode 100644
index 000000000..944426e29
--- /dev/null
+++ b/Examples/test-suite/php/default_args_runme.php
@@ -0,0 +1,141 @@
+blah(), true, "EnumClass::blah() default arguments don't work");
+
+$de = new DerivedEnumClass();
+$de->accelerate();
+$de->accelerate(EnumClass::SLOW);
+
+check::equal(Statics::staticMethod(), 60, "Statics::staticMethod()");
+
+check::equal(cfunc1(1), 2.0, "cfunc1(1)");
+
+check::equal(cfunc2(1), 3.0, "cfunc2(1)");
+
+check::equal(cfunc3(1), 4.0, "cfunc3(1)");
+
+$f = new Foo();
+
+$f->newname();
+$f->newname(1);
+$f->defaulted1();
+$f->defaulted2();
+
+check::equal($f->double_if_void_ptr_is_null(2, Null), 4, "\$f->double_if_void_ptr_is_null(2, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(3), 6, "\$f->double_if_void_ptr_is_null(3)");
+
+check::equal($f->double_if_void_ptr_is_null(4, Null), 8, "\$f->double_if_void_ptr_is_null(4, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(5, Null), 10, "\$f->double_if_void_ptr_is_null(5, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(6, Null), 12, "\$f->double_if_void_ptr_is_null(6, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(7), 14, "\$f->double_if_void_ptr_is_null(7)");
+
+try {
+ $f = new Foo(1);
+ check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+ $f = new Foo(1, 2);
+ check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+ $f = new Foo(1, 2, 3);
+ check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+ $m = $f->meth(1);
+ check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+try {
+ $m = $f->meth(1, 2);
+ check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+try {
+ $m = $f->meth(1, 2, 3);
+ check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+check::equal(Klass::inc(100, new Klass(22))->val, 122, "Klass::inc failed");
+
+check::equal(klass::inc(100)->val, 99, "klass::inc failed");
+
+check::equal(klass::inc()->val, 0, "klass::inc failed");
+
+$tricky = new TrickyInPython();
+check::equal($tricky->value_m1(10), -1, "trickyvalue_m1 failed");
+check::equal($tricky->value_m1(10, 10), 10, "trickyvalue_m1 failed");
+check::equal($tricky->value_0xabcdef(10), 0xabcdef, "trickyvalue_0xabcdef failed");
+check::equal($tricky->value_0644(10), 420, "trickyvalue_0644 failed");
+check::equal($tricky->value_perm(10), 420, "trickyvalue_perm failed");
+check::equal($tricky->value_m01(10), -1, "trickyvalue_m01 failed");
+check::equal($tricky->booltest2(), True, "booltest2 failed");
+
+check::equal($tricky->max_32bit_int1(), 0x7FFFFFFF, "max_32bit_int1 failed");
+check::equal($tricky->min_32bit_int1(), -2147483648, "min_32bit_int1 failed");
+check::equal($tricky->max_32bit_int2(), 0x7FFFFFFF, "max_32bit_int2 failed");
+
+$tricky->too_big_32bit_int1();
+$tricky->too_small_32bit_int1();
+$tricky->too_big_32bit_int2();
+$tricky->too_small_32bit_int2();
+
+seek();
+seek(10);
+
+check::equal(booltest(), True, "booltest failed");
+
+check::equal(slightly_off_square(10), 102, "slightly_off_square(10)");
+
+check::equal(slightly_off_square(), 291, "slightly_off_square()");
+
+check::equal(chartest1(), "x", "chartest1()");
+
+check::equal(chartest2(), "\0", "chartest2()");
+
+check::equal(chartest3(), "\1", "chartest3()");
+
+check::equal(chartest4(), "\n", "chartest4()");
+
+check::equal(chartest5(), "B", "chartest5()");
+
+check::equal(chartest6(), "C", "chartest6()");
+
+if (PHP_MAJOR_VERSION >= 8) {
+ // Regression test for bug in initial implementation of PHP type declarations.
+ $p = (new ReflectionMethod('TrickyInPython', 'value_m1'))->getParameters();
+ // empty array in buggy version
+ check::equal(count($p), 2, "Expected 2 parameters");
+ check::equal((string)$p[0]->getType(), 'int', "Expected int parameter");
+ check::equal((string)$p[1]->getType(), 'int', "Expected int parameter");
+
+ $p = (new ReflectionMethod('EnumClass', 'blah'))->getParameters();
+ // empty array in buggy version
+ check::equal(count($p), 2, "Expected 2 parameters");
+ check::equal((string)$p[0]->getType(), 'int', "Expected int parameter");
+ check::equal((string)$p[1]->getType(), 'int', "Expected int parameter");
+}
+
+check::done();
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index faf4fe070..d0c337a6a 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -13,6 +13,7 @@
*/
#include "swigmod.h"
+#include
#include
#include
@@ -269,12 +270,19 @@ public:
while (Len(byref) <= key) {
Append(byref, None);
}
+ // If any overload takes a particular parameter by reference then the
+ // dispatch function also needs to take that parameter by reference so
+ // we can just set unconditionally here.
Setitem(byref, key, ""); // Just needs to be something != None.
}
int get_byref(int key) const {
return byref && key < Len(byref) && Getitem(byref, key) != None;
}
+
+ int size() const {
+ return std::max(Len(merged_types), Len(byref));
+ }
};
static PHPTypes *phptypes = NULL;
@@ -759,36 +767,12 @@ public:
Printf(arginfo_code, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_###, 0, 0, %d)\n", num_required);
}
- if (Getattr(n, "defaultargs")) {
- // Include parameters with default values in the arginfo.
- l = Getattr(Getattr(n, "defaultargs"), "parms");
- }
- int param_count = 0;
- for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
- String *tmap_in_numinputs = Getattr(p, "tmap:in:numinputs");
- // tmap:in:numinputs is unset for varargs, which we don't count here.
- if (!tmap_in_numinputs || Equal(tmap_in_numinputs, "0")) {
- /* Ignored parameter */
- continue;
- }
-
- ++param_count;
-
+ int phptypes_size = phptypes->size();
+ for (int param_count = 1; param_count < phptypes_size; ++param_count) {
String *phpclasses = NewStringEmpty();
- String *phptype = NULL;
- if (GetFlag(n, "feature:php:type")) {
- phptype = phptypes->get_phptype(param_count, phpclasses);
- }
+ String *phptype = phptypes->get_phptype(param_count, phpclasses);
- int byref;
- if (!dispatch) {
- byref = GetFlag(p, "tmap:in:byref");
- if (byref) phptypes->set_byref(param_count);
- } else {
- // If any overload takes a particular parameter by reference then the
- // dispatch function also needs to take that parameter by reference.
- byref = phptypes->get_byref(param_count);
- }
+ int byref = phptypes->get_byref(param_count);
// FIXME: Should we be doing byref for return value as well?
@@ -1356,6 +1340,7 @@ public:
}
phptypes->process_phptype(p, i + 1, "tmap:in:phptype");
+ if (GetFlag(p, "tmap:in:byref")) phptypes->set_byref(i + 1);
String *source = NewStringf("args[%d]", i);
Replaceall(tm, "$input", source);
From 3a84a4dd96d320cbbaa9d51bf5ebea94dc0ef6fb Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Sun, 12 Jun 2022 10:19:15 +1200
Subject: [PATCH 475/662] [php] Fix new default_args_runme.php for PHP < 7.3
---
.../test-suite/php/default_args_runme.php | 34 ++++++++++++-------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/Examples/test-suite/php/default_args_runme.php b/Examples/test-suite/php/default_args_runme.php
index 944426e29..3e3f2f31a 100644
--- a/Examples/test-suite/php/default_args_runme.php
+++ b/Examples/test-suite/php/default_args_runme.php
@@ -42,39 +42,49 @@ check::equal($f->double_if_void_ptr_is_null(6, Null), 12, "\$f->double_if_void_p
check::equal($f->double_if_void_ptr_is_null(7), 14, "\$f->double_if_void_ptr_is_null(7)");
+# For the testcases below PHP < 7.3 emits an error, while newer versions throw
+# an exception. We handle the older versions by suppressing the error with `@`,
+# then checking for the created object being Null if the PHP version is < 7.3.
+
try {
- $f = new Foo(1);
- check::fail("Foo::Foo ignore is not working");
+ @$f = new Foo(1);
+ if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
+ check::fail("Foo::Foo ignore is not working");
} catch (ArgumentCountError $e) {
}
try {
- $f = new Foo(1, 2);
- check::fail("Foo::Foo ignore is not working");
+ @$f = new Foo(1, 2);
+ if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
+ check::fail("Foo::Foo ignore is not working");
} catch (ArgumentCountError $e) {
}
try {
- $f = new Foo(1, 2, 3);
- check::fail("Foo::Foo ignore is not working");
+ @$f = new Foo(1, 2, 3);
+ if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
+ check::fail("Foo::Foo ignore is not working");
} catch (ArgumentCountError $e) {
}
try {
- $m = $f->meth(1);
- check::fail("Foo::meth ignore is not working");
+ @$m = $f->meth(1);
+ if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
+ check::fail("Foo::meth ignore is not working");
} catch (Error $e) {
}
try {
- $m = $f->meth(1, 2);
- check::fail("Foo::meth ignore is not working");
+ @$m = $f->meth(1, 2);
+ if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
+ check::fail("Foo::meth ignore is not working");
} catch (Error $e) {
}
try {
- $m = $f->meth(1, 2, 3);
- check::fail("Foo::meth ignore is not working");
+ @$m = $f->meth(1, 2, 3);
+ if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
+ check::fail("Foo::meth ignore is not working");
} catch (Error $e) {
}
From cdcb8cc9eef34001110bd9d5ebc636ca8975c747 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Sun, 12 Jun 2022 15:02:26 +1200
Subject: [PATCH 476/662] [php] Try again to fix default_args_runme.php for
PHP7
---
.../test-suite/php/default_args_runme.php | 38 ++++++++++---------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/Examples/test-suite/php/default_args_runme.php b/Examples/test-suite/php/default_args_runme.php
index 3e3f2f31a..0ace7e45a 100644
--- a/Examples/test-suite/php/default_args_runme.php
+++ b/Examples/test-suite/php/default_args_runme.php
@@ -46,48 +46,50 @@ check::equal($f->double_if_void_ptr_is_null(7), 14, "\$f->double_if_void_ptr_is_
# an exception. We handle the older versions by suppressing the error with `@`,
# then checking for the created object being Null if the PHP version is < 7.3.
+if (PHP_MAJOR_VERSION == 7) {
+ $old_error_handler = set_error_handler(function($n,$s,$f,$l){throw preg_match('/^Wrong parameter count/', $s) ? new ArgumentCountError($s) : new Error($s);});
+}
+
try {
- @$f = new Foo(1);
- if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
- check::fail("Foo::Foo ignore is not working");
+ $f = new Foo(1);
+ check::fail("Foo::Foo ignore is not working");
} catch (ArgumentCountError $e) {
}
try {
- @$f = new Foo(1, 2);
- if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
- check::fail("Foo::Foo ignore is not working");
+ $f = new Foo(1, 2);
+ check::fail("Foo::Foo ignore is not working");
} catch (ArgumentCountError $e) {
}
try {
- @$f = new Foo(1, 2, 3);
- if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
- check::fail("Foo::Foo ignore is not working");
+ $f = new Foo(1, 2, 3);
+ check::fail("Foo::Foo ignore is not working");
} catch (ArgumentCountError $e) {
}
try {
- @$m = $f->meth(1);
- if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
- check::fail("Foo::meth ignore is not working");
+ $m = $f->meth(1);
+ check::fail("Foo::meth ignore is not working");
} catch (Error $e) {
}
try {
- @$m = $f->meth(1, 2);
- if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
- check::fail("Foo::meth ignore is not working");
+ $m = $f->meth(1, 2);
+ check::fail("Foo::meth ignore is not working");
} catch (Error $e) {
}
try {
- @$m = $f->meth(1, 2, 3);
- if (!(PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION < 3 && $f === null))
- check::fail("Foo::meth ignore is not working");
+ $m = $f->meth(1, 2, 3);
+ check::fail("Foo::meth ignore is not working");
} catch (Error $e) {
}
+if (PHP_MAJOR_VERSION == 7) {
+ set_error_handler($old_error_handler);
+}
+
check::equal(Klass::inc(100, new Klass(22))->val, 122, "Klass::inc failed");
check::equal(klass::inc(100)->val, 99, "klass::inc failed");
From b41fede82715b216a97be825c87dd08dc92ef98e Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Sun, 12 Jun 2022 15:27:49 +1200
Subject: [PATCH 477/662] [php] Fix default_args_runme.php for PHP7.0
---
Examples/test-suite/php/default_args_runme.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Examples/test-suite/php/default_args_runme.php b/Examples/test-suite/php/default_args_runme.php
index 0ace7e45a..cd0ec8127 100644
--- a/Examples/test-suite/php/default_args_runme.php
+++ b/Examples/test-suite/php/default_args_runme.php
@@ -47,6 +47,10 @@ check::equal($f->double_if_void_ptr_is_null(7), 14, "\$f->double_if_void_ptr_is_
# then checking for the created object being Null if the PHP version is < 7.3.
if (PHP_MAJOR_VERSION == 7) {
+ if (PHP_MINOR_VERSION == 0) {
+ # ArgumentCountError was added in PHP 7.1.
+ class ArgumentCountError extends Error {}
+ }
$old_error_handler = set_error_handler(function($n,$s,$f,$l){throw preg_match('/^Wrong parameter count/', $s) ? new ArgumentCountError($s) : new Error($s);});
}
From 9cdf46e8c8c45bc6d1035fefa7639194e73a075a Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Sun, 12 Jun 2022 10:12:02 +1200
Subject: [PATCH 478/662] [php] Adjust #required params for subclass methods
If the same method name is implemented in a parent class then the
subclass can't have more required parameters than that or else we
get a compatibility error when the module is loaded.
The testsuite wasn't catching this problem because it was no longer
trying to load the modules for testcases without _runme.php, because
the mechanism to do that relied on there being a generated .php
wrapper, which we no longer have by default. Fix that to provide a
regression test for this fix.
See #2151
---
Examples/Makefile.in | 2 +-
Examples/test-suite/php/Makefile.in | 12 +++++-----
.../php/director_abstract_runme.php | 6 ++---
.../test-suite/php/director_stl_runme.php | 2 +-
Source/Modules/php.cxx | 22 +++++++++++++++----
5 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index d7b9a5bcf..532152e80 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -1071,7 +1071,7 @@ php_cpp: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
php_run:
- $(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});include($$argv[1]);' $(PHP_SCRIPT) $(RUNPIPE)
+ $(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});if(strlen($$argv[1]))include($$argv[1]);' '$(PHP_SCRIPT)' $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in
index c460bff28..6a2a4590b 100644
--- a/Examples/test-suite/php/Makefile.in
+++ b/Examples/test-suite/php/Makefile.in
@@ -68,18 +68,18 @@ missingtests: missingcpptests missingctests
@echo ' $(MULTI_CPP_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.multicpptest
-# Runs the testcase. Tries to run testcase_runme.php, and if that's not
-# found, runs testcase.php, except for multicpptests.
+# Runs the testcase. Tries to run testcase_runme.php, and if that's not found,
+# at least test that the module loads without errors, except for multicpptests.
run_testcase = \
if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php_run; \
- elif [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php -a ! -f $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list ]; then \
- $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php RUNTOOL='$(RUNTOOL)' php_run; \
+ elif [ ! -f $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list ]; then \
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT= RUNTOOL='$(RUNTOOL)' php_run; \
fi
-# Clean: remove the generated .php file
+# Clean: remove the generated PHP-specific files
%.clean:
- @rm -f $*.php php_$*.h
+ @rm -f php_$*.h
clean:
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' php_clean
diff --git a/Examples/test-suite/php/director_abstract_runme.php b/Examples/test-suite/php/director_abstract_runme.php
index bb424f9ea..2d9799f2f 100644
--- a/Examples/test-suite/php/director_abstract_runme.php
+++ b/Examples/test-suite/php/director_abstract_runme.php
@@ -22,19 +22,19 @@ check::equal($a->ping(), "MyFoo::ping()", "MyFoo::ping failed");
check::equal($a->pong(), "Foo::pong();MyFoo::ping()", "MyFoo::pong failed");
class MyExample1 extends Example1 {
- function Color($r, $g, $b) {
+ function Color($r, $g = NULL, $b = NULL) {
return $r;
}
}
class MyExample2 extends Example1 {
- function Color($r, $g, $b) {
+ function Color($r, $g = NULL, $b = NULL) {
return $g;
}
}
class MyExample3 extends Example1 {
- function Color($r, $g, $b) {
+ function Color($r, $g = NULL, $b = NULL) {
return $b;
}
}
diff --git a/Examples/test-suite/php/director_stl_runme.php b/Examples/test-suite/php/director_stl_runme.php
index 654251a30..031a87ae7 100644
--- a/Examples/test-suite/php/director_stl_runme.php
+++ b/Examples/test-suite/php/director_stl_runme.php
@@ -26,7 +26,7 @@ class MyFoo extends Foo {
return $v;
}
- function vsecond($v1, $v2) {
+ function vsecond($v1, $v2 = NULL) {
return $v2;
}
}
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index d0c337a6a..c424572f1 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -218,17 +218,31 @@ class PHPTypes {
// the dispatch function. If NULL, no parameters are passed by reference.
List *byref;
+ // Used to clamp the required number of parameters in the arginfo to be
+ // compatible with any parent class version of the method.
+ int required_clamp;
+
public:
- PHPTypes() : merged_types(NewList()), byref(NULL) { }
+ PHPTypes(int num_required)
+ : merged_types(NewList()),
+ byref(NULL),
+ required_clamp(num_required) { }
PHPTypes(const PHPTypes *o)
- : merged_types(Copy(o->merged_types)), byref(Copy(o->byref)) { }
+ : merged_types(Copy(o->merged_types)),
+ byref(Copy(o->byref)),
+ required_clamp(o->required_clamp) { }
~PHPTypes() {
Delete(merged_types);
Delete(byref);
}
+ int adjust_num_required(int num_required) {
+ required_clamp = std::min(num_required, required_clamp);
+ return required_clamp;
+ }
+
// key is 0 for return type, or >= 1 for parameters numbered from 1
void process_phptype(Node *n, int key, const String_or_char *attribute_name);
@@ -712,7 +726,7 @@ public:
}
}
- int num_required = emit_num_required(l);
+ int num_required = phptypes->adjust_num_required(emit_num_required(l));
// We want to only emit each different arginfo once, as that reduces the
// size of both the generated source code and the compiled extension
@@ -1214,7 +1228,7 @@ public:
}
}
if (!phptypes) {
- phptypes = new PHPTypes();
+ phptypes = new PHPTypes(emit_num_required(l));
}
if (class_name) {
SetVoid(all_phptypes, NewStringf("%s:%s", class_name, wname), phptypes);
From 9b096e65612347d8497bca39eb54f003570e8130 Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Tue, 14 Jun 2022 17:40:12 +1200
Subject: [PATCH 479/662] WIP
---
Examples/test-suite/php/Makefile.in | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in
index 6a2a4590b..9e34ccc3d 100644
--- a/Examples/test-suite/php/Makefile.in
+++ b/Examples/test-suite/php/Makefile.in
@@ -26,6 +26,13 @@ C_TEST_CASES += \
li_cdata_carrays \
multivalue \
+# These fail with PHP8 currently. Aiming to fix before 4.1 release. See #2181.
+FAILING_CPP_TESTS = \
+ director_redefined \
+ director_using_member_scopes \
+ using_composition \
+ using_extend \
+
include $(srcdir)/../common.mk
# Overridden variables here
From 088dc6e8707b45872c687c980349ece6866c0bfd Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 15 Jun 2022 08:45:29 +0100
Subject: [PATCH 480/662] Add move assignment operator to SwigValueWrapper
Closes #2039
---
CHANGES.current | 4 +
Examples/test-suite/common.mk | 1 +
.../test-suite/cpp11_move_only_valuewrapper.i | 239 ++++++++++++++++++
.../cpp11_move_only_valuewrapper_runme.cs | 25 ++
Lib/swig.swg | 4 +
5 files changed, 273 insertions(+)
create mode 100644 Examples/test-suite/cpp11_move_only_valuewrapper.i
create mode 100644 Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
diff --git a/CHANGES.current b/CHANGES.current
index 35b0f7ee2..1e06bd85b 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-06-15: wsfulton
+ #2039 Add move assignment operator to SwigValueWrapper used by the
+ valuewrapper feature.
+
2022-06-04: sethrj
Enhance $typemap to support typemap attributes.
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 69f38113f..003138010 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -597,6 +597,7 @@ CPP11_TEST_CASES += \
cpp11_initializer_list \
cpp11_initializer_list_extend \
cpp11_lambda_functions \
+ cpp11_move_only_valuewrapper \
cpp11_noexcept \
cpp11_null_pointer_constant \
cpp11_raw_string_literals \
diff --git a/Examples/test-suite/cpp11_move_only_valuewrapper.i b/Examples/test-suite/cpp11_move_only_valuewrapper.i
new file mode 100644
index 000000000..fb9f5dc31
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only_valuewrapper.i
@@ -0,0 +1,239 @@
+%module cpp11_move_only_valuewrapper
+
+/*
+ * This test case checks SwigValueWrapper and move assignment.
+ * Although not necessary, the test case was developed testing with C++98 compatibility for comparing improvements.
+ * C++11 and later is of course required for the move assignment support.
+ * C++98 is not actually necesary now as the test-suite only runs this test with compilers that support C++11 and later.
+*/
+
+%{
+#include
+#include
+using std::cout;
+using std::endl;
+
+#if __cplusplus >= 201103L
+#include
+#else
+namespace std {
+ // just something that will compile and vaguely work for when c++11 is not supported
+ template class unique_ptr {
+ T *ptr;
+ public:
+ unique_ptr(T *ptr = 0) : ptr(ptr) {}
+ unique_ptr(const unique_ptr &a) : ptr(a.ptr) { /*please look away*/ const_cast(a).ptr = 0;}
+ ~unique_ptr() { delete ptr; }
+ unique_ptr& operator=(const unique_ptr &a) {
+ if (&a != this) {
+ delete ptr;
+ ptr = a.ptr;
+ /*please look away*/ const_cast(a).ptr = 0;
+ }
+ return *this;
+ }
+ };
+}
+#endif
+%}
+
+%include
+
+%valuewrapper XXX;
+%ignore XXX::operator=;
+%catches(std::string) XXX::check_counts;
+
+%inline %{
+bool debug = false;
+struct XXX {
+ XXX(int i = 0) { if (debug) cout << "XXX(" << i << ")" << " " << this << endl; normal_constructor_count++; }
+ XXX(const XXX &other) { if (debug) cout << "XXX(const XXX &)" << " " << this << " " << &other << endl; copy_constructor_count++;}
+ XXX & operator=(const XXX &other) { if (debug) cout << "operator=(const XXX &)" << " " << this << " " << &other << endl; copy_assignment_count++; return *this; }
+#if defined(__cplusplus) && __cplusplus >= 201103L
+ XXX(XXX &&other) noexcept { if (debug) cout << "XXX(XXX &&)" << " " << this << endl; move_constructor_count++; }
+ XXX & operator=(XXX &&other) noexcept { if (debug) cout << "operator=(XXX &&)" << " " << this << endl; move_assignment_count++; return *this; }
+#endif
+ ~XXX() { if (debug) cout << "~XXX()" << " " << this << endl; destructor_count++; }
+ static int normal_constructor_count;
+ static int copy_constructor_count;
+ static int copy_assignment_count;
+ static int move_constructor_count;
+ static int move_assignment_count;
+ static int destructor_count;
+ static void reset_counts() {
+ XXX::normal_constructor_count = 0;
+ XXX::copy_constructor_count = 0;
+ XXX::copy_assignment_count = 0;
+ XXX::move_constructor_count = 0;
+ XXX::move_assignment_count = 0;
+ XXX::destructor_count = 0;
+ }
+ // Check against expected counts of constructor, assignment operators etc.
+ // Not observed during development, but compiler optimisation could change the expected values.
+ // Throws exception if not correct (use %catches to catch them)
+ static void check_counts(
+ int normal_constructor_count,
+ int copy_constructor_count,
+ int copy_assignment_count,
+ int move_constructor_count,
+ int move_assignment_count,
+ int destructor_count) {
+ bool match = (
+ normal_constructor_count == XXX::normal_constructor_count &&
+ copy_constructor_count == XXX::copy_constructor_count &&
+ copy_assignment_count == XXX::copy_assignment_count &&
+ move_constructor_count == XXX::move_constructor_count &&
+ move_assignment_count == XXX::move_assignment_count &&
+ destructor_count == XXX::destructor_count);
+ if (!match) {
+ std::stringstream ss;
+ ss << "check_counts failed" << std::endl <<
+ XXX::normal_constructor_count << " " <<
+ XXX::copy_constructor_count << " " <<
+ XXX::copy_assignment_count << " " <<
+ XXX::move_constructor_count << " " <<
+ XXX::move_assignment_count << " " <<
+ XXX::destructor_count << " " <<
+ " (actual)" << std::endl <<
+ normal_constructor_count << " " <<
+ copy_constructor_count << " " <<
+ copy_assignment_count << " " <<
+ move_constructor_count << " " <<
+ move_assignment_count << " " <<
+ destructor_count << " " <<
+ " (expected)" << std::endl;
+ throw ss.str();
+ }
+ }
+};
+
+int XXX::normal_constructor_count = 0;
+int XXX::copy_constructor_count = 0;
+int XXX::copy_assignment_count = 0;
+int XXX::move_constructor_count = 0;
+int XXX::move_assignment_count = 0;
+int XXX::destructor_count = 0;
+bool has_cplusplus11() {
+#if __cplusplus >= 201103L
+ return true;
+#else
+ return false;
+#endif
+}
+%}
+
+#if defined(SWIGCSHARP)
+%typemap(out) std::unique_ptr %{
+ if (debug) cout << "out start" << endl;
+#if __cplusplus >= 201103L
+ $result = new std::unique_ptr(std::move(static_cast&>($1)));
+#else
+ $result = new std::unique_ptr((const std::unique_ptr &)$1);
+#endif
+ if (debug) cout << "out done" << endl;
+%}
+
+std::unique_ptr makeUniqueXXX();
+void cleanup(std::unique_ptr* p);
+#endif
+
+%{
+std::unique_ptr makeUniqueXXX() {
+ if (debug) cout << "makeUniqueXXX()" << endl;
+ return std::unique_ptr(new XXX(11));
+}
+void cleanup(std::unique_ptr* p) {
+ delete p;
+}
+%}
+
+%inline %{
+XXX createXXX() {
+ if (debug) cout << "createXXX()" << endl;
+ return XXX(111);
+}
+%}
+
+
+%catches(std::string) test1;
+%catches(std::string) test2;
+%catches(std::string) test3;
+%catches(std::string) test4;
+%catches(std::string) test5;
+%catches(std::string) test6;
+
+%inline %{
+// 'unit tests' for SwigValueWrapper
+void test1() {
+ XXX::reset_counts();
+ {
+ SwigValueWrapper x;
+ x = XXX();
+ }
+#if __cplusplus >= 201103L
+ XXX::check_counts(1, 0, 0, 1, 0, 2); // was same as < c++11 counts below before move assignment operator added to SwigValueWrapper
+#else
+ XXX::check_counts(1, 1, 0, 0, 0, 2);
+#endif
+}
+void test2() {
+ XXX::reset_counts();
+ {
+ SwigValueWrapper x;
+ x = XXX();
+ x = XXX();
+ }
+#if __cplusplus >= 201103L
+ XXX::check_counts(2, 0, 0, 2, 0, 4);
+#else
+ XXX::check_counts(2, 2, 0, 0, 0, 4);
+#endif
+}
+void test3() {
+ XXX::reset_counts();
+ {
+ SwigValueWrapper x;
+ XXX a(999);
+#if __cplusplus >= 201103L
+ x = std::move(a);
+#endif
+ }
+#if __cplusplus >= 201103L
+ XXX::check_counts(1, 0, 0, 1, 0, 2);
+#endif
+}
+void test4() {
+ XXX::reset_counts();
+ {
+ SwigValueWrapper > x;
+ x = std::unique_ptr(new XXX(444));
+ }
+ XXX::check_counts(1, 0, 0, 0, 0, 1);
+}
+void test5() {
+#if __cplusplus >= 201103L
+ XXX::reset_counts();
+ {
+ SwigValueWrapper > x;
+ x = std::unique_ptr(new XXX(550));
+ std::unique_ptr x2(new XXX(555));
+ x = std::move(x2);
+ }
+ XXX::check_counts(2, 0, 0, 0, 0, 2);
+#endif
+}
+void test6() {
+#if __cplusplus >= 201103L
+ XXX::reset_counts();
+ {
+ // emulates how std::unique_ptr typemaps could be wrapped with SwigValueWrapper
+ void *ptr = 0;
+ SwigValueWrapper > x; // SWIG generated if std::unique_ptr<> definition not parsed
+ x = makeUniqueXXX(); // SWIG generated code wrapping function returning std::unique_ptr
+ ptr = new std::unique_ptr(std::move((std::unique_ptr&)x)); // 'out' typemap (move std::unique_ptr from stack to the heap), note non-const cast std::unique_tr&
+ delete (std::unique_ptr *)ptr; // Final cleanup (user needs to call this)
+ }
+ XXX::check_counts(1, 0, 0, 0, 0, 1);
+#endif
+}
+%}
diff --git a/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
new file mode 100644
index 000000000..69f788699
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
@@ -0,0 +1,25 @@
+using System;
+using cpp11_move_only_valuewrapperNamespace;
+
+public class cpp11_move_only_valuewrapper_runme {
+
+ public static void Main() {
+ XXX.reset_counts();
+ using (XXX xxx = cpp11_move_only_valuewrapper.createXXX()) {
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ XXX.check_counts(1, 1, 0, 1, 0, 3); // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+ cpp11_move_only_valuewrapper.test1();
+ cpp11_move_only_valuewrapper.test2();
+ cpp11_move_only_valuewrapper.test3();
+ cpp11_move_only_valuewrapper.test4();
+ cpp11_move_only_valuewrapper.test5();
+ cpp11_move_only_valuewrapper.test6();
+
+ // C# only test (SwigValueWrapper and custom typemaps for std::unique_ptr)
+ SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
+ cpp11_move_only_valuewrapper.cleanup(ptr);
+
+ }
+
+}
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 223d46482..9978ae9b7 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -663,6 +663,7 @@ namespace std {
#ifdef __cplusplus
%insert("runtime") %{
#ifdef __cplusplus
+#include
/* SwigValueWrapper is described in swig.swg */
template class SwigValueWrapper {
struct SwigMovePointer {
@@ -676,6 +677,9 @@ template class SwigValueWrapper {
public:
SwigValueWrapper() : pointer(0) { }
SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+#if __cplusplus >= 201103L
+ SwigValueWrapper& operator=(T&& t) { SwigMovePointer tmp(new T(std::move(t))); pointer = tmp; return *this; }
+#endif
operator T&() const { return *pointer.ptr; }
T *operator&() { return pointer.ptr; }
};%}
From 4dd285fad736c014224ef2ad25b85e17f3dce1f9 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Thu, 16 Jun 2022 07:47:44 +0100
Subject: [PATCH 481/662] Cosmetic rename SwigMovePointer -> SwigSmartPointer
This smart pointer doesn't really offer move semantics as is commonly
understood in C++11, so rename accordingly.
---
Lib/swig.swg | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 9978ae9b7..f6ba3a69f 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -653,8 +653,8 @@ namespace std {
* arg1 = Vector(1,2,3); // Assignment from a value
*
* The class offers a strong guarantee of exception safety.
- * With regards to the implementation, the private SwigMovePointer nested class is
- * a simple smart pointer with move semantics, much like std::auto_ptr.
+ * With regards to the implementation, the private SwigSmartPointer nested class is
+ * a simple smart pointer providing exception safety, much like std::auto_ptr.
*
* This wrapping technique was suggested by William Fulton and is henceforth
* known as the "Fulton Transform" :-).
@@ -666,19 +666,19 @@ namespace std {
#include
/* SwigValueWrapper is described in swig.swg */
template class SwigValueWrapper {
- struct SwigMovePointer {
+ struct SwigSmartPointer {
T *ptr;
- SwigMovePointer(T *p) : ptr(p) { }
- ~SwigMovePointer() { delete ptr; }
- SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+ SwigSmartPointer(T *p) : ptr(p) { }
+ ~SwigSmartPointer() { delete ptr; }
+ SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
} pointer;
SwigValueWrapper& operator=(const SwigValueWrapper& rhs);
SwigValueWrapper(const SwigValueWrapper& rhs);
public:
SwigValueWrapper() : pointer(0) { }
- SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+ SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; }
#if __cplusplus >= 201103L
- SwigValueWrapper& operator=(T&& t) { SwigMovePointer tmp(new T(std::move(t))); pointer = tmp; return *this; }
+ SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; }
#endif
operator T&() const { return *pointer.ptr; }
T *operator&() { return pointer.ptr; }
From 6c4010e4421fbb1be76e89f4edba2d7db532c1cb Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 30 Jun 2022 12:36:45 +1200
Subject: [PATCH 482/662] Resolve -Wstrict-prototypes warnings with clang-15
warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes]
---
Source/CParse/cparse.h | 2 +-
Source/CParse/cscanner.c | 10 +++++-----
Source/CParse/parser.y | 6 +++---
Source/CParse/templ.c | 2 +-
Source/DOH/file.c | 4 ++--
Source/DOH/memory.c | 4 ++--
Source/Preprocessor/cpp.c | 4 ++--
Source/Preprocessor/expr.c | 6 +++---
Source/Swig/include.c | 4 ++--
Source/Swig/misc.c | 2 +-
Source/Swig/naming.c | 8 ++++----
Source/Swig/parms.c | 2 +-
Source/Swig/swigfile.h | 2 +-
Source/Swig/typemap.c | 4 ++--
Source/Swig/typesys.c | 8 ++++----
15 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h
index c67ffeaba..0d9ca4b9d 100644
--- a/Source/CParse/cparse.h
+++ b/Source/CParse/cparse.h
@@ -43,7 +43,7 @@ extern "C" {
extern void scanner_clear_rename(void);
extern void scanner_set_location(String *file, int line);
extern void scanner_set_main_input_file(String *file);
- extern String *scanner_get_main_input_file();
+ extern String *scanner_get_main_input_file(void);
extern void Swig_cparse_follow_locators(int);
extern void start_inline(char *, int);
extern String *scanner_ccode;
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
index a658f5a6f..155c7c81b 100644
--- a/Source/CParse/cscanner.c
+++ b/Source/CParse/cscanner.c
@@ -123,7 +123,7 @@ void Swig_cparse_cplusplusout(int v) {
* Initialize buffers
* ------------------------------------------------------------------------- */
-void scanner_init() {
+void scanner_init(void) {
scan = NewScanner();
Scanner_idstart(scan,"%");
scan_init = 1;
@@ -528,11 +528,11 @@ void scanner_set_location(String *file, int line) {
Scanner_set_location(scan,file,line-1);
}
-void scanner_check_typedef() {
+void scanner_check_typedef(void) {
check_typedef = 1;
}
-void scanner_ignore_typedef() {
+void scanner_ignore_typedef(void) {
check_typedef = 0;
}
@@ -540,7 +540,7 @@ void scanner_last_id(int x) {
last_id = x;
}
-void scanner_clear_rename() {
+void scanner_clear_rename(void) {
rename_active = 0;
}
@@ -554,7 +554,7 @@ void scanner_set_main_input_file(String *file) {
main_input_file = file;
}
-String *scanner_get_main_input_file() {
+String *scanner_get_main_input_file(void) {
return main_input_file;
}
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 1ae3a59db..ddb9634b2 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -50,7 +50,7 @@
* Externals
* ----------------------------------------------------------------------------- */
-int yyparse();
+int yyparse(void);
/* NEW Variables */
@@ -349,7 +349,7 @@ static String *make_name(Node *n, String *name,SwigType *decl) {
}
/* Generate an unnamed identifier */
-static String *make_unnamed() {
+static String *make_unnamed(void) {
unnamed++;
return NewStringf("$unnamed%d$",unnamed);
}
@@ -874,7 +874,7 @@ static void add_typedef_name(Node *n, Node *declnode, String *oldName, Symtab *c
/* If the class name is qualified. We need to create or lookup namespace entries */
-static Symtab *set_scope_to_global() {
+static Symtab *set_scope_to_global(void) {
Symtab *symtab = Swig_symbol_global_scope();
Swig_symbol_setscope(symtab);
return symtab;
diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c
index f8c926d37..44a606299 100644
--- a/Source/CParse/templ.c
+++ b/Source/CParse/templ.c
@@ -19,7 +19,7 @@ static int template_debug = 0;
const char *baselists[3];
-void SwigType_template_init() {
+void SwigType_template_init(void) {
baselists[0] = "baselist";
baselists[1] = "protectedbaselist";
baselists[2] = "privatebaselist";
diff --git a/Source/DOH/file.c b/Source/DOH/file.c
index bf8055177..8ec8bd6ae 100644
--- a/Source/DOH/file.c
+++ b/Source/DOH/file.c
@@ -35,7 +35,7 @@ typedef struct {
* reference count of the underlying DOH objects.
* ----------------------------------------------------------------------------- */
-static DOHList *open_files_list_instance() {
+static DOHList *open_files_list_instance(void) {
static DOHList *all_open_files = 0;
if (!all_open_files)
all_open_files = DohNewList();
@@ -73,7 +73,7 @@ static void open_files_list_remove(DohFile *f) {
* Close all opened files, to be called on program termination
* ----------------------------------------------------------------------------- */
-void DohCloseAllOpenFiles() {
+void DohCloseAllOpenFiles(void) {
int i;
DOHList *all_open_files = open_files_list_instance();
for (i = 0; i < DohLen(all_open_files); i++) {
diff --git a/Source/DOH/memory.c b/Source/DOH/memory.c
index 88ed0f959..d461ce392 100644
--- a/Source/DOH/memory.c
+++ b/Source/DOH/memory.c
@@ -48,7 +48,7 @@ static int pools_initialized = 0;
* CreatePool() - Create a new memory pool
* ---------------------------------------------------------------------- */
-static void CreatePool() {
+static void CreatePool(void) {
Pool *p = 0;
p = (Pool *) DohMalloc(sizeof(Pool));
p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase));
@@ -65,7 +65,7 @@ static void CreatePool() {
* InitPools() - Initialize the memory allocator
* ---------------------------------------------------------------------- */
-static void InitPools() {
+static void InitPools(void) {
if (pools_initialized)
return;
CreatePool(); /* Create initial pool */
diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c
index 34ace2d77..14fa1aa01 100644
--- a/Source/Preprocessor/cpp.c
+++ b/Source/Preprocessor/cpp.c
@@ -1356,14 +1356,14 @@ static void add_chunk(DOH *ns, DOH *chunk, int allow) {
push/pop_imported(): helper functions for defining and undefining
SWIGIMPORTED (when %importing a file).
*/
-static void push_imported() {
+static void push_imported(void) {
if (imported_depth == 0) {
Preprocessor_define("SWIGIMPORTED 1", 0);
}
++imported_depth;
}
-static void pop_imported() {
+static void pop_imported(void) {
--imported_depth;
if (imported_depth == 0) {
Preprocessor_undef("SWIGIMPORTED");
diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c
index e5c768765..52e467b6c 100644
--- a/Source/Preprocessor/expr.c
+++ b/Source/Preprocessor/expr.c
@@ -52,7 +52,7 @@ static int expr_init = 0; /* Initialization flag */
static const char *errmsg = 0; /* Parsing error */
/* Initialize the precedence table for various operators. Low values have higher precedence */
-static void init_precedence() {
+static void init_precedence(void) {
prec[SWIG_TOKEN_NOT] = 10;
prec[OP_UMINUS] = 10;
prec[OP_UPLUS] = 10;
@@ -85,7 +85,7 @@ static void init_precedence() {
/* Reduce a single operator on the stack */
/* return 0 on failure, 1 on success */
-static int reduce_op() {
+static int reduce_op(void) {
long op_token = stack[sp - 1].value;
assert(sp > 0);
assert(stack[sp - 1].op == EXPR_OP);
@@ -474,6 +474,6 @@ extra_rparen:
* Return error message set by the evaluator (if any)
* ----------------------------------------------------------------------------- */
-const char *Preprocessor_expr_error() {
+const char *Preprocessor_expr_error(void) {
return errmsg;
}
diff --git a/Source/Swig/include.c b/Source/Swig/include.c
index 94df338f0..ca43dbd65 100644
--- a/Source/Swig/include.c
+++ b/Source/Swig/include.c
@@ -145,7 +145,7 @@ static List *Swig_search_path_any(int syspath) {
return slist;
}
-List *Swig_search_path() {
+List *Swig_search_path(void) {
return Swig_search_path_any(0);
}
@@ -376,6 +376,6 @@ String *Swig_file_dirname(const_String_or_char_ptr filename) {
/*
* Swig_file_debug()
*/
-void Swig_file_debug_set() {
+void Swig_file_debug_set(void) {
file_debug = 1;
}
diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c
index 0519b57c9..55306b1da 100644
--- a/Source/Swig/misc.c
+++ b/Source/Swig/misc.c
@@ -1497,7 +1497,7 @@ int Swig_is_generated_overload(Node *n) {
* Initialize the SWIG core
* ----------------------------------------------------------------------------- */
-void Swig_init() {
+void Swig_init(void) {
/* Set some useful string encoding methods */
DohEncoding("escape", Swig_string_escape);
DohEncoding("hexescape", Swig_string_hexescape);
diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c
index 4d07d5b2f..0673429ad 100644
--- a/Source/Swig/naming.c
+++ b/Source/Swig/naming.c
@@ -744,28 +744,28 @@ void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *d
* ----------------------------------------------------------------------------- */
static Hash *namewarn_hash = 0;
-static Hash *name_namewarn_hash() {
+static Hash *name_namewarn_hash(void) {
if (!namewarn_hash)
namewarn_hash = NewHash();
return namewarn_hash;
}
static Hash *rename_hash = 0;
-static Hash *name_rename_hash() {
+static Hash *name_rename_hash(void) {
if (!rename_hash)
rename_hash = NewHash();
return rename_hash;
}
static List *namewarn_list = 0;
-static List *name_namewarn_list() {
+static List *name_namewarn_list(void) {
if (!namewarn_list)
namewarn_list = NewList();
return namewarn_list;
}
static List *rename_list = 0;
-static List *name_rename_list() {
+static List *name_rename_list(void) {
if (!rename_list)
rename_list = NewList();
return rename_list;
diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c
index 3e832c361..f89ad6356 100644
--- a/Source/Swig/parms.c
+++ b/Source/Swig/parms.c
@@ -149,7 +149,7 @@ int ParmList_len(ParmList *p) {
* get_empty_type()
* ---------------------------------------------------------------------- */
-static SwigType *get_empty_type() {
+static SwigType *get_empty_type(void) {
return NewStringEmpty();
}
diff --git a/Source/Swig/swigfile.h b/Source/Swig/swigfile.h
index f12b33081..0583b3792 100644
--- a/Source/Swig/swigfile.h
+++ b/Source/Swig/swigfile.h
@@ -30,7 +30,7 @@ extern String *Swig_file_extension(const_String_or_char_ptr filename);
extern String *Swig_file_basename(const_String_or_char_ptr filename);
extern String *Swig_file_filename(const_String_or_char_ptr filename);
extern String *Swig_file_dirname(const_String_or_char_ptr filename);
-extern void Swig_file_debug_set();
+extern void Swig_file_debug_set(void);
/* Delimiter used in accessing files and directories */
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index 2f9c06000..126d88026 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -151,7 +151,7 @@ static void set_typemap(const SwigType *type, Hash **tmhash) {
* Initialize the typemap system
* ----------------------------------------------------------------------------- */
-void Swig_typemap_init() {
+void Swig_typemap_init(void) {
typemaps = NewHash();
}
@@ -2170,7 +2170,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
* Display all typemaps
* ----------------------------------------------------------------------------- */
-void Swig_typemap_debug() {
+void Swig_typemap_debug(void) {
int nesting_level = 2;
Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n");
Swig_print(typemaps, nesting_level);
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
index d6d6bcc88..710688a0f 100644
--- a/Source/Swig/typesys.c
+++ b/Source/Swig/typesys.c
@@ -180,7 +180,7 @@ int Swig_value_wrapper_mode(int mode) {
}
-static void flush_cache() {
+static void flush_cache(void) {
typedef_resolve_cache = 0;
typedef_all_cache = 0;
typedef_qualified_cache = 0;
@@ -188,7 +188,7 @@ static void flush_cache() {
/* Initialize the scoping system */
-void SwigType_typesystem_init() {
+void SwigType_typesystem_init(void) {
if (global_scope)
Delete(global_scope);
if (scopes)
@@ -407,7 +407,7 @@ void SwigType_using_scope(Typetab *scope) {
* table for the scope that was popped off.
* ----------------------------------------------------------------------------- */
-Typetab *SwigType_pop_scope() {
+Typetab *SwigType_pop_scope(void) {
Typetab *t, *old = current_scope;
t = Getattr(current_scope, "parent");
if (!t)
@@ -2093,7 +2093,7 @@ static int SwigType_compare_mangled(const DOH *a, const DOH *b) {
* Returns the sorted list of mangled type names that should be exported into the
* wrapper file.
* ----------------------------------------------------------------------------- */
-List *SwigType_get_sorted_mangled_list() {
+List *SwigType_get_sorted_mangled_list(void) {
List *l = Keys(r_mangled);
SortList(l, SwigType_compare_mangled);
return l;
From f5e2d044df193f3aa2340eca9ee47d5f125982fc Mon Sep 17 00:00:00 2001
From: Olly Betts
Date: Thu, 30 Jun 2022 12:50:53 +1200
Subject: [PATCH 483/662] Remove set but not used variables
Highlighted by clang-15 warnings such as:
warning: variable 'index' set but not used [-Wunused-but-set-variable]
---
Source/Modules/directors.cxx | 2 --
Source/Modules/lua.cxx | 2 --
Source/Modules/ocaml.cxx | 7 -------
Source/Modules/octave.cxx | 2 --
Source/Modules/php.cxx | 7 -------
Source/Modules/tcl8.cxx | 1 +
6 files changed, 1 insertion(+), 20 deletions(-)
diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx
index 196974792..4ca8b25e5 100644
--- a/Source/Modules/directors.cxx
+++ b/Source/Modules/directors.cxx
@@ -97,7 +97,6 @@ String *Swig_director_declaration(Node *n) {
String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
String *func;
- int i = 0;
int comma = 0;
Parm *p = parms;
SwigType *pt;
@@ -115,7 +114,6 @@ String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
pname = Getattr(p, "name");
Printf(func, "%s", pname);
comma = 1;
- i++;
}
p = nextSibling(p);
}
diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx
index 18cf8a346..5265aa5c1 100644
--- a/Source/Modules/lua.cxx
+++ b/Source/Modules/lua.cxx
@@ -1418,7 +1418,6 @@ public:
List *baselist = Getattr(n, "bases");
if (baselist && Len(baselist)) {
Iterator b;
- int index = 0;
b = First(baselist);
while (b.item) {
String *bname = Getattr(b.item, "name");
@@ -1431,7 +1430,6 @@ public:
Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
b = Next(b);
- index++;
}
}
// First, print class static part
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
index 97bb8cc17..84f16aa99 100644
--- a/Source/Modules/ocaml.cxx
+++ b/Source/Modules/ocaml.cxx
@@ -1486,10 +1486,6 @@ public:
int i;
char source[256];
- int outputs = 0;
- if (!is_void)
- outputs++;
-
/* build argument list and type conversion string */
for (i = 0, idx = 0, p = l; i < num_arguments; i++) {
@@ -1497,9 +1493,6 @@ public:
p = Getattr(p, "tmap:ignore:next");
}
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx
index 9e5bd17a1..e6c55fb0b 100644
--- a/Source/Modules/octave.cxx
+++ b/Source/Modules/octave.cxx
@@ -1003,7 +1003,6 @@ public:
List *baselist = Getattr(n, "bases");
if (baselist && Len(baselist)) {
Iterator b;
- int index = 0;
b = First(baselist);
while (b.item) {
String *bname = Getattr(b.item, "name");
@@ -1016,7 +1015,6 @@ public:
Printf(base_class_names, "\"%s\",", bname_mangled);
Printf(base_class, "0,");
b = Next(b);
- index++;
Delete(bname_mangled);
}
}
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index c424572f1..67f7f1f19 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -2167,10 +2167,6 @@ public:
Parm *p;
- int outputs = 0;
- if (!is_void)
- outputs++;
-
/* build argument list and type conversion string */
idx = 0;
p = l;
@@ -2180,9 +2176,6 @@ public:
continue;
}
- if (Getattr(p, "tmap:directorargout") != 0)
- outputs++;
-
String *pname = Getattr(p, "name");
String *ptype = Getattr(p, "type");
diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx
index 641dfc866..72908d8ed 100644
--- a/Source/Modules/tcl8.cxx
+++ b/Source/Modules/tcl8.cxx
@@ -825,6 +825,7 @@ public:
//Printf(f_init,"/* Register base : %s */\n", bmangle);
//Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname));
+ (void)index;
b = Next(b);
index++;
Putc(',', base_class);
From a0fed47163b566fbaae19aa0e7805bd59fd446e9 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 21 Jun 2022 14:56:17 +0100
Subject: [PATCH 484/662] Remove duplicate typemaps
---
Lib/cffi/cffi.swg | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/Lib/cffi/cffi.swg b/Lib/cffi/cffi.swg
index f7294956f..690081032 100644
--- a/Lib/cffi/cffi.swg
+++ b/Lib/cffi/cffi.swg
@@ -201,15 +201,6 @@
;;;SWIG wrapper code ends here
%}
-#ifdef __cplusplus
-%typemap(out) SWIGTYPE "$result = new $1_type($1);";
-#else
-%typemap(out) SWIGTYPE {
- $result = ($&1_ltype) malloc(sizeof($1_type));
- memmove($result, &$1, sizeof($1_type));
-}
-#endif
-
//////////////////////////////////////////////////////////////
/* name conversion for overloaded operators. */
From 6ccef6dae1dee6d569642d49f449c40e8d432627 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Fri, 24 Jun 2022 21:24:24 +0100
Subject: [PATCH 485/662] Ocaml clean fixes
---
Examples/test-suite/ocaml/Makefile.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in
index 79e25efcf..9b0c32b0f 100644
--- a/Examples/test-suite/ocaml/Makefile.in
+++ b/Examples/test-suite/ocaml/Makefile.in
@@ -103,7 +103,7 @@ $(MULTI_CPP_TEST_CASES:=.multicpptest): extra_objects
# Clean
%.clean:
- @rm -f $*.ml $*.mli $*_runme;
+ @rm -f $*_wrap.* $*.cmo $*.cmi $*.ml $*.mli $*_runme;
@if test $(srcdir) != .; then rm -f $(ml_runme); fi
clean:
From bf36bf7d8aa8d130f30d0cbb2c260966f96bc108 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 22 Jun 2022 12:52:06 +0100
Subject: [PATCH 486/662] Movable and move-only types supported in "out"
typemaps.
Enhance SWIGTYPE "out" typemaps to use std::move when copying
objects, thereby making use of move semantics when wrapping a function returning
by value if the returned type supports move semantics.
Wrapping functions that return move only types 'by value' now work out the box
without having to provide custom typemaps.
The implementation removed all casts in the "out" typemaps to allow the compiler to
appropriately choose calling a move constructor, where possible, otherwise a copy
constructor. The implementation alsoand required modifying SwigValueWrapper to
change a cast operator from:
SwigValueWrapper::operator T&() const;
to
#if __cplusplus >=201103L
SwigValueWrapper::operator T&&() const;
#else
SwigValueWrapper::operator T&() const;
#endif
This is not backwards compatible for C++11 and later when using the valuewrapper feature
if a cast is explicitly being made in user supplied "out" typemaps. Suggested change
in custom "out" typemaps for C++11 and later code:
1. Try remove the cast altogether to let the compiler use an appropriate implicit cast.
2. Change the cast, for example, from static_cast to static_cast, using the
__cplusplus macro if all versions of C++ need to be supported.
Issue #999
Closes #1044
More about the commit:
Added some missing "varout" typemaps for Ocaml which was falling back to
use "out" typemaps as they were missing.
Ruby std::set fix for SwigValueWrapper C++11 changes.
---
CHANGES.current | 33 +++++
Doc/Manual/CPlusPlus11.html | 79 +++++++++++
Doc/Manual/Contents.html | 3 +
Doc/Manual/SWIGPlus.html | 24 ++--
Doc/Manual/Typemaps.html | 10 +-
Examples/test-suite/common.mk | 1 +
Examples/test-suite/cpp11_move_only.i | 52 +++++++
Examples/test-suite/cpp11_move_only_helper.i | 71 ++++++++++
.../test-suite/cpp11_move_only_valuewrapper.i | 129 +++++-------------
.../csharp/cpp11_move_only_runme.cs | 23 ++++
.../cpp11_move_only_valuewrapper_runme.cs | 16 ++-
.../csharp/typemap_out_optimal_runme.cs | 8 +-
.../d/typemap_out_optimal_runme.1.d | 1 +
.../d/typemap_out_optimal_runme.2.d | 1 +
.../go/typemap_out_optimal_runme.go | 1 +
.../java/cpp11_move_only_runme.java | 39 ++++++
.../cpp11_move_only_valuewrapper_runme.java | 44 ++++++
.../java/typemap_out_optimal_runme.java | 10 +-
.../python/cpp11_move_only_runme.py | 17 +++
.../python/typemap_out_optimal_runme.py | 3 +
Examples/test-suite/typemap_out_optimal.i | 13 +-
Lib/cffi/cffi.swg | 3 +-
Lib/csharp/csharp.swg | 2 +-
Lib/d/dswigtype.swg | 2 +-
Lib/guile/typemaps.i | 5 +-
Lib/java/java.swg | 2 +-
Lib/lua/luatypemaps.swg | 2 +-
Lib/mzscheme/typemaps.i | 2 +-
Lib/ocaml/ocaml.swg | 10 +-
Lib/ocaml/std_string.i | 9 ++
Lib/php/php.swg | 2 +-
Lib/ruby/std_set.i | 7 +-
Lib/swig.swg | 6 +-
Lib/typemaps/swigtype.swg | 16 ++-
34 files changed, 508 insertions(+), 138 deletions(-)
create mode 100644 Examples/test-suite/cpp11_move_only.i
create mode 100644 Examples/test-suite/cpp11_move_only_helper.i
create mode 100644 Examples/test-suite/csharp/cpp11_move_only_runme.cs
create mode 100644 Examples/test-suite/java/cpp11_move_only_runme.java
create mode 100644 Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java
create mode 100644 Examples/test-suite/python/cpp11_move_only_runme.py
diff --git a/CHANGES.current b/CHANGES.current
index 1e06bd85b..6584e1781 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,39 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-06-29: wsfulton
+ #999 #1044 Enhance SWIGTYPE "out" typemaps to use std::move when copying
+ objects, thereby making use of move semantics when wrapping a function returning
+ by value if the returned type supports move semantics.
+
+ Wrapping functions that return move only types 'by value' now work out the box
+ without having to provide custom typemaps.
+
+ The implementation removed all casts in the "out" typemaps to allow the compiler to
+ appropriately choose calling a move constructor, where possible, otherwise a copy
+ constructor. The implementation alsoand required modifying SwigValueWrapper to
+ change a cast operator from:
+
+ SwigValueWrapper::operator T&() const;
+
+ to
+
+ #if __cplusplus >=201103L
+ SwigValueWrapper::operator T&&() const;
+ #else
+ SwigValueWrapper::operator T&() const;
+ #endif
+
+ This is not backwards compatible for C++11 and later when using the valuewrapper feature
+ if a cast is explicitly being made in user supplied "out" typemaps. Suggested change
+ in custom "out" typemaps for C++11 and later code:
+
+ 1. Try remove the cast altogether to let the compiler use an appropriate implicit cast.
+ 2. Change the cast, for example, from static_cast to static_cast, using the
+ __cplusplus macro if all versions of C++ need to be supported.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
2022-06-15: wsfulton
#2039 Add move assignment operator to SwigValueWrapper used by the
valuewrapper feature.
diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html
index 86a35bfaa..b98713961 100644
--- a/Doc/Manual/CPlusPlus11.html
+++ b/Doc/Manual/CPlusPlus11.html
@@ -15,6 +15,9 @@
Core language changes
- Rvalue reference and move semantics
+
- Generalized constant expressions
- Extern template
- Initializer lists
@@ -123,6 +126,82 @@ example.i:18: Warning 503: Can't wrap 'operator =' unless renamed to a valid ide
+
+
+
+
+SWIG has traditionally relied on wrapped C++ types to be copy constructible or copy assignable, either via an explicit or implicit copy constructor and copy assignment operator.
+Prior to C++11, a function could not return nor take a type by value that was not copyable.
+In C++11 this is no longer the case. A type can also be movable if it has has a move constructor and a move assignment operator.
+A move-only type is movable but not copyable; it has both the copy constructor and copy assignment operator deleted.
+Movable types can appear in function signatures for passing 'by value' and in C++11 the object can then be moved rather than copied.
+
+
+
+SWIG has been enhanced with support for both copyable and/or movable types but this is currently just for function return values.
+
+
+
+The support for function return values is generically implemented in the "out" SWIGTYPE typemap which supports any type, including copyable, movable and move-only types.
+The typemap code is very simple and written so that the compiler will call the move constructor if possible,
+otherwise the copy constructor:
+
+
+
+%typemap(out) SWIGTYPE %{
+ $result = new $1_ltype($1);
+%}
+
+
+
+The above typemap is for C# and when used to wrap a move-only type such as:
+
+
+
+struct MoveOnly {
+ int val;
+ MoveOnly(): val(0) {}
+
+ MoveOnly(const MoveOnly &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+
+ MoveOnly & operator=(const MoveOnly &) = delete;
+ MoveOnly & operator=(MoveOnly &&) = default;
+
+ static MoveOnly create() { return MoveOnly(); }
+};
+
+
+
+will generate wrapper code for the create factory method:
+
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
+ void * jresult ;
+ SwigValueWrapper< MoveOnly > result;
+
+ result = MoveOnly::create();
+ jresult = new MoveOnly(result);
+ return jresult;
+}
+
+
+
+SwigValueWrapper is covered in Pass and return by value.
+Note that the generated code could be optimised further using the "optimal" attribute in the "out" typemap.
+
+
+
+There is currently only partial support for move-only types as
+support for move-only types used as a parameter in a function, that are passed 'by value', is not yet available.
+
+
+
+Compatibility note:
+SWIG-4.1.0 introduced support for taking advantage of types with move semantics and wrapping functions that return movable or move-only types 'by value'.
+
+
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 6f48360fd..ef87cf78d 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -297,6 +297,9 @@
- Core language changes
- Rvalue reference and move semantics
+
- Generalized constant expressions
- Extern template
- Initializer lists
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index 4cefdc365..820c5088b 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -584,7 +584,7 @@ automatically generate a wrapper for one.
-
If a C++ class does not declare an explicit copy constructor, SWIG will
-automatically generate a wrapper for one if the %copyctor is used.
+automatically generate a wrapper for one if %copyctor is used.
-
@@ -1352,16 +1352,19 @@ following:
Vector *wrap_cross_product(Vector *a, Vector *b) {
- Vector x = *a;
- Vector y = *b;
- Vector r = cross_product(x, y);
+ Vector x;
+ Vector y;
+ Vector r;
+ x = *a;
+ y = *b;
+ r = cross_product(x, y);
return new Vector(r);
}
-In order for the wrapper code to compile, Vector must define a copy constructor and a
-default constructor.
+In order for the wrapper code to compile, Vector must define a default constructor, copy assignment operator (and/or a move assignment operator for C++11 and later).
+The Movable and move-only types section should be read regarding C++11 move semantics and return by value.
@@ -1374,9 +1377,12 @@ called the "Fulton Transform". This produces a wrapper that looks like this:
Vector cross_product(Vector *a, Vector *b) {
- SwigValueWrapper<Vector> x = *a;
- SwigValueWrapper<Vector> y = *b;
- SwigValueWrapper<Vector> r = cross_product(x, y);
+ SwigValueWrapper<Vector> x;
+ SwigValueWrapper<Vector> y;
+ SwigValueWrapper<Vector> r;
+ x = *a;
+ y = *b;
+ r = cross_product(x, y);
return new Vector(r);
}
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
index 28f9d51ad..24a68b1ba 100644
--- a/Doc/Manual/Typemaps.html
+++ b/Doc/Manual/Typemaps.html
@@ -3364,7 +3364,7 @@ Consider running the following code through SWIG:
%typemap(out) SWIGTYPE %{
- $result = new $1_ltype((const $1_ltype &)$1);
+ $result = new $1_ltype($1);
%}
%inline %{
@@ -3414,7 +3414,7 @@ If the typemap code is kept the same and just the "optimal" attribute specified
%typemap(out, optimal="1") SWIGTYPE %{
- $result = new $1_ltype((const $1_ltype &)$1);
+ $result = new $1_ltype($1);
%}
@@ -3441,7 +3441,7 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() {
void * jresult ;
XX result;
result = XX::create();
- jresult = new XX((const XX &)result);
+ jresult = new XX(result);
return jresult;
}
@@ -3456,7 +3456,7 @@ With the "optimal" attribute, the code is:
SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() {
void * jresult ;
- jresult = new XX((const XX &)XX::create());
+ jresult = new XX(XX::create());
return jresult;
}
@@ -3513,7 +3513,7 @@ It should be clear that the above code cannot be used as the argument to the cop
-Secondly, if the typemaps uses $1 more than once, then multiple calls to the wrapped function
+Secondly, if the typemap uses $1 more than once, then multiple calls to the wrapped function
will be made. Obviously that is not very optimal.
In fact SWIG attempts to detect this and will issue a warning something like:
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 003138010..a640febc1 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -597,6 +597,7 @@ CPP11_TEST_CASES += \
cpp11_initializer_list \
cpp11_initializer_list_extend \
cpp11_lambda_functions \
+ cpp11_move_only \
cpp11_move_only_valuewrapper \
cpp11_noexcept \
cpp11_null_pointer_constant \
diff --git a/Examples/test-suite/cpp11_move_only.i b/Examples/test-suite/cpp11_move_only.i
new file mode 100644
index 000000000..7c91933c4
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only.i
@@ -0,0 +1,52 @@
+%module cpp11_move_only
+
+#if defined(SWIGD)
+%rename(trace) debug;
+#endif
+
+%include "cpp11_move_only_helper.i"
+
+%ignore MoveOnly::operator=;
+//%valuewrapper MoveOnly; // SWIG sets %valuewrapper by default for move-only types
+
+%inline %{
+#include
+using namespace std;
+
+bool debug = false;
+
+struct MoveOnly {
+ MoveOnly(int i = 0) { if (debug) cout << "MoveOnly(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+ MoveOnly(const MoveOnly &other) = delete;
+ MoveOnly & operator=(const MoveOnly &other) = delete;
+
+ MoveOnly(MoveOnly &&other) noexcept { if (debug) cout << "MoveOnly(MoveOnly &&)" << " " << this << endl; Counter::move_constructor++; }
+ MoveOnly & operator=(MoveOnly &&other) noexcept { if (debug) cout << "operator=(MoveOnly &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
+ ~MoveOnly() { if (debug) cout << "~MoveOnly()" << " " << this << endl; Counter::destructor++; }
+
+ static MoveOnly create() { return MoveOnly(111); }
+ // static const MoveOnly createConst() { return MoveOnly(111); } // not supported by default
+};
+%}
+
+%ignore MovableCopyable::operator=;
+%ignore MovableCopyable::MovableCopyable(MovableCopyable &&);
+// %valuewrapper MovableCopyable; // SWIG does not use valuewrapper by default for copyable types with a default constructor
+
+%inline %{
+// Movable and Copyable
+struct MovableCopyable {
+ MovableCopyable(int i = 0) { if (debug) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+ MovableCopyable(const MovableCopyable &other) { if (debug) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+ MovableCopyable & operator=(const MovableCopyable &other) { if (debug) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
+
+ MovableCopyable(MovableCopyable &&other) noexcept { if (debug) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
+ MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (debug) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
+ ~MovableCopyable() { if (debug) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
+
+ static MovableCopyable create() { return MovableCopyable(111); }
+ static const MovableCopyable createConst() { return MovableCopyable(111); }
+};
+%}
diff --git a/Examples/test-suite/cpp11_move_only_helper.i b/Examples/test-suite/cpp11_move_only_helper.i
new file mode 100644
index 000000000..89fc1509b
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only_helper.i
@@ -0,0 +1,71 @@
+// Helper interface for cpp11_move_only.i and others
+
+%include
+%catches(std::string) Counter::check_counts;
+
+%inline %{
+#include
+using namespace std;
+
+
+struct Counter {
+ static int normal_constructor;
+ static int copy_constructor;
+ static int copy_assignment;
+ static int move_constructor;
+ static int move_assignment;
+ static int destructor;
+ static void reset_counts() {
+ normal_constructor = 0;
+ copy_constructor = 0;
+ copy_assignment = 0;
+ move_constructor = 0;
+ move_assignment = 0;
+ destructor = 0;
+ }
+ // Check against expected counts of constructor, assignment operators etc.
+ // Not observed during development, but compiler optimisation could change the expected values.
+ // Throws exception if not correct (use %catches to catch them)
+ static void check_counts(
+ int normal_constructor,
+ int copy_constructor,
+ int copy_assignment,
+ int move_constructor,
+ int move_assignment,
+ int destructor) {
+ bool match = (
+ normal_constructor == Counter::normal_constructor &&
+ copy_constructor == Counter::copy_constructor &&
+ copy_assignment == Counter::copy_assignment &&
+ move_constructor == Counter::move_constructor &&
+ move_assignment == Counter::move_assignment &&
+ destructor == Counter::destructor);
+ if (!match) {
+ std::stringstream ss;
+ ss << "check_counts failed" << std::endl <<
+ Counter::normal_constructor << " " <<
+ Counter::copy_constructor << " " <<
+ Counter::copy_assignment << " " <<
+ Counter::move_constructor << " " <<
+ Counter::move_assignment << " " <<
+ Counter::destructor << " " <<
+ " (actual)" << std::endl <<
+ normal_constructor << " " <<
+ copy_constructor << " " <<
+ copy_assignment << " " <<
+ move_constructor << " " <<
+ move_assignment << " " <<
+ destructor << " " <<
+ " (expected)" << std::endl;
+ throw ss.str();
+ }
+ }
+};
+
+int Counter::normal_constructor = 0;
+int Counter::copy_constructor = 0;
+int Counter::copy_assignment = 0;
+int Counter::move_constructor = 0;
+int Counter::move_assignment = 0;
+int Counter::destructor = 0;
+%}
diff --git a/Examples/test-suite/cpp11_move_only_valuewrapper.i b/Examples/test-suite/cpp11_move_only_valuewrapper.i
index fb9f5dc31..bde95f014 100644
--- a/Examples/test-suite/cpp11_move_only_valuewrapper.i
+++ b/Examples/test-suite/cpp11_move_only_valuewrapper.i
@@ -37,82 +37,28 @@ namespace std {
#endif
%}
-%include
+#if defined(SWIGD)
+%rename(trace) debug;
+#endif
+
+%include "cpp11_move_only_helper.i"
%valuewrapper XXX;
%ignore XXX::operator=;
-%catches(std::string) XXX::check_counts;
%inline %{
bool debug = false;
struct XXX {
- XXX(int i = 0) { if (debug) cout << "XXX(" << i << ")" << " " << this << endl; normal_constructor_count++; }
- XXX(const XXX &other) { if (debug) cout << "XXX(const XXX &)" << " " << this << " " << &other << endl; copy_constructor_count++;}
- XXX & operator=(const XXX &other) { if (debug) cout << "operator=(const XXX &)" << " " << this << " " << &other << endl; copy_assignment_count++; return *this; }
+ XXX(int i = 0) { if (debug) cout << "XXX(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+ XXX(const XXX &other) { if (debug) cout << "XXX(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+ XXX & operator=(const XXX &other) { if (debug) cout << "operator=(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
#if defined(__cplusplus) && __cplusplus >= 201103L
- XXX(XXX &&other) noexcept { if (debug) cout << "XXX(XXX &&)" << " " << this << endl; move_constructor_count++; }
- XXX & operator=(XXX &&other) noexcept { if (debug) cout << "operator=(XXX &&)" << " " << this << endl; move_assignment_count++; return *this; }
+ XXX(XXX &&other) noexcept { if (debug) cout << "XXX(XXX &&)" << " " << this << endl; Counter::move_constructor++; }
+ XXX & operator=(XXX &&other) noexcept { if (debug) cout << "operator=(XXX &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
#endif
- ~XXX() { if (debug) cout << "~XXX()" << " " << this << endl; destructor_count++; }
- static int normal_constructor_count;
- static int copy_constructor_count;
- static int copy_assignment_count;
- static int move_constructor_count;
- static int move_assignment_count;
- static int destructor_count;
- static void reset_counts() {
- XXX::normal_constructor_count = 0;
- XXX::copy_constructor_count = 0;
- XXX::copy_assignment_count = 0;
- XXX::move_constructor_count = 0;
- XXX::move_assignment_count = 0;
- XXX::destructor_count = 0;
- }
- // Check against expected counts of constructor, assignment operators etc.
- // Not observed during development, but compiler optimisation could change the expected values.
- // Throws exception if not correct (use %catches to catch them)
- static void check_counts(
- int normal_constructor_count,
- int copy_constructor_count,
- int copy_assignment_count,
- int move_constructor_count,
- int move_assignment_count,
- int destructor_count) {
- bool match = (
- normal_constructor_count == XXX::normal_constructor_count &&
- copy_constructor_count == XXX::copy_constructor_count &&
- copy_assignment_count == XXX::copy_assignment_count &&
- move_constructor_count == XXX::move_constructor_count &&
- move_assignment_count == XXX::move_assignment_count &&
- destructor_count == XXX::destructor_count);
- if (!match) {
- std::stringstream ss;
- ss << "check_counts failed" << std::endl <<
- XXX::normal_constructor_count << " " <<
- XXX::copy_constructor_count << " " <<
- XXX::copy_assignment_count << " " <<
- XXX::move_constructor_count << " " <<
- XXX::move_assignment_count << " " <<
- XXX::destructor_count << " " <<
- " (actual)" << std::endl <<
- normal_constructor_count << " " <<
- copy_constructor_count << " " <<
- copy_assignment_count << " " <<
- move_constructor_count << " " <<
- move_assignment_count << " " <<
- destructor_count << " " <<
- " (expected)" << std::endl;
- throw ss.str();
- }
- }
+ ~XXX() { if (debug) cout << "~XXX()" << " " << this << endl; Counter::destructor++; }
};
-int XXX::normal_constructor_count = 0;
-int XXX::copy_constructor_count = 0;
-int XXX::copy_assignment_count = 0;
-int XXX::move_constructor_count = 0;
-int XXX::move_assignment_count = 0;
-int XXX::destructor_count = 0;
bool has_cplusplus11() {
#if __cplusplus >= 201103L
return true;
@@ -122,20 +68,8 @@ bool has_cplusplus11() {
}
%}
-#if defined(SWIGCSHARP)
-%typemap(out) std::unique_ptr %{
- if (debug) cout << "out start" << endl;
-#if __cplusplus >= 201103L
- $result = new std::unique_ptr(std::move(static_cast&>($1)));
-#else
- $result = new std::unique_ptr((const std::unique_ptr &)$1);
-#endif
- if (debug) cout << "out done" << endl;
-%}
-
std::unique_ptr makeUniqueXXX();
void cleanup(std::unique_ptr* p);
-#endif
%{
std::unique_ptr makeUniqueXXX() {
@@ -145,6 +79,7 @@ std::unique_ptr makeUniqueXXX() {
void cleanup(std::unique_ptr* p) {
delete p;
}
+typedef XXX UUU;
%}
%inline %{
@@ -152,6 +87,16 @@ XXX createXXX() {
if (debug) cout << "createXXX()" << endl;
return XXX(111);
}
+XXX createXXX2() {
+ if (debug) cout << "createXXX2()" << endl;
+ return XXX(222);
+}
+UUU createUnknownType() {
+ if (debug) cout << "createXXX2()" << endl;
+ return XXX(222);
+}
+struct YYY {};
+void inputByValue(UUU uuu, XXX xxx, YYY yyy) {}
%}
@@ -165,32 +110,32 @@ XXX createXXX() {
%inline %{
// 'unit tests' for SwigValueWrapper
void test1() {
- XXX::reset_counts();
+ Counter::reset_counts();
{
SwigValueWrapper x;
x = XXX();
}
#if __cplusplus >= 201103L
- XXX::check_counts(1, 0, 0, 1, 0, 2); // was same as < c++11 counts below before move assignment operator added to SwigValueWrapper
+ Counter::check_counts(1, 0, 0, 1, 0, 2); // was same as < c++11 counts below before move assignment operator added to SwigValueWrapper
#else
- XXX::check_counts(1, 1, 0, 0, 0, 2);
+ Counter::check_counts(1, 1, 0, 0, 0, 2);
#endif
}
void test2() {
- XXX::reset_counts();
+ Counter::reset_counts();
{
SwigValueWrapper x;
x = XXX();
x = XXX();
}
#if __cplusplus >= 201103L
- XXX::check_counts(2, 0, 0, 2, 0, 4);
+ Counter::check_counts(2, 0, 0, 2, 0, 4);
#else
- XXX::check_counts(2, 2, 0, 0, 0, 4);
+ Counter::check_counts(2, 2, 0, 0, 0, 4);
#endif
}
void test3() {
- XXX::reset_counts();
+ Counter::reset_counts();
{
SwigValueWrapper x;
XXX a(999);
@@ -199,41 +144,41 @@ void test3() {
#endif
}
#if __cplusplus >= 201103L
- XXX::check_counts(1, 0, 0, 1, 0, 2);
+ Counter::check_counts(1, 0, 0, 1, 0, 2);
#endif
}
void test4() {
- XXX::reset_counts();
+ Counter::reset_counts();
{
SwigValueWrapper > x;
x = std::unique_ptr(new XXX(444));
}
- XXX::check_counts(1, 0, 0, 0, 0, 1);
+ Counter::check_counts(1, 0, 0, 0, 0, 1);
}
void test5() {
#if __cplusplus >= 201103L
- XXX::reset_counts();
+ Counter::reset_counts();
{
SwigValueWrapper > x;
x = std::unique_ptr(new XXX(550));
std::unique_ptr x2(new XXX(555));
x = std::move(x2);
}
- XXX::check_counts(2, 0, 0, 0, 0, 2);
+ Counter::check_counts(2, 0, 0, 0, 0, 2);
#endif
}
void test6() {
#if __cplusplus >= 201103L
- XXX::reset_counts();
+ Counter::reset_counts();
{
// emulates how std::unique_ptr typemaps could be wrapped with SwigValueWrapper
void *ptr = 0;
SwigValueWrapper > x; // SWIG generated if std::unique_ptr<> definition not parsed
x = makeUniqueXXX(); // SWIG generated code wrapping function returning std::unique_ptr
- ptr = new std::unique_ptr(std::move((std::unique_ptr&)x)); // 'out' typemap (move std::unique_ptr from stack to the heap), note non-const cast std::unique_tr&
+ ptr = new std::unique_ptr(x); // 'out' typemap (move std::unique_ptr from stack to the heap)
delete (std::unique_ptr *)ptr; // Final cleanup (user needs to call this)
}
- XXX::check_counts(1, 0, 0, 0, 0, 1);
+ Counter::check_counts(1, 0, 0, 0, 0, 1);
#endif
}
%}
diff --git a/Examples/test-suite/csharp/cpp11_move_only_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_runme.cs
new file mode 100644
index 000000000..57cb7aa18
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_only_runme.cs
@@ -0,0 +1,23 @@
+using System;
+using cpp11_move_onlyNamespace;
+
+public class cpp11_move_only_runme {
+
+ public static void Main() {
+ Counter.reset_counts();
+ using (MoveOnly mo = MoveOnly.create()) {
+ }
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+
+ Counter.reset_counts();
+ using (MovableCopyable mo = MovableCopyable.create()) {
+ }
+ Counter.check_counts(2, 1, 0, 0, 1, 3);
+
+ // Move semantics not used
+ Counter.reset_counts();
+ using (MovableCopyable mo = MovableCopyable.createConst()) {
+ }
+ Counter.check_counts(2, 1, 1, 0, 0, 3);
+ }
+}
diff --git a/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
index 69f788699..d6a42a3f7 100644
--- a/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
+++ b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
@@ -4,11 +4,18 @@ using cpp11_move_only_valuewrapperNamespace;
public class cpp11_move_only_valuewrapper_runme {
public static void Main() {
- XXX.reset_counts();
+ Counter.reset_counts();
using (XXX xxx = cpp11_move_only_valuewrapper.createXXX()) {
}
if (cpp11_move_only_valuewrapper.has_cplusplus11())
- XXX.check_counts(1, 1, 0, 1, 0, 3); // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+ // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+ // Was (1, 1, 0, 1, 0, 3) before SwigValueWrapper::operator T&&() was added with new "out" typemaps
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ Counter.reset_counts();
+ using (XXX xxx = cpp11_move_only_valuewrapper.createXXX2()) {
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
cpp11_move_only_valuewrapper.test1();
cpp11_move_only_valuewrapper.test2();
cpp11_move_only_valuewrapper.test3();
@@ -16,10 +23,11 @@ public class cpp11_move_only_valuewrapper_runme {
cpp11_move_only_valuewrapper.test5();
cpp11_move_only_valuewrapper.test6();
- // C# only test (SwigValueWrapper and custom typemaps for std::unique_ptr)
+ // Tests SwigValueWrapper, std::unique_ptr (SWIG not parsing a type that is move-only)
+ Counter.reset_counts();
SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
cpp11_move_only_valuewrapper.cleanup(ptr);
-
+ Counter.check_counts(1, 0, 0, 0, 0, 1);
}
}
diff --git a/Examples/test-suite/csharp/typemap_out_optimal_runme.cs b/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
index 5bc1d14be..0d697498a 100644
--- a/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
+++ b/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
@@ -3,10 +3,14 @@ using typemap_out_optimalNamespace;
public class typemap_out_optimal_runme {
- public static XX x = null;
public static void Main() {
XX.debug = false;
- x = XX.create();
+ if (XX.debug)
+ Console.WriteLine("calling create()");
+ using (XX x = XX.create()) { }
+ if (XX.debug)
+ Console.WriteLine("calling createConst()");
+ using (XX x = XX.createConst()) { }
}
}
diff --git a/Examples/test-suite/d/typemap_out_optimal_runme.1.d b/Examples/test-suite/d/typemap_out_optimal_runme.1.d
index 16aab3cff..1267197e2 100644
--- a/Examples/test-suite/d/typemap_out_optimal_runme.1.d
+++ b/Examples/test-suite/d/typemap_out_optimal_runme.1.d
@@ -6,4 +6,5 @@ void main() {
XX x;
XX.trace = false;
x = XX.create();
+ x = XX.createConst();
}
diff --git a/Examples/test-suite/d/typemap_out_optimal_runme.2.d b/Examples/test-suite/d/typemap_out_optimal_runme.2.d
index 16aab3cff..1267197e2 100644
--- a/Examples/test-suite/d/typemap_out_optimal_runme.2.d
+++ b/Examples/test-suite/d/typemap_out_optimal_runme.2.d
@@ -6,4 +6,5 @@ void main() {
XX x;
XX.trace = false;
x = XX.create();
+ x = XX.createConst();
}
diff --git a/Examples/test-suite/go/typemap_out_optimal_runme.go b/Examples/test-suite/go/typemap_out_optimal_runme.go
index 0cccd97a6..0467ce293 100644
--- a/Examples/test-suite/go/typemap_out_optimal_runme.go
+++ b/Examples/test-suite/go/typemap_out_optimal_runme.go
@@ -5,4 +5,5 @@ import . "swigtests/typemap_out_optimal"
func main() {
SetXXDebug(false)
_ = XXCreate()
+ _ = XXCreateConst()
}
diff --git a/Examples/test-suite/java/cpp11_move_only_runme.java b/Examples/test-suite/java/cpp11_move_only_runme.java
new file mode 100644
index 000000000..b652634e5
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_only_runme.java
@@ -0,0 +1,39 @@
+
+import cpp11_move_only.*;
+
+public class cpp11_move_only_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp11_move_only");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+
+ {
+ Counter.reset_counts();
+ MoveOnly mo = MoveOnly.create();
+ mo.delete();
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ }
+
+ {
+ Counter.reset_counts();
+ MovableCopyable mo = MovableCopyable.create();
+ mo.delete();
+ Counter.check_counts(2, 1, 0, 0, 1, 3);
+ }
+
+ // Move semantics not used
+ {
+ Counter.reset_counts();
+ MovableCopyable mo = MovableCopyable.createConst();
+ mo.delete();
+ Counter.check_counts(2, 1, 1, 0, 0, 3);
+ }
+ }
+}
diff --git a/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java b/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java
new file mode 100644
index 000000000..c857a7b81
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java
@@ -0,0 +1,44 @@
+import cpp11_move_only_valuewrapper.*;
+
+public class cpp11_move_only_valuewrapper_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp11_move_only_valuewrapper");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+ Counter.reset_counts();
+ {
+ XXX xxx = cpp11_move_only_valuewrapper.createXXX();
+ xxx.delete();
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+ // Was (1, 1, 0, 1, 0, 3) before SwigValueWrapper::operator T&&() was added with new "out" typemaps
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ Counter.reset_counts();
+ {
+ XXX xxx = cpp11_move_only_valuewrapper.createXXX2();
+ xxx.delete();
+ }
+ if (cpp11_move_only_valuewrapper.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 2, 0, 3);
+ cpp11_move_only_valuewrapper.test1();
+ cpp11_move_only_valuewrapper.test2();
+ cpp11_move_only_valuewrapper.test3();
+ cpp11_move_only_valuewrapper.test4();
+ cpp11_move_only_valuewrapper.test5();
+ cpp11_move_only_valuewrapper.test6();
+
+ // Tests SwigValueWrapper, std::unique_ptr (SWIG not parsing a type that is move-only)
+ Counter.reset_counts();
+ SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
+ cpp11_move_only_valuewrapper.cleanup(ptr);
+ Counter.check_counts(1, 0, 0, 0, 0, 1);
+ }
+}
diff --git a/Examples/test-suite/java/typemap_out_optimal_runme.java b/Examples/test-suite/java/typemap_out_optimal_runme.java
index 8a87f0c4b..b48e5d697 100644
--- a/Examples/test-suite/java/typemap_out_optimal_runme.java
+++ b/Examples/test-suite/java/typemap_out_optimal_runme.java
@@ -12,10 +12,16 @@ public class typemap_out_optimal_runme {
}
}
- public static XX x = null;
public static void main(String argv[]) {
XX.setDebug(false);
- x = XX.create();
+ {
+ XX x = XX.create();
+ x.delete();
+ }
+ {
+ XX x = XX.createConst();
+ x.delete();
+ }
}
}
diff --git a/Examples/test-suite/python/cpp11_move_only_runme.py b/Examples/test-suite/python/cpp11_move_only_runme.py
new file mode 100644
index 000000000..1c3183327
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_move_only_runme.py
@@ -0,0 +1,17 @@
+from cpp11_move_only import *
+
+Counter.reset_counts()
+mo = MoveOnly.create()
+del mo
+Counter.check_counts(1, 0, 0, 2, 0, 3)
+
+Counter.reset_counts()
+mo = MovableCopyable.create()
+del mo
+Counter.check_counts(2, 1, 0, 0, 1, 3)
+
+# Move semantics not used
+Counter.reset_counts()
+mo = MovableCopyable.createConst()
+del mo
+Counter.check_counts(2, 1, 1, 0, 0, 3)
diff --git a/Examples/test-suite/python/typemap_out_optimal_runme.py b/Examples/test-suite/python/typemap_out_optimal_runme.py
index c325ece55..beed46bfc 100644
--- a/Examples/test-suite/python/typemap_out_optimal_runme.py
+++ b/Examples/test-suite/python/typemap_out_optimal_runme.py
@@ -2,3 +2,6 @@ from typemap_out_optimal import *
cvar.XX_debug = False
x = XX.create()
+del x
+x = XX.createConst()
+del x
diff --git a/Examples/test-suite/typemap_out_optimal.i b/Examples/test-suite/typemap_out_optimal.i
index d707ed2d5..11f1db80f 100644
--- a/Examples/test-suite/typemap_out_optimal.i
+++ b/Examples/test-suite/typemap_out_optimal.i
@@ -4,15 +4,15 @@
// Just the following languages tested
#if defined (SWIGCSHARP) || defined (SWIGD)
%typemap(out, optimal="1") SWIGTYPE %{
- $result = new $1_ltype((const $1_ltype &)$1);
+ $result = new $1_ltype($1);
%}
#elif defined (SWIGJAVA)
%typemap(out, optimal="1") SWIGTYPE %{
- *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1);
+ *($&1_ltype*)&$result = new $1_ltype($1);
%}
#elif defined (SWIGUTL)
%typemap(out,noblock="1", optimal="1") SWIGTYPE {
- %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+ %set_output(SWIG_NewPointerObj(new $1_ltype($1), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
}
#endif
@@ -32,9 +32,14 @@ struct XX {
XX(const XX &other) { if (debug) cout << "XX(const XX &)" << endl; }
XX& operator =(const XX &other) { if (debug) cout << "operator=(const XX &)" << endl; return *this; }
~XX() { if (debug) cout << "~XX()" << endl; }
- static XX create() {
+
+// Note: best observed RVO for C#, Java and Python with g++-6 to g++-10 (just one constructor and one destructor call)
+ static XX create() {
return XX(123);
}
+ static const XX createConst() {
+ return XX(456);
+ }
static bool debug;
};
bool XX::debug = true;
diff --git a/Lib/cffi/cffi.swg b/Lib/cffi/cffi.swg
index 690081032..205bf7900 100644
--- a/Lib/cffi/cffi.swg
+++ b/Lib/cffi/cffi.swg
@@ -90,7 +90,8 @@
enum SWIGTYPE, SWIGTYPE *,
SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$result = $1;";
#ifdef __cplusplus
-%typemap(out) SWIGTYPE "$result = new $1_type($1);";
+%typemap(out) SWIGTYPE
+%{ $result = new $1_ltype($1); %}
#else
%typemap(out) SWIGTYPE {
$result = ($&1_ltype) malloc(sizeof($1_type));
diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg
index 0e180f576..d4bcd3c80 100644
--- a/Lib/csharp/csharp.swg
+++ b/Lib/csharp/csharp.swg
@@ -399,7 +399,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(out) SWIGTYPE
#ifdef __cplusplus
-%{ $result = new $1_ltype((const $1_ltype &)$1); %}
+%{ $result = new $1_ltype($1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index 1d97cb089..535e8d576 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -52,7 +52,7 @@
%typemap(out) SWIGTYPE
#ifdef __cplusplus
-%{ $result = new $1_ltype((const $1_ltype &)$1); %}
+%{ $result = new $1_ltype($1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
diff --git a/Lib/guile/typemaps.i b/Lib/guile/typemaps.i
index f4d3a0118..4ad1aefa8 100644
--- a/Lib/guile/typemaps.i
+++ b/Lib/guile/typemaps.i
@@ -130,7 +130,7 @@
#ifdef __cplusplus
{
$&1_ltype resultptr;
- resultptr = new $1_ltype((const $1_ltype &) $1);
+ resultptr = new $1_ltype($1);
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 1);
}
#else
@@ -145,8 +145,7 @@
%typemap(varout) SWIGTYPE
#ifdef __cplusplus
{
- $&1_ltype resultptr;
- resultptr = new $1_ltype((const $1_ltype&) $1);
+ $&1_ltype resultptr = ($&1_ltype)&$1;
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 0);
}
#else
diff --git a/Lib/java/java.swg b/Lib/java/java.swg
index 8f95f3a3b..7967c1882 100644
--- a/Lib/java/java.swg
+++ b/Lib/java/java.swg
@@ -665,7 +665,7 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
%typemap(out) SWIGTYPE
#ifdef __cplusplus
-%{ *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1); %}
+%{ *($&1_ltype*)&$result = new $1_ltype($1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
diff --git a/Lib/lua/luatypemaps.swg b/Lib/lua/luatypemaps.swg
index f8e12846b..97ecef41e 100644
--- a/Lib/lua/luatypemaps.swg
+++ b/Lib/lua/luatypemaps.swg
@@ -217,7 +217,7 @@ $1=($1_ltype)&temp;%}
#ifdef __cplusplus
%typemap(out) SWIGTYPE
{
- $&1_ltype resultptr = new $1_ltype((const $1_ltype &) $1);
+ $&1_ltype resultptr = new $1_ltype($1);
SWIG_NewPointerObj(L,(void *) resultptr,$&1_descriptor,1); SWIG_arg++;
}
#else
diff --git a/Lib/mzscheme/typemaps.i b/Lib/mzscheme/typemaps.i
index 09bda2cca..059dd06ff 100644
--- a/Lib/mzscheme/typemaps.i
+++ b/Lib/mzscheme/typemaps.i
@@ -127,7 +127,7 @@
#ifdef __cplusplus
{
$&1_ltype resultptr;
- resultptr = new $1_ltype(($1_ltype &) $1);
+ resultptr = new $1_ltype($1);
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 1);
}
#else
diff --git a/Lib/ocaml/ocaml.swg b/Lib/ocaml/ocaml.swg
index afb01daea..0c190bbc4 100644
--- a/Lib/ocaml/ocaml.swg
+++ b/Lib/ocaml/ocaml.swg
@@ -93,10 +93,14 @@
$1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ;
}
+%typemap(varout) SWIGTYPE {
+ $result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)&$1, $&1_descriptor);
+}
+
#ifdef __cplusplus
%typemap(out) SWIGTYPE {
- $&1_ltype temp = new $ltype((const $1_ltype &) $1);
+ $&1_ltype temp = new $1_ltype($1);
$result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)temp, $&1_descriptor);
}
@@ -110,6 +114,10 @@
#endif
+%typemap(varout) SWIGTYPE * {
+ $result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)$1, $1_descriptor);
+}
+
%typemap(directorin) SWIGTYPE {
$<ype temp = new $ltype((const $ltype &)$1);
swig_result = SWIG_Ocaml_ptr_to_val("create_$ltype_from_ptr", (void *)temp, $&1_descriptor);
diff --git a/Lib/ocaml/std_string.i b/Lib/ocaml/std_string.i
index 712c3bb73..a8881a16c 100644
--- a/Lib/ocaml/std_string.i
+++ b/Lib/ocaml/std_string.i
@@ -83,9 +83,18 @@ class wstring;
$result = caml_val_string_len($1.c_str(),$1.size());
}
+%typemap(varout) string {
+ $result = caml_val_string_len($1.c_str(),$1.size());
+}
+
%typemap(out) string * {
$result = caml_val_string_len((*$1).c_str(),(*$1).size());
}
+
+%typemap(varout) string * {
+ $result = caml_val_string_len((*$1).c_str(),(*$1).size());
+}
+
%typemap(typecheck) string, const string & = char *;
}
diff --git a/Lib/php/php.swg b/Lib/php/php.swg
index ffcffde70..7d6d5f29d 100644
--- a/Lib/php/php.swg
+++ b/Lib/php/php.swg
@@ -443,7 +443,7 @@
%typemap(out, phptype="SWIGTYPE") SWIGTYPE
{
#ifdef __cplusplus
- $&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1);
+ $&1_ltype resultobj = new $1_ltype($1);
#else
$&1_ltype resultobj = ($&1_ltype) malloc(sizeof($1_type));
memcpy(resultobj, &$1, sizeof($1_type));
diff --git a/Lib/ruby/std_set.i b/Lib/ruby/std_set.i
index e38702ef5..1b425c6b5 100644
--- a/Lib/ruby/std_set.i
+++ b/Lib/ruby/std_set.i
@@ -180,17 +180,14 @@
// Redefine std::set iterator/reverse_iterator typemap
%typemap(out,noblock=1) iterator, reverse_iterator {
- $result = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,const $type &),
- self),
- swig::Iterator::descriptor(),SWIG_POINTER_OWN);
+ $result = SWIG_NewPointerObj((swig::make_set_nonconst_iterator<$type>($1, self)), swig::Iterator::descriptor(), SWIG_POINTER_OWN);
}
// Redefine std::set std::pair typemap
%typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
std::pair {
$result = rb_ary_new2(2);
- rb_ary_push($result, SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,$type &).first),
- swig::Iterator::descriptor(),SWIG_POINTER_OWN));
+ rb_ary_push($result, SWIG_NewPointerObj((swig::make_set_nonconst_iterator($1.first)), swig::Iterator::descriptor(), SWIG_POINTER_OWN));
rb_ary_push($result, SWIG_From(bool)(%static_cast($1,const $type &).second));
}
diff --git a/Lib/swig.swg b/Lib/swig.swg
index f6ba3a69f..188c47e03 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -677,10 +677,12 @@ template class SwigValueWrapper {
public:
SwigValueWrapper() : pointer(0) { }
SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; }
-#if __cplusplus >= 201103L
+#if __cplusplus >=201103L
SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; }
-#endif
+ operator T&&() const { return std::move(*pointer.ptr); }
+#else
operator T&() const { return *pointer.ptr; }
+#endif
T *operator&() { return pointer.ptr; }
};%}
diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg
index 402313ebf..6973e3a10 100644
--- a/Lib/typemaps/swigtype.swg
+++ b/Lib/typemaps/swigtype.swg
@@ -146,9 +146,15 @@
}
/* Return by value */
+#ifdef __cplusplus
%typemap(out, noblock=1) SWIGTYPE {
- %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+ %set_output(SWIG_NewPointerObj((new $1_ltype($1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
}
+#else
+%typemap(out, noblock=1) SWIGTYPE {
+ %set_output(SWIG_NewPointerObj(%new_copy($1, $1_ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+}
+#endif
/* -----------------------------------------------------------------------------
* --- Variable input ---
@@ -534,7 +540,7 @@
* ------------------------------------------------------------ */
%typemap(throws,noblock=1) SWIGTYPE {
- %raise(SWIG_NewPointerObj(%new_copy($1, $ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor);
+ %raise(SWIG_NewPointerObj(%new_copy($1, $1_ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor);
}
%typemap(throws,noblock=1) SWIGTYPE * {
@@ -703,9 +709,15 @@
/* INSTANCE typemap */
+#ifdef __cplusplus
+%typemap(out,noblock=1) SWIGTYPE INSTANCE {
+ %set_output(SWIG_NewInstanceObj((new $1_ltype($1)), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
+}
+#else
%typemap(out,noblock=1) SWIGTYPE INSTANCE {
%set_output(SWIG_NewInstanceObj(%new_copy($1, $1_ltype), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
}
+#endif
%typemap(out,noblock=1) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] {
%set_output(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, $owner | %newinstance_flags));
From 7cab5accef810642e500194debecedfcad940deb Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Wed, 29 Jun 2022 22:46:03 +0100
Subject: [PATCH 487/662] SwigValueWrapper::operator& should always have been
const
---
Lib/swig.swg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 188c47e03..416d40982 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -683,7 +683,7 @@ public:
#else
operator T&() const { return *pointer.ptr; }
#endif
- T *operator&() { return pointer.ptr; }
+ T *operator&() const { return pointer.ptr; }
};%}
/*
From 1993b334a6583aaec1ce28000c3b3a1ae0406d5d Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Thu, 30 Jun 2022 17:28:25 +0100
Subject: [PATCH 488/662] Generate swiglabels code earlier on in runtime code
Since the recent inclusion of , the warning suppressions in
swiglabels.swg stopped working as they appear after this include file.
In particular, The _MSC_VER warnings were not working.
---
Lib/swig.swg | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 416d40982..ca7586457 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -602,6 +602,10 @@ namespace std {
* Runtime code
* ----------------------------------------------------------------------------- */
+
+%insert("runtime") "swiglabels.swg"
+
+
/* The SwigValueWrapper class */
/*
@@ -703,8 +707,3 @@ template T SwigValueInit() {
%}
#endif
-/* The swiglabels */
-
-%insert("runtime") "swiglabels.swg"
-
-
From 299880e6a658934d39ae3b53159a3b61f1051c16 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 2 Jul 2022 16:06:32 +0100
Subject: [PATCH 489/662] Add std::unique support
Simple copy of current auto_ptr support (just suppport for
functions returning std::unique_ptr).
Closes #1722
---
CHANGES.current | 10 ++
Doc/Manual/CPlusPlus11.html | 6 +-
Doc/Manual/Contents.html | 1 +
Doc/Manual/Library.html | 117 ++++++++++++++++--
Examples/test-suite/common.mk | 1 +
Examples/test-suite/cpp11_std_unique_ptr.i | 53 ++++++++
.../csharp/cpp11_std_unique_ptr_runme.cs | 64 ++++++++++
.../java/cpp11_std_unique_ptr_runme.java | 68 ++++++++++
.../python/cpp11_std_unique_ptr_runme.py | 17 +++
.../ruby/cpp11_std_unique_ptr_runme.rb | 27 ++++
Lib/csharp/std_unique_ptr.i | 27 ++++
Lib/java/std_unique_ptr.i | 29 +++++
Lib/python/std_unique_ptr.i | 19 +++
Lib/ruby/std_unique_ptr.i | 19 +++
14 files changed, 443 insertions(+), 15 deletions(-)
create mode 100644 Examples/test-suite/cpp11_std_unique_ptr.i
create mode 100644 Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs
create mode 100644 Examples/test-suite/java/cpp11_std_unique_ptr_runme.java
create mode 100644 Examples/test-suite/python/cpp11_std_unique_ptr_runme.py
create mode 100644 Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb
create mode 100644 Lib/csharp/std_unique_ptr.i
create mode 100644 Lib/java/std_unique_ptr.i
create mode 100644 Lib/python/std_unique_ptr.i
create mode 100644 Lib/ruby/std_unique_ptr.i
diff --git a/CHANGES.current b/CHANGES.current
index 6584e1781..57dd6c765 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,16 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-07-02: wsfulton
+ #1722 [C#, Java, Python, Ruby] Add std::unique_ptr support. Ported from std::auto_ptr.
+ Use the %unique_ptr(T) macro as follows for usage std::unique_ptr. For example, for
+ a class called Klass:
+
+ %include "std_unique_ptr.i"
+ %unique_ptr(Klass)
+
+ Support is currently limited to only returning a std::unique_ptr from a function.
+
2022-06-29: wsfulton
#999 #1044 Enhance SWIGTYPE "out" typemaps to use std::move when copying
objects, thereby making use of move semantics when wrapping a function returning
diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html
index b98713961..52764eeef 100644
--- a/Doc/Manual/CPlusPlus11.html
+++ b/Doc/Manual/CPlusPlus11.html
@@ -1236,8 +1236,10 @@ While SWIG could provide wrappers for the new C++11 regular expressions classes,
SWIG provides special smart pointer handling for std::shared_ptr in the same way it has support for boost::shared_ptr.
-Please see the shared_ptr smart pointer library section.
-There is no special smart pointer handling available for std::weak_ptr and std::unique_ptr yet.
+Please see the shared_ptr smart pointer
+and unique_ptr smart pointer library sections.
+There is no special smart pointer handling available for std::weak_ptr.
+
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index ef87cf78d..39d83bd14 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -448,6 +448,7 @@
- shared_ptr and templates
- shared_ptr and directors
+
- unique_ptr smart pointer
- auto_ptr smart pointer
- Utility Libraries
diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html
index 3ecfc3a39..b18ecc957 100644
--- a/Doc/Manual/Library.html
+++ b/Doc/Manual/Library.html
@@ -40,6 +40,7 @@
- shared_ptr and templates
- shared_ptr and directors
+
- unique_ptr smart pointer
- auto_ptr smart pointer
- Utility Libraries
@@ -2040,38 +2041,45 @@ The SWIG code below shows the required ordering:
The languages that support shared_ptr also have support for using shared_ptr with directors.
-
-
+
-While std::auto_ptr is deprecated in C++11, some existing code may
-still be using it, so SWIG provides limited support for this class:
-std_auto_ptr.i defines the typemaps which apply to the functions
-returning objects of this type. Any other use of std_auto_ptr.i is not
-directly supported.
+The std_unique_ptr.i library file provides SWIG's unique_ptr support.
+It defines typemaps and a macro, %unique_ptr(T), to use for handling
+std::unique_ptr<T> for a type T.
+The type T must be non-primitive.
+This macro should be used before any code declaring or using type T.
+Ordering requirements for using this smart pointer macro are the same as the
+equivalent %shared_ptr(T) macro covered in the previous section.
-A typical example of use would be
+Note that the support provided is limited to returning this smart pointer from a function.
+Any other use of std::auto_ptr is not directly provided yet.
+
+
+
+Example usage would be
-%include <std_auto_ptr.i>
+%include <std_unique_ptr.i>
-%auto_ptr(Klass)
+%unique_ptr(Klass)
%inline %{
+#include <memory>
class Klass {
public:
// Factory function creating objects of this class:
- static std::auto_ptr<Klass> Create(int value) {
- return std::auto_ptr<Klass>(new Klass(value));
+ static std::unique_ptr<Klass> Create(int value) {
+ return std::unique_ptr<Klass>(new Klass(value));
}
int getValue() const { return m_value; }
private:
- DerivedIntValue(int value) : m_value(value) {}
+ Klass(int value) : m_value(value) {}
int m_value;
};
%}
@@ -2090,6 +2098,89 @@ int value = k.getValue();
+
+The implementation simply calls std::unique_ptr::release() to obtain
+the underlying raw pointer. The pointer is then used to create a target language
+proxy class in the same way that SWIG handles a C++ function returning a class by value.
+The target language proxy class then owns the memory pointed to by the raw pointer
+and memory handling is identical to normal SWIG proxy class handling of the underlying C++ memory.
+Note that an object returned by value is first copied/moved from the stack onto the heap in order to obtain
+a raw pointer on the heap, whereas the underlying raw pointer in std::unique_ptr already points to an object the heap.
+
+
+
+Note that the implementation is quite different to the std::shared_ptr smart pointer,
+where the proxy class manages the underlying C++ memory as a pointer to a shared_ptr instead of a plain raw pointer.
+
+
+
+
+
+
+While std::auto_ptr is deprecated in C++11, some existing code may
+still be using it, so SWIG provides limited support for this class by some target languages.
+
+
+
+The std_auto_ptr.i library file provides SWIG's auto_ptr support.
+It defines typemaps and a macro, %auto_ptr(T), to use for handling
+std::auto_ptr<T> for a type T.
+The type T must be non-primitive.
+This macro should be used before any code declaring or using type T.
+Ordering requirements for using this smart pointer macro are the same as the
+equivalent %shared_ptr(T) and %unique_ptr macros covered in
+the previous two sections.
+
+
+
+Note that the support provided is limited to returning this smart pointer from a function.
+Any other use of std::auto_ptr is not directly provided.
+
+
+
+Example usage would be
+
+
+
+%include <std_auto_ptr.i>
+
+%auto_ptr(Klass)
+%inline %{
+#include <memory>
+class Klass {
+public:
+ // Factory function creating objects of this class:
+ static std::auto_ptr<Klass> Create(int value) {
+ return std::auto_ptr<Klass>(new Klass(value));
+ }
+
+ int getValue() const { return m_value; }
+
+private:
+ Klass(int value) : m_value(value) {}
+ int m_value;
+};
+%}
+
+
+
+
+The returned objects can be used naturally from the target language, e.g. from
+C#:
+
+
+
+
+Klass k = Klass.Create(17);
+int value = k.getValue();
+
+
+
+
+The implementation simply calls std::auto_ptr::release() to obtain the underlying raw pointer.
+That is, it works the same way covered in the previous section for std::unique_ptr.
+
+
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index a640febc1..bf0e52f02 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -612,6 +612,7 @@ CPP11_TEST_CASES += \
cpp11_sizeof_object \
cpp11_static_assert \
cpp11_std_array \
+ cpp11_std_unique_ptr \
cpp11_strongly_typed_enumerations \
cpp11_thread_local \
cpp11_template_double_brackets \
diff --git a/Examples/test-suite/cpp11_std_unique_ptr.i b/Examples/test-suite/cpp11_std_unique_ptr.i
new file mode 100644
index 000000000..518d9be6e
--- /dev/null
+++ b/Examples/test-suite/cpp11_std_unique_ptr.i
@@ -0,0 +1,53 @@
+%module cpp11_std_unique_ptr
+
+#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY)
+
+%include "std_unique_ptr.i"
+
+%unique_ptr(Klass)
+
+%inline %{
+#include
+#include
+#include "swig_examples_lock.h"
+
+class Klass {
+public:
+ explicit Klass(const char* label) :
+ m_label(label)
+ {
+ SwigExamples::Lock lock(critical_section);
+ total_count++;
+ }
+
+ const char* getLabel() const { return m_label.c_str(); }
+
+ ~Klass()
+ {
+ SwigExamples::Lock lock(critical_section);
+ total_count--;
+ }
+
+ static int getTotal_count() { return total_count; }
+
+private:
+ static SwigExamples::CriticalSection critical_section;
+ static int total_count;
+
+ std::string m_label;
+};
+
+SwigExamples::CriticalSection Klass::critical_section;
+int Klass::total_count = 0;
+
+%}
+
+%inline %{
+
+std::unique_ptr makeKlassUniquePtr(const char* label) {
+ return std::unique_ptr(new Klass(label));
+}
+
+%}
+
+#endif
diff --git a/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs b/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs
new file mode 100644
index 000000000..db5c8cff0
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs
@@ -0,0 +1,64 @@
+using System;
+using cpp11_std_unique_ptrNamespace;
+
+public class cpp11_std_unique_ptr_runme {
+ private static void WaitForGC()
+ {
+ System.GC.Collect();
+ System.GC.WaitForPendingFinalizers();
+ System.Threading.Thread.Sleep(10);
+ }
+
+ public static void Main()
+ {
+ Klass k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+ if (k1.getLabel() != "first")
+ throw new Exception("wrong object label");
+
+ Klass k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+ if (Klass.getTotal_count() != 2)
+ throw new Exception("number of objects should be 2");
+
+ using (Klass k3 = cpp11_std_unique_ptr.makeKlassUniquePtr("second")) {
+ if (Klass.getTotal_count() != 3)
+ throw new Exception("number of objects should be 3");
+ }
+ if (Klass.getTotal_count() != 2)
+ throw new Exception("number of objects should be 2");
+
+ k1 = null;
+ {
+ int countdown = 500;
+ int expectedCount = 1;
+ while (true) {
+ WaitForGC();
+ if (--countdown == 0)
+ break;
+ if (Klass.getTotal_count() == expectedCount)
+ break;
+ };
+ int actualCount = Klass.getTotal_count();
+ if (actualCount != expectedCount)
+ Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
+ }
+
+ if (k2.getLabel() != "second")
+ throw new Exception("wrong object label");
+
+ k2 = null;
+ {
+ int countdown = 500;
+ int expectedCount = 0;
+ while (true) {
+ WaitForGC();
+ if (--countdown == 0)
+ break;
+ if (Klass.getTotal_count() == expectedCount)
+ break;
+ }
+ int actualCount = Klass.getTotal_count();
+ if (actualCount != expectedCount)
+ Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
+ }
+ }
+}
diff --git a/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java b/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java
new file mode 100644
index 000000000..a734b0e5e
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java
@@ -0,0 +1,68 @@
+import cpp11_std_unique_ptr.*;
+
+public class cpp11_std_unique_ptr_runme {
+ static {
+ try {
+ System.loadLibrary("cpp11_std_unique_ptr");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ private static void WaitForGC()
+ {
+ System.gc();
+ System.runFinalization();
+ try {
+ java.lang.Thread.sleep(10);
+ } catch (java.lang.InterruptedException e) {
+ }
+ }
+
+ public static void main(String argv[]) throws Throwable
+ {
+ Klass k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+ if (!k1.getLabel().equals("first"))
+ throw new RuntimeException("wrong object label");
+
+ Klass k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+ if (Klass.getTotal_count() != 2)
+ throw new RuntimeException("number of objects should be 2");
+
+ k1 = null;
+ {
+ int countdown = 500;
+ int expectedCount = 1;
+ while (true) {
+ WaitForGC();
+ if (--countdown == 0)
+ break;
+ if (Klass.getTotal_count() == expectedCount)
+ break;
+ }
+ int actualCount = Klass.getTotal_count();
+ if (actualCount != expectedCount)
+ System.err.println("GC failed to run (cpp11_std_unique_ptr 1). Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
+ }
+
+ if (!k2.getLabel().equals("second"))
+ throw new RuntimeException("wrong object label");
+
+ k2 = null;
+ {
+ int countdown = 500;
+ int expectedCount = 0;
+ while (true) {
+ WaitForGC();
+ if (--countdown == 0)
+ break;
+ if (Klass.getTotal_count() == expectedCount)
+ break;
+ };
+ int actualCount = Klass.getTotal_count();
+ if (actualCount != expectedCount)
+ System.err.println("GC failed to run (cpp11_std_unique_ptr 2). Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
+ }
+ }
+}
diff --git a/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py b/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py
new file mode 100644
index 000000000..a84efcd5f
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py
@@ -0,0 +1,17 @@
+from cpp11_std_unique_ptr import *
+
+k1 = makeKlassUniquePtr("first")
+k2 = makeKlassUniquePtr("second")
+if Klass.getTotal_count() != 2:
+ raise "number of objects should be 2"
+
+del k1
+if Klass.getTotal_count() != 1:
+ raise "number of objects should be 1"
+
+if k2.getLabel() != "second":
+ raise "wrong object label"
+
+del k2
+if Klass.getTotal_count() != 0:
+ raise "no objects should be left"
diff --git a/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb b/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb
new file mode 100644
index 000000000..cfc03fe2a
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'cpp11_std_unique_ptr'
+
+def gc_check(expected_count)
+# GC.start(full_mark: true, immediate_sweep: true)
+ GC.start
+# GC is not reliably run, skip check
+# swig_assert_equal_simple(expected_count, Cpp11_std_unique_ptr::Klass::getTotal_count())
+end
+
+k1 = Cpp11_std_unique_ptr::makeKlassUniquePtr("first")
+k2 = Cpp11_std_unique_ptr::makeKlassUniquePtr("second")
+swig_assert_equal_simple(2, Cpp11_std_unique_ptr::Klass::getTotal_count())
+
+gc_check(2)
+k1 = nil
+gc_check(1)
+
+swig_assert_equal_simple(k2.getLabel(), "second")
+gc_check(1)
+
+k2 = nil
+gc_check(0)
+
diff --git a/Lib/csharp/std_unique_ptr.i b/Lib/csharp/std_unique_ptr.i
new file mode 100644
index 000000000..b2716756a
--- /dev/null
+++ b/Lib/csharp/std_unique_ptr.i
@@ -0,0 +1,27 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::unique_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (ctype) std::unique_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::unique_ptr< TYPE > "HandleRef"
+%typemap (cstype) std::unique_ptr< TYPE > "$typemap(cstype, TYPE)"
+%typemap (out) std::unique_ptr< TYPE > %{
+ $result = (void *)$1.release();
+%}
+%typemap(csout, excode=SWIGEXCODE) std::unique_ptr< TYPE > {
+ System.IntPtr cPtr = $imcall;
+ $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
+ return ret;
+ }
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template class unique_ptr {};
+}
diff --git a/Lib/java/std_unique_ptr.i b/Lib/java/std_unique_ptr.i
new file mode 100644
index 000000000..665d913ae
--- /dev/null
+++ b/Lib/java/std_unique_ptr.i
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::unique_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (jni) std::unique_ptr< TYPE > "jlong"
+%typemap (jtype) std::unique_ptr< TYPE > "long"
+%typemap (jstype) std::unique_ptr< TYPE > "$typemap(jstype, TYPE)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ jlong lpp = 0;
+ *(TYPE **) &lpp = $1.release();
+ $result = lpp;
+%}
+%typemap(javaout) std::unique_ptr< TYPE > {
+ long cPtr = $jnicall;
+ return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
+ }
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template class unique_ptr {};
+}
diff --git a/Lib/python/std_unique_ptr.i b/Lib/python/std_unique_ptr.i
new file mode 100644
index 000000000..331817f76
--- /dev/null
+++ b/Lib/python/std_unique_ptr.i
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::unique_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template class unique_ptr {};
+}
diff --git a/Lib/ruby/std_unique_ptr.i b/Lib/ruby/std_unique_ptr.i
new file mode 100644
index 000000000..163c7c2d1
--- /dev/null
+++ b/Lib/ruby/std_unique_ptr.i
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::unique_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (out) std::unique_ptr< TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template class unique_ptr {};
+}
From 980e21a3bf371ee8dbeb8276a5d61861e749fa7b Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sat, 2 Jul 2022 16:12:16 +0100
Subject: [PATCH 490/662] Cosmetic changes to auto_ptr library files
---
Lib/csharp/std_auto_ptr.i | 26 ++++++++++++++------------
Lib/java/std_auto_ptr.i | 28 +++++++++++++++-------------
Lib/python/std_auto_ptr.i | 18 ++++++++++--------
Lib/ruby/std_auto_ptr.i | 18 ++++++++++--------
4 files changed, 49 insertions(+), 41 deletions(-)
diff --git a/Lib/csharp/std_auto_ptr.i b/Lib/csharp/std_auto_ptr.i
index 1d91c9872..068d3a9d1 100644
--- a/Lib/csharp/std_auto_ptr.i
+++ b/Lib/csharp/std_auto_ptr.i
@@ -1,23 +1,25 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::auto_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (ctype) std::auto_ptr "void *"
-%typemap (imtype, out="System.IntPtr") std::auto_ptr "HandleRef"
-%typemap (cstype) std::auto_ptr "$typemap(cstype, TYPE)"
-%typemap (out) std::auto_ptr %{
+%typemap (ctype) std::auto_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::auto_ptr< TYPE > "HandleRef"
+%typemap (cstype) std::auto_ptr< TYPE > "$typemap(cstype, TYPE)"
+%typemap (out) std::auto_ptr< TYPE > %{
$result = (void *)$1.release();
%}
-%typemap(csout, excode=SWIGEXCODE) std::auto_ptr {
+%typemap(csout, excode=SWIGEXCODE) std::auto_ptr< TYPE > {
System.IntPtr cPtr = $imcall;
$typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
return ret;
}
-%template() std::auto_ptr;
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
diff --git a/Lib/java/std_auto_ptr.i b/Lib/java/std_auto_ptr.i
index 69ac2841f..0eb5fe155 100644
--- a/Lib/java/std_auto_ptr.i
+++ b/Lib/java/std_auto_ptr.i
@@ -1,25 +1,27 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::auto_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (jni) std::auto_ptr "jlong"
-%typemap (jtype) std::auto_ptr "long"
-%typemap (jstype) std::auto_ptr "$typemap(jstype, TYPE)"
+%typemap (jni) std::auto_ptr< TYPE > "jlong"
+%typemap (jtype) std::auto_ptr< TYPE > "long"
+%typemap (jstype) std::auto_ptr< TYPE > "$typemap(jstype, TYPE)"
-%typemap (out) std::auto_ptr %{
+%typemap (out) std::auto_ptr< TYPE > %{
jlong lpp = 0;
- *(TYPE**) &lpp = $1.release();
+ *(TYPE **) &lpp = $1.release();
$result = lpp;
%}
-%typemap(javaout) std::auto_ptr {
+%typemap(javaout) std::auto_ptr< TYPE > {
long cPtr = $jnicall;
return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
}
-%template() std::auto_ptr;
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
diff --git a/Lib/python/std_auto_ptr.i b/Lib/python/std_auto_ptr.i
index c94006a68..fb044f851 100644
--- a/Lib/python/std_auto_ptr.i
+++ b/Lib/python/std_auto_ptr.i
@@ -1,15 +1,17 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::auto_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (out) std::auto_ptr %{
+%typemap (out) std::auto_ptr< TYPE > %{
%set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
%}
-%template() std::auto_ptr;
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
diff --git a/Lib/ruby/std_auto_ptr.i b/Lib/ruby/std_auto_ptr.i
index eab8ec53d..ecaea2b0f 100644
--- a/Lib/ruby/std_auto_ptr.i
+++ b/Lib/ruby/std_auto_ptr.i
@@ -1,15 +1,17 @@
-/*
- The typemaps here allow handling functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * The typemaps here allow handling functions returning std::auto_ptr<>,
+ * which is the most common use of this type. If you have functions taking it
+ * as parameter, these typemaps can't be used for them and you need to do
+ * something else (e.g. use shared_ptr<> which SWIG supports fully).
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (out) std::auto_ptr %{
+%typemap (out) std::auto_ptr< TYPE > %{
%set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
%}
-%template() std::auto_ptr;
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
From e75095e6c56ac45aba7aaafb4c732e1f1c675591 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 3 Jul 2022 13:35:08 +0100
Subject: [PATCH 491/662] Add OCaml throws typemaps for std::string
---
Lib/ocaml/std_string.i | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Lib/ocaml/std_string.i b/Lib/ocaml/std_string.i
index a8881a16c..2564cfb38 100644
--- a/Lib/ocaml/std_string.i
+++ b/Lib/ocaml/std_string.i
@@ -96,6 +96,9 @@ class wstring;
}
%typemap(typecheck) string, const string & = char *;
+
+%typemap(throws) string, const string & "SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, $1.c_str());"
+
}
#ifdef ENABLE_CHARPTR_ARRAY
From 71cd6a38fe539a89dc2ee159c6d54017fd4e90a0 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Sun, 3 Jul 2022 13:58:26 +0100
Subject: [PATCH 492/662] Performance optimisation for directors for classes
passed by value
The directorin typemaps in the director methods now use std::move on the
input parameter when copying the object from the stack to the heap prior
to the callback into the target language, thereby taking advantage of
move semantics if available.
---
CHANGES.current | 6 +++
.../csharp/director_pass_by_value_runme.cs | 2 +
Examples/test-suite/director_pass_by_value.i | 41 +++++++++++++++++--
.../java/director_pass_by_value_runme.java | 2 +
.../ocaml/director_pass_by_value_runme.ml | 3 ++
.../php/director_pass_by_value_runme.php | 3 ++
.../python/director_pass_by_value_runme.py | 2 +
Lib/csharp/boost_shared_ptr.i | 2 +-
Lib/csharp/csharp.swg | 2 +-
Lib/d/boost_shared_ptr.i | 2 +-
Lib/d/dswigtype.swg | 2 +-
Lib/go/go.swg | 2 +-
Lib/java/boost_shared_ptr.i | 2 +-
Lib/java/java.swg | 2 +-
Lib/java/swiginterface.i | 2 +-
Lib/ocaml/ocaml.swg | 2 +-
Lib/octave/boost_shared_ptr.i | 2 +-
Lib/php/php.swg | 2 +-
Lib/python/boost_shared_ptr.i | 2 +-
Lib/r/boost_shared_ptr.i | 2 +-
Lib/ruby/boost_shared_ptr.i | 2 +-
Lib/scilab/boost_shared_ptr.i | 2 +-
Lib/swig.swg | 9 ++++
Lib/typemaps/swigtype.swg | 2 +-
24 files changed, 80 insertions(+), 20 deletions(-)
diff --git a/CHANGES.current b/CHANGES.current
index 57dd6c765..9adfa8ad0 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-07-03: wsfulton
+ Performane optimisation for directors for classes passed by value. The directorin
+ typemaps in the director methods now use std::move on the input parameter when
+ copying the object from the stack to the heap prior to the callback into the target
+ language, thereby taking advantage of move semantics if available.
+
2022-07-02: wsfulton
#1722 [C#, Java, Python, Ruby] Add std::unique_ptr support. Ported from std::auto_ptr.
Use the %unique_ptr(T) macro as follows for usage std::unique_ptr. For example, for
diff --git a/Examples/test-suite/csharp/director_pass_by_value_runme.cs b/Examples/test-suite/csharp/director_pass_by_value_runme.cs
index ba6371590..1f64f6d7e 100644
--- a/Examples/test-suite/csharp/director_pass_by_value_runme.cs
+++ b/Examples/test-suite/csharp/director_pass_by_value_runme.cs
@@ -28,6 +28,8 @@ public class runme
break;
};
}
+ if (director_pass_by_value.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 1, 0, 1); // check move constructor called and just one destructor
// bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
int ret = runme.passByVal.getVal();
if (ret != 0x12345678)
diff --git a/Examples/test-suite/director_pass_by_value.i b/Examples/test-suite/director_pass_by_value.i
index 31d8ce2d2..5e31c9d3b 100644
--- a/Examples/test-suite/director_pass_by_value.i
+++ b/Examples/test-suite/director_pass_by_value.i
@@ -1,14 +1,38 @@
%module(directors="1") director_pass_by_value
+
+#if defined(SWIGD)
+%rename(trace) debug;
+#endif
+
%director DirectorPassByValueAbstractBase;
+%include "cpp11_move_only_helper.i"
+
+%ignore PassedByValue::operator=;
+%ignore PassedByValue::PassedByValue(PassedByValue &&);
+
%inline %{
-class PassedByValue {
- int val;
-public:
- PassedByValue() { val = 0x12345678; }
+#include
+using namespace std;
+int debug = false;
+struct PassedByValue {
+ PassedByValue(int v = 0x12345678) { val = v; if (debug) cout << "PassedByValue(0x" << hex << val << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+ PassedByValue(const PassedByValue &other) { val = other.val; if (debug) cout << "PassedByValue(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+ PassedByValue & operator=(const PassedByValue &other) { val = other.val; if (debug) cout << "operator=(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
+
+#if __cplusplus >= 201103L
+ PassedByValue(PassedByValue &&other) noexcept { val = other.val; if (debug) cout << "PassedByValue(PassedByValue &&)" << " " << this << endl; Counter::move_constructor++; }
+ PassedByValue & operator=(PassedByValue &&other) noexcept { val = other.val; if (debug) cout << "operator=(PassedByValue &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
+ ~PassedByValue() { if (debug) cout << "~PassedByValue()" << " " << this << endl; Counter::destructor++; }
+#endif
+
int getVal() { return val; }
+private:
+ int val;
};
+
int doSomething(int x) {
int yy[256];
yy[0] =0x9876;
@@ -18,6 +42,7 @@ int doSomething(int x) {
class DirectorPassByValueAbstractBase {
public:
virtual void virtualMethod(PassedByValue pbv) = 0;
+ virtual void virtualConstMethod(const PassedByValue pbv) {}
virtual ~DirectorPassByValueAbstractBase () {}
};
@@ -27,4 +52,12 @@ public:
f.virtualMethod(PassedByValue());
}
};
+
+bool has_cplusplus11() {
+#if __cplusplus >= 201103L
+ return true;
+#else
+ return false;
+#endif
+}
%}
diff --git a/Examples/test-suite/java/director_pass_by_value_runme.java b/Examples/test-suite/java/director_pass_by_value_runme.java
index 24ded2ccf..1d34c3b55 100644
--- a/Examples/test-suite/java/director_pass_by_value_runme.java
+++ b/Examples/test-suite/java/director_pass_by_value_runme.java
@@ -32,6 +32,8 @@ public class director_pass_by_value_runme {
break;
};
}
+ if (director_pass_by_value.has_cplusplus11())
+ Counter.check_counts(1, 0, 0, 1, 0, 1); // check move constructor called and just one destructor
// bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
int ret = director_pass_by_value_runme.passByVal.getVal();
if (ret != 0x12345678)
diff --git a/Examples/test-suite/ocaml/director_pass_by_value_runme.ml b/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
index af862f189..ce2137fbe 100644
--- a/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
+++ b/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
@@ -14,10 +14,13 @@ let d =
(director_pass_by_value_Derived)
'()
+let cpp11 = _has_cplusplus11 '() as bool
+
let _ =
let caller = new_Caller '() in
assert (caller -> call_virtualMethod (d) = C_void);
assert (Array.length !passByVal = 1);
+(* TODO: only run if cpp11... let _ = _Counter_check_counts (C_list [C_int 0; C_int 0; C_int 0; C_int 1; C_int 0; C_int 1]) in*) (* check move constructor called and just one destructor *)
let a = List.hd (fnhelper (!passByVal.(0))) in
assert (a -> getVal () as int = 0x12345678);
assert (a -> "~" () = C_void);
diff --git a/Examples/test-suite/php/director_pass_by_value_runme.php b/Examples/test-suite/php/director_pass_by_value_runme.php
index d3763292f..b8f1bb9f9 100644
--- a/Examples/test-suite/php/director_pass_by_value_runme.php
+++ b/Examples/test-suite/php/director_pass_by_value_runme.php
@@ -14,6 +14,9 @@ class director_pass_by_value_Derived extends DirectorPassByValueAbstractBase {
# bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
$caller = new Caller();
$caller->call_virtualMethod(new director_pass_by_value_Derived());
+if (has_cplusplus11()) {
+ Counter::check_counts(1, 0, 0, 1, 0, 1); # check move constructor called and just one destructor
+}
$ret = $passByVal->getVal();
if ($ret != 0x12345678) {
check::fail("Bad return value, got " . dechex($ret));
diff --git a/Examples/test-suite/python/director_pass_by_value_runme.py b/Examples/test-suite/python/director_pass_by_value_runme.py
index 7744db962..9dbd64ad6 100644
--- a/Examples/test-suite/python/director_pass_by_value_runme.py
+++ b/Examples/test-suite/python/director_pass_by_value_runme.py
@@ -8,6 +8,8 @@ class director_pass_by_value_Derived(director_pass_by_value.DirectorPassByValueA
# bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
director_pass_by_value.Caller().call_virtualMethod(director_pass_by_value_Derived())
+if director_pass_by_value.has_cplusplus11():
+ director_pass_by_value.Counter.check_counts(1, 0, 0, 1, 0, 1) # check move constructor called and just one destructor
ret = passByVal.getVal();
if ret != 0x12345678:
raise RuntimeError("Bad return value, got " + hex(ret))
diff --git a/Lib/csharp/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i
index 508c0ec14..2bbb6e277 100644
--- a/Lib/csharp/boost_shared_ptr.i
+++ b/Lib/csharp/boost_shared_ptr.i
@@ -32,7 +32,7 @@
%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
%typemap(directorin) CONST TYPE
-%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
%typemap(directorout) CONST TYPE
%{ if (!$input) {
diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg
index d4bcd3c80..94e0458a6 100644
--- a/Lib/csharp/csharp.swg
+++ b/Lib/csharp/csharp.swg
@@ -409,7 +409,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
#endif
%typemap(directorin) SWIGTYPE
-%{ $input = (void *)new $1_ltype((const $1_ltype &)$1); %}
+%{ $input = (void *)new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(csdirectorin) SWIGTYPE "new $&csclassname($iminput, true)"
%typemap(csdirectorout) SWIGTYPE "$&csclassname.getCPtr($cscall).Handle"
diff --git a/Lib/d/boost_shared_ptr.i b/Lib/d/boost_shared_ptr.i
index 4a220a589..1018bd1f2 100644
--- a/Lib/d/boost_shared_ptr.i
+++ b/Lib/d/boost_shared_ptr.i
@@ -26,7 +26,7 @@
%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
%typemap(directorin) CONST TYPE
-%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
%typemap(directorout) CONST TYPE
%{ if (!$input) {
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index 535e8d576..3fb7f6a01 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -62,7 +62,7 @@
#endif
%typemap(directorin) SWIGTYPE
- "$input = (void *)new $1_ltype((const $1_ltype &)$1);"
+ "$input = (void *)new $1_ltype(SWIG_STD_MOVE($1));"
%typemap(directorout) SWIGTYPE
%{ if (!$input) {
SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
diff --git a/Lib/go/go.swg b/Lib/go/go.swg
index 6e415d2c1..bb7a471cc 100644
--- a/Lib/go/go.swg
+++ b/Lib/go/go.swg
@@ -625,7 +625,7 @@
%typemap(goout) SWIGTYPE ""
%typemap(directorin) SWIGTYPE
-%{ $input = new $1_ltype((const $1_ltype &)$1); %}
+%{ $input = new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(godirectorin) SWIGTYPE ""
diff --git a/Lib/java/boost_shared_ptr.i b/Lib/java/boost_shared_ptr.i
index 325a6832d..adf9c203e 100644
--- a/Lib/java/boost_shared_ptr.i
+++ b/Lib/java/boost_shared_ptr.i
@@ -33,7 +33,7 @@
%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") CONST TYPE
%{ $input = 0;
- *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+ *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
%typemap(directorout) CONST TYPE
%{ if (!$input) {
diff --git a/Lib/java/java.swg b/Lib/java/java.swg
index 7967c1882..23744aeb3 100644
--- a/Lib/java/java.swg
+++ b/Lib/java/java.swg
@@ -676,7 +676,7 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") SWIGTYPE
%{ $input = 0;
- *(($&1_ltype*)&$input) = new $1_ltype((const $1_ltype &)$1); %}
+ *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(javadirectorin) SWIGTYPE "new $&javaclassname($jniinput, true)"
%typemap(javadirectorout) SWIGTYPE "$&javaclassname.getCPtr($javacall)"
diff --git a/Lib/java/swiginterface.i b/Lib/java/swiginterface.i
index 0a0f7806a..c3ca97d36 100644
--- a/Lib/java/swiginterface.i
+++ b/Lib/java/swiginterface.i
@@ -40,7 +40,7 @@
%typemap(javadirectorout) CTYPE *const& "$javacall.$*interfacename_GetInterfaceCPtr()"
%typemap(directorin,descriptor="L$packagepath/$&javainterfacename;") CTYPE
%{ $input = 0;
- *(($&1_ltype*)&$input) = new $1_ltype((const $1_ltype &)$1); %}
+ *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(directorin,descriptor="L$packagepath/$javainterfacename;") CTYPE *, CTYPE []
%{ *(($&1_ltype)&$input) = ($1_ltype) $1; %}
%typemap(directorin,descriptor="L$packagepath/$javainterfacename;") CTYPE &
diff --git a/Lib/ocaml/ocaml.swg b/Lib/ocaml/ocaml.swg
index 0c190bbc4..ef0a64c90 100644
--- a/Lib/ocaml/ocaml.swg
+++ b/Lib/ocaml/ocaml.swg
@@ -119,7 +119,7 @@
}
%typemap(directorin) SWIGTYPE {
- $<ype temp = new $ltype((const $ltype &)$1);
+ $<ype temp = new $1_ltype(SWIG_STD_MOVE($1));
swig_result = SWIG_Ocaml_ptr_to_val("create_$ltype_from_ptr", (void *)temp, $&1_descriptor);
args = caml_list_append(args, swig_result);
}
diff --git a/Lib/octave/boost_shared_ptr.i b/Lib/octave/boost_shared_ptr.i
index 668bf4354..a1427b74d 100644
--- a/Lib/octave/boost_shared_ptr.i
+++ b/Lib/octave/boost_shared_ptr.i
@@ -59,7 +59,7 @@
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/php/php.swg b/Lib/php/php.swg
index 7d6d5f29d..c2442d24b 100644
--- a/Lib/php/php.swg
+++ b/Lib/php/php.swg
@@ -454,7 +454,7 @@
%typemap(directorin) SWIGTYPE
%{
ZVAL_UNDEF($input);
- SWIG_SetPointerZval($input, SWIG_as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&1_descriptor, 1);
+ SWIG_SetPointerZval($input, SWIG_as_voidptr(new $1_ltype(SWIG_STD_MOVE($1))), $&1_descriptor, 1);
%}
%typemap(out, phptype="void") void "";
diff --git a/Lib/python/boost_shared_ptr.i b/Lib/python/boost_shared_ptr.i
index 709e7811d..ab9962ac8 100644
--- a/Lib/python/boost_shared_ptr.i
+++ b/Lib/python/boost_shared_ptr.i
@@ -63,7 +63,7 @@
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/r/boost_shared_ptr.i b/Lib/r/boost_shared_ptr.i
index 668bf4354..a1427b74d 100644
--- a/Lib/r/boost_shared_ptr.i
+++ b/Lib/r/boost_shared_ptr.i
@@ -59,7 +59,7 @@
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/ruby/boost_shared_ptr.i b/Lib/ruby/boost_shared_ptr.i
index 9676bf9d8..fe3ea8cde 100644
--- a/Lib/ruby/boost_shared_ptr.i
+++ b/Lib/ruby/boost_shared_ptr.i
@@ -59,7 +59,7 @@
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/scilab/boost_shared_ptr.i b/Lib/scilab/boost_shared_ptr.i
index 668bf4354..a1427b74d 100644
--- a/Lib/scilab/boost_shared_ptr.i
+++ b/Lib/scilab/boost_shared_ptr.i
@@ -59,7 +59,7 @@
}
%typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
- smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
$input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
%}
%typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/swig.swg b/Lib/swig.swg
index ca7586457..c9b301426 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -703,6 +703,15 @@ public:
template T SwigValueInit() {
return T();
}
+%}
+
+%insert("runtime") %{
+#if __cplusplus >=201103L
+# define SWIG_STD_MOVE(OBJ) std::move(OBJ)
+#else
+# define SWIG_STD_MOVE(OBJ) OBJ
+#endif
+
#endif
%}
#endif
diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg
index 6973e3a10..52fac3252 100644
--- a/Lib/typemaps/swigtype.swg
+++ b/Lib/typemaps/swigtype.swg
@@ -417,7 +417,7 @@
/* directorin */
%typemap(directorin,noblock=1) SWIGTYPE {
- $input = SWIG_NewPointerObj(%as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
+ $input = SWIG_NewPointerObj(%as_voidptr(new $1_ltype(SWIG_STD_MOVE($1))), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
}
%typemap(directorin,noblock=1) SWIGTYPE * {
From 319442a8c4fe9d3bb3ce1f4a6fa45e4da2e7f88e Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 4 Jul 2022 08:40:04 +0100
Subject: [PATCH 493/662] More move semantics improvements
More removal of casts in the out typemaps when copying objects to enable
C++ compilers to possibly make use of move semantics.
---
Lib/csharp/boost_intrusive_ptr.i | 4 ++--
Lib/csharp/boost_shared_ptr.i | 4 ++--
Lib/d/boost_shared_ptr.i | 4 ++--
Lib/java/boost_intrusive_ptr.i | 4 ++--
Lib/java/boost_shared_ptr.i | 2 +-
Lib/lua/lua.swg | 2 +-
Lib/mzscheme/typemaps.i | 2 +-
Lib/octave/boost_shared_ptr.i | 4 ++--
Lib/php/utils.i | 2 +-
Lib/python/boost_shared_ptr.i | 4 ++--
Lib/r/boost_shared_ptr.i | 4 ++--
Lib/ruby/boost_shared_ptr.i | 4 ++--
Lib/scilab/boost_shared_ptr.i | 4 ++--
13 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/Lib/csharp/boost_intrusive_ptr.i b/Lib/csharp/boost_intrusive_ptr.i
index fa3f53a20..355a910cf 100644
--- a/Lib/csharp/boost_intrusive_ptr.i
+++ b/Lib/csharp/boost_intrusive_ptr.i
@@ -32,7 +32,7 @@
%}
%typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{
//plain value(out)
- $1_ltype* resultp = new $1_ltype(($1_ltype &)$1);
+ $1_ltype* resultp = new $1_ltype($1);
intrusive_ptr_add_ref(resultp);
*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >());
%}
@@ -372,7 +372,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
// plain pointer
%typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
diff --git a/Lib/csharp/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i
index 2bbb6e277..d47fab558 100644
--- a/Lib/csharp/boost_shared_ptr.i
+++ b/Lib/csharp/boost_shared_ptr.i
@@ -29,7 +29,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
%typemap(directorin) CONST TYPE
%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
@@ -122,7 +122,7 @@
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
%{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
%typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
-%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
+%{ $result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
if ($owner) delete $1; %}
%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
diff --git a/Lib/d/boost_shared_ptr.i b/Lib/d/boost_shared_ptr.i
index 1018bd1f2..6d85c5aef 100644
--- a/Lib/d/boost_shared_ptr.i
+++ b/Lib/d/boost_shared_ptr.i
@@ -23,7 +23,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
%typemap(directorin) CONST TYPE
%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
@@ -116,7 +116,7 @@
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
%{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
%typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
-%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
+%{ $result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
if ($owner) delete $1; %}
%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
diff --git a/Lib/java/boost_intrusive_ptr.i b/Lib/java/boost_intrusive_ptr.i
index 3bc80b467..072a31e8c 100644
--- a/Lib/java/boost_intrusive_ptr.i
+++ b/Lib/java/boost_intrusive_ptr.i
@@ -33,7 +33,7 @@
%}
%typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{
//plain value(out)
- $1_ltype* resultp = new $1_ltype(($1_ltype &)$1);
+ $1_ltype* resultp = new $1_ltype($1);
intrusive_ptr_add_ref(resultp);
*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >());
%}
@@ -342,7 +342,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
// plain pointer
%typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
diff --git a/Lib/java/boost_shared_ptr.i b/Lib/java/boost_shared_ptr.i
index adf9c203e..ce00162da 100644
--- a/Lib/java/boost_shared_ptr.i
+++ b/Lib/java/boost_shared_ptr.i
@@ -29,7 +29,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") CONST TYPE
%{ $input = 0;
diff --git a/Lib/lua/lua.swg b/Lib/lua/lua.swg
index 5144f601d..12c635d77 100644
--- a/Lib/lua/lua.swg
+++ b/Lib/lua/lua.swg
@@ -213,7 +213,7 @@ SWIG_fail;%}
// %apply SWIGTYPE EXCEPTION_BY_VAL {FooBar};
// %apply SWIGTYPE& EXCEPTION_BY_VAL {FooBar&}; // note: need & twice
%typemap(throws) SWIGTYPE EXCEPTION_BY_VAL
-%{SWIG_NewPointerObj(L,(void *)new $1_ltype(($1_ltype &) $1),$&1_descriptor,1);
+%{SWIG_NewPointerObj(L,(void *)new $1_ltype($1),$&1_descriptor,1);
SWIG_fail;%}
// similar for object reference
diff --git a/Lib/mzscheme/typemaps.i b/Lib/mzscheme/typemaps.i
index 059dd06ff..0fc947d58 100644
--- a/Lib/mzscheme/typemaps.i
+++ b/Lib/mzscheme/typemaps.i
@@ -143,7 +143,7 @@
#ifdef __cplusplus
{
$&1_ltype resultptr;
- resultptr = new $1_ltype(($1_ltype &) $1);
+ resultptr = new $1_ltype($1);
$result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 0);
}
#else
diff --git a/Lib/octave/boost_shared_ptr.i b/Lib/octave/boost_shared_ptr.i
index a1427b74d..87c89b5f9 100644
--- a/Lib/octave/boost_shared_ptr.i
+++ b/Lib/octave/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,7 +54,7 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
diff --git a/Lib/php/utils.i b/Lib/php/utils.i
index 1343495e0..33db942a9 100644
--- a/Lib/php/utils.i
+++ b/Lib/php/utils.i
@@ -81,7 +81,7 @@
%{
$*1_ltype swig_val;
CONVERT_IN(swig_val, $*1_ltype, *$input);
- $1_ltype temp = new $*1_ltype(($*1_ltype)swig_val);
+ $1_ltype temp = new $*1_ltype(swig_val);
swig_acquire_ownership(temp);
$result = temp;
%}
diff --git a/Lib/python/boost_shared_ptr.i b/Lib/python/boost_shared_ptr.i
index ab9962ac8..bfd8787c0 100644
--- a/Lib/python/boost_shared_ptr.i
+++ b/Lib/python/boost_shared_ptr.i
@@ -39,7 +39,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -58,7 +58,7 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
diff --git a/Lib/r/boost_shared_ptr.i b/Lib/r/boost_shared_ptr.i
index a1427b74d..87c89b5f9 100644
--- a/Lib/r/boost_shared_ptr.i
+++ b/Lib/r/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,7 +54,7 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
diff --git a/Lib/ruby/boost_shared_ptr.i b/Lib/ruby/boost_shared_ptr.i
index fe3ea8cde..70deae4f2 100644
--- a/Lib/ruby/boost_shared_ptr.i
+++ b/Lib/ruby/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,7 +54,7 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
diff --git a/Lib/scilab/boost_shared_ptr.i b/Lib/scilab/boost_shared_ptr.i
index a1427b74d..87c89b5f9 100644
--- a/Lib/scilab/boost_shared_ptr.i
+++ b/Lib/scilab/boost_shared_ptr.i
@@ -35,7 +35,7 @@
}
}
%typemap(out) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
@@ -54,7 +54,7 @@
}
}
%typemap(varout) CONST TYPE {
- SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+ SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
%set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
}
From 5e06e0931edee5d102ef45fa74ed805368cb22dd Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Mon, 4 Jul 2022 09:52:31 +0100
Subject: [PATCH 494/662] Remove Tcl SWIGTYPE CLASS typemap
Odd typemap cleanup - this typemap can't be used - SWIG_new_copy does not exist
---
Lib/tcl/tcltypemaps.swg | 5 -----
1 file changed, 5 deletions(-)
diff --git a/Lib/tcl/tcltypemaps.swg b/Lib/tcl/tcltypemaps.swg
index ad31bcfc9..66cce47ec 100644
--- a/Lib/tcl/tcltypemaps.swg
+++ b/Lib/tcl/tcltypemaps.swg
@@ -77,11 +77,6 @@
#endif
-%typemap(throws,noblock=1) SWIGTYPE CLASS {
- SWIG_set_result(SWIG_NewInstanceObj(%as_voidptr(SWIG_new_copy($1, $1_ltype)), $&1_descriptor, 1));
- SWIG_fail;
-}
-
%typemap(out) SWIGTYPE = SWIGTYPE INSTANCE;
%typemap(out) SWIGTYPE * = SWIGTYPE *INSTANCE;
%typemap(out) SWIGTYPE *const = SWIGTYPE *;
From e1173cac26be86bd1b1caf6e5266435fe90a5250 Mon Sep 17 00:00:00 2001
From: William S Fulton
Date: Tue, 5 Jul 2022 10:53:08 +0100
Subject: [PATCH 495/662] Tcl std_vector.i functions not static
Closes #2305
---
Lib/tcl/std_vector.i | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Lib/tcl/std_vector.i b/Lib/tcl/std_vector.i
index 144788be5..a74bf3a1b 100644
--- a/Lib/tcl/std_vector.i
+++ b/Lib/tcl/std_vector.i
@@ -34,11 +34,11 @@
%{
#include
-Tcl_Obj* SwigString_FromString(const std::string &s) {
+SWIGINTERN Tcl_Obj* SwigString_FromString(const std::string &s) {
return Tcl_NewStringObj(s.data(), (int)s.length());
}
-int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
+SWIGINTERN int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
int v;
int res = Tcl_GetBooleanFromObj(interp, o, &v);
if (res == TCL_OK) {
@@ -47,7 +47,7 @@ int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
return res;
}
-int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
+SWIGINTERN int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
int len;
const char* temp = Tcl_GetStringFromObj(o, &len);
(void)interp;
From 87cbf8c3410cdde9356875f2652ea5927b3543f4 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor