summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Wette <karl.wette@ligo.org>2013-02-18 09:48:42 +0100
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2013-02-19 20:05:46 +0000
commitee2b46abe0b747bc949538f51c9e2a989a867da9 (patch)
tree71b500cea663c8aeb13fa574877fa5905d81c113
parent9d330a99703f079bdff5a8d7945cc1d2d7c56f53 (diff)
downloadswig-ee2b46abe0b747bc949538f51c9e2a989a867da9.tar.gz
Fix SWIG's handling of qualified (e.g. const) variables of array type
-rw-r--r--CHANGES.current12
-rw-r--r--Examples/test-suite/common.mk1
-rw-r--r--Examples/test-suite/typemap_array_qualifiers.i79
-rw-r--r--Source/Swig/typesys.c61
4 files changed, 153 insertions, 0 deletions
diff --git a/CHANGES.current b/CHANGES.current
index 0b65717ff..779e20528 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -5,6 +5,18 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.10 (in progress)
============================
+2013-02-19: kwwette
+ Fix bug in SWIG's handling of qualified (e.g. const) variables of array type. Given the typedef
+ a(7).q(volatile).double myarray // typedef volatile double[7] myarray;
+ the type
+ q(const).myarray // const myarray
+ becomes
+ a(7).q(const volatile).double // const volatile double[7]
+ Previously, SwigType_typedef_resolve() produces the type
+ q(const).a(7).q(volatile).double // non-sensical type
+ which would never match %typemap declarations, whose types were parsed correctly.
+ Add typemap_array_qualifiers.i to the test suite which checks for the correct behaviour.
+
2013-02-18: wsfulton
Deprecate typedef names used as constructor and destructor names in %extend. The real
class/struct name should be used.
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 173e9b287..83be90d2d 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -433,6 +433,7 @@ CPP_TEST_CASES += \
typedef_sizet \
typedef_struct \
typemap_arrays \
+ typemap_array_qualifiers \
typemap_delete \
typemap_directorout \
typemap_global_scope \
diff --git a/Examples/test-suite/typemap_array_qualifiers.i b/Examples/test-suite/typemap_array_qualifiers.i
new file mode 100644
index 000000000..947721402
--- /dev/null
+++ b/Examples/test-suite/typemap_array_qualifiers.i
@@ -0,0 +1,79 @@
+%module typemap_array_qualifiers
+
+%define CLEAR_SWIGTYPE_TYPEMAPS
+%typemap(in)
+ SWIGTYPE,
+ SWIGTYPE *,
+ SWIGTYPE *const,
+ SWIGTYPE *const&,
+ const SWIGTYPE *,
+ const SWIGTYPE *const,
+ const SWIGTYPE *const&,
+ const volatile SWIGTYPE *,
+ const volatile SWIGTYPE *const,
+ const volatile SWIGTYPE *const&,
+ SWIGTYPE [],
+ SWIGTYPE [ANY],
+ const SWIGTYPE [],
+ const SWIGTYPE [ANY],
+ const volatile SWIGTYPE [],
+ const volatile SWIGTYPE [ANY],
+ SWIGTYPE &,
+ const SWIGTYPE &,
+ const volatile SWIGTYPE &
+{
+%#error Incorrect typemap for $symname: $type
+}
+%enddef
+
+%inline %{
+ typedef struct {
+ int a;
+ } SomeType;
+ typedef SomeType myarray[3];
+ typedef const SomeType myconstarray[4];
+ typedef volatile SomeType ** mycrazyarray[5];
+ typedef volatile SomeType (mycrazyfunc)(SomeType);
+ typedef volatile SomeType (*mycrazyfuncptr)(SomeType);
+%}
+
+CLEAR_SWIGTYPE_TYPEMAPS;
+%typemap(in) SWIGTYPE [ANY] {
+/* Correct typemap for $symname: $type */
+}
+%inline %{
+ void func1a(myarray x) {};
+ void func1b(volatile myarray x) {};
+%}
+
+CLEAR_SWIGTYPE_TYPEMAPS;
+%typemap(in) const SWIGTYPE [ANY] {
+/* Correct typemap for $symname: $type */
+}
+%typemap(in) const volatile SWIGTYPE [ANY] {
+/* Correct typemap for $symname: $type */
+}
+%inline %{
+ void func2a(const myarray x) {};
+ void func2b(const myconstarray x) {};
+ void func2c(const volatile myconstarray x) {};
+%}
+
+CLEAR_SWIGTYPE_TYPEMAPS;
+%typemap(in) volatile SWIGTYPE **const [ANY] {
+/* Correct typemap for $symname: $type */
+}
+%typemap(in) volatile SWIGTYPE **const [ANY][ANY] {
+/* Correct typemap for $symname: $type */
+}
+%inline %{
+ void func3a(const mycrazyarray x, const mycrazyarray y[7]) {};
+%}
+
+CLEAR_SWIGTYPE_TYPEMAPS;
+%typemap(in) SWIGTYPE (*const) (ANY) {
+/* Correct typemap for $symname: $type */
+}
+%inline %{
+ void func4a(mycrazyfunc *const x, const mycrazyfuncptr y) {};
+%}
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
index d12d70543..372ac3f65 100644
--- a/Source/Swig/typesys.c
+++ b/Source/Swig/typesys.c
@@ -792,6 +792,67 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) {
goto return_result;
}
Delete(base);
+
+ /* If 'type' is an array, then the right-most qualifier in 'r' should
+ be added to 'type' after the array qualifier, so that given
+ a(7).q(volatile).double myarray // typedef volatile double[7] myarray;
+ the type
+ q(const).myarray // const myarray
+ becomes
+ a(7).q(const volatile).double // const volatile double[7]
+ and NOT
+ q(const).a(7).q(volatile).double // non-sensical type
+ */
+ if (r && Len(r) && SwigType_isarray(type)) {
+ List *r_elem;
+ String *r_qual;
+ int r_sz;
+ r_elem = SwigType_split(r);
+ r_sz = Len(r_elem);
+ r_qual = Getitem(r_elem, r_sz-1);
+ if (SwigType_isqualifier(r_qual)) {
+ String *new_r;
+ String *new_type;
+ List *type_elem;
+ String *type_qual;
+ String *r_qual_arg;
+ int i, type_sz;
+
+ type_elem = SwigType_split(type);
+ type_sz = Len(type_elem);
+ i = 0;
+ for (i = 0; i < type_sz; ++i) {
+ String *e = Getitem(type_elem, i);
+ if (!SwigType_isarray(e))
+ break;
+ }
+ type_qual = Copy(Getitem(type_elem, i));
+ r_qual_arg = SwigType_parm(r_qual);
+ SwigType_add_qualifier(type_qual, r_qual_arg);
+ Delete(r_qual_arg);
+ Setitem(type_elem, i, type_qual);
+
+ new_r = NewStringEmpty();
+ for (i = 0; i < r_sz-1; ++i) {
+ Append(new_r, Getitem(r_elem, i));
+ }
+ new_type = NewStringEmpty();
+ for (i = 0; i < type_sz; ++i) {
+ Append(new_type, Getitem(type_elem, i));
+ }
+#ifdef SWIG_DEBUG
+ Printf(stdout, "r+type='%s%s' new_r+new_type='%s%s'\n", r, type, new_r, new_type);
+#endif
+
+ Delete(r);
+ r = new_r;
+ newtype = 1;
+ type = new_type;
+ Delete(type_elem);
+ }
+ Delete(r_elem);
+ }
+
Append(r, type);
if (newtype) {
Delete(type);