Fix SWIG's handling of qualified (e.g. const) variables of array type
This commit is contained in:
parent
9d330a9970
commit
ee2b46abe0
4 changed files with 153 additions and 0 deletions
|
|
@ -5,6 +5,18 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 2.0.10 (in progress)
|
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
|
2013-02-18: wsfulton
|
||||||
Deprecate typedef names used as constructor and destructor names in %extend. The real
|
Deprecate typedef names used as constructor and destructor names in %extend. The real
|
||||||
class/struct name should be used.
|
class/struct name should be used.
|
||||||
|
|
|
||||||
|
|
@ -433,6 +433,7 @@ CPP_TEST_CASES += \
|
||||||
typedef_sizet \
|
typedef_sizet \
|
||||||
typedef_struct \
|
typedef_struct \
|
||||||
typemap_arrays \
|
typemap_arrays \
|
||||||
|
typemap_array_qualifiers \
|
||||||
typemap_delete \
|
typemap_delete \
|
||||||
typemap_directorout \
|
typemap_directorout \
|
||||||
typemap_global_scope \
|
typemap_global_scope \
|
||||||
|
|
|
||||||
79
Examples/test-suite/typemap_array_qualifiers.i
Normal file
79
Examples/test-suite/typemap_array_qualifiers.i
Normal file
|
|
@ -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) {};
|
||||||
|
%}
|
||||||
|
|
@ -792,6 +792,67 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) {
|
||||||
goto return_result;
|
goto return_result;
|
||||||
}
|
}
|
||||||
Delete(base);
|
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);
|
Append(r, type);
|
||||||
if (newtype) {
|
if (newtype) {
|
||||||
Delete(type);
|
Delete(type);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue