diff options
author | Karl Wette <karl.wette@ligo.org> | 2013-02-18 09:48:42 +0100 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2013-02-19 20:05:46 +0000 |
commit | ee2b46abe0b747bc949538f51c9e2a989a867da9 (patch) | |
tree | 71b500cea663c8aeb13fa574877fa5905d81c113 | |
parent | 9d330a99703f079bdff5a8d7945cc1d2d7c56f53 (diff) | |
download | swig-ee2b46abe0b747bc949538f51c9e2a989a867da9.tar.gz |
Fix SWIG's handling of qualified (e.g. const) variables of array type
-rw-r--r-- | CHANGES.current | 12 | ||||
-rw-r--r-- | Examples/test-suite/common.mk | 1 | ||||
-rw-r--r-- | Examples/test-suite/typemap_array_qualifiers.i | 79 | ||||
-rw-r--r-- | Source/Swig/typesys.c | 61 |
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); |