Typemap matching rules enhancement for non-default typemaps. Previously all qualifiers were stripped in one step, now they are stripped one at a time starting with the left most qualifier.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12007 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
58a7e2c3d6
commit
efd200ffe2
10 changed files with 398 additions and 38 deletions
|
|
@ -1,6 +1,14 @@
|
||||||
Version 2.0.0 (in progress)
|
Version 2.0.0 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
2010-05-01: wsfulton
|
||||||
|
Typemap matching enhancement for non-default typemaps. Previously all
|
||||||
|
qualifiers were stripped in one step, now they are stripped one at a time
|
||||||
|
starting with the left most qualifier. For example, int const*const
|
||||||
|
is first stripped to int *const then int *.
|
||||||
|
|
||||||
|
*** POTENTIAL INCOMPATIBILITY ***
|
||||||
|
|
||||||
2010-04-25: bhy
|
2010-04-25: bhy
|
||||||
[Python] Fix #2985655 - broken constructor renaming.
|
[Python] Fix #2985655 - broken constructor renaming.
|
||||||
|
|
||||||
|
|
@ -37,7 +45,7 @@ Version 2.0.0 (in progress)
|
||||||
Numerous subtle typemap matching rule fixes when using the default type. The typemap
|
Numerous subtle typemap matching rule fixes when using the default type. The typemap
|
||||||
matching rules are to take a type and find the best default typemap (SWIGTYPE, SWIGTYPE* etc),
|
matching rules are to take a type and find the best default typemap (SWIGTYPE, SWIGTYPE* etc),
|
||||||
then look for the next best match by reducing the chosen default type. The type deduction
|
then look for the next best match by reducing the chosen default type. The type deduction
|
||||||
now follows C++ template partial specialization matching rules.
|
now follows C++ class template partial specialization matching rules.
|
||||||
|
|
||||||
Below are the set of changes made showing the default type deduction
|
Below are the set of changes made showing the default type deduction
|
||||||
along with the old reduced type and the new version of the reduced type:
|
along with the old reduced type and the new version of the reduced type:
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,7 @@
|
||||||
<li><a href="Typemaps.html#Typemaps_nn17">Basic matching rules</a>
|
<li><a href="Typemaps.html#Typemaps_nn17">Basic matching rules</a>
|
||||||
<li><a href="Typemaps.html#Typemaps_typedef_reductions">Typedef reductions matching</a>
|
<li><a href="Typemaps.html#Typemaps_typedef_reductions">Typedef reductions matching</a>
|
||||||
<li><a href="Typemaps.html#Typemaps_nn19">Default typemap matching rules</a>
|
<li><a href="Typemaps.html#Typemaps_nn19">Default typemap matching rules</a>
|
||||||
|
<li><a href="Typemaps.html#Typemaps_matching_template_comparison">Matching comparison with C++ templates</a>
|
||||||
<li><a href="Typemaps.html#Typemaps_multi_argument_typemaps_patterns">Multi-arguments typemaps</a>
|
<li><a href="Typemaps.html#Typemaps_multi_argument_typemaps_patterns">Multi-arguments typemaps</a>
|
||||||
<li><a href="Typemaps.html#Typemaps_debugging_search">Debugging typemap pattern matching</a>
|
<li><a href="Typemaps.html#Typemaps_debugging_search">Debugging typemap pattern matching</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
<li><a href="#Typemaps_nn17">Basic matching rules</a>
|
<li><a href="#Typemaps_nn17">Basic matching rules</a>
|
||||||
<li><a href="#Typemaps_typedef_reductions">Typedef reductions matching</a>
|
<li><a href="#Typemaps_typedef_reductions">Typedef reductions matching</a>
|
||||||
<li><a href="#Typemaps_nn19">Default typemap matching rules</a>
|
<li><a href="#Typemaps_nn19">Default typemap matching rules</a>
|
||||||
|
<li><a href="#Typemaps_matching_template_comparison">Matching comparison with C++ templates</a>
|
||||||
<li><a href="#Typemaps_multi_argument_typemaps_patterns">Multi-arguments typemaps</a>
|
<li><a href="#Typemaps_multi_argument_typemaps_patterns">Multi-arguments typemaps</a>
|
||||||
<li><a href="#Typemaps_debugging_search">Debugging typemap pattern matching</a>
|
<li><a href="#Typemaps_debugging_search">Debugging typemap pattern matching</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -1026,8 +1027,10 @@ is used.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If <tt>TYPE</tt> includes qualifiers (const, volatile, etc.), they are stripped to form a new stripped type
|
If <tt>TYPE</tt> includes qualifiers (const, volatile, etc.), each qualifier is stripped one at a time to form a new stripped type
|
||||||
and the matching rules above are repeated on the stripped type.
|
and the matching rules above are repeated on the stripped type.
|
||||||
|
The left-most qualifier is stripped first, resulting in the right-most (or top-level) qualifier being stripped last.
|
||||||
|
For example <tt>int const*const</tt> is first stripped to <tt>int *const</tt> then <tt>int *</tt>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1056,8 +1059,8 @@ To find a typemap for the argument <tt>const char *s</tt>, SWIG will search for
|
||||||
<pre>
|
<pre>
|
||||||
const char *s Exact type and name match
|
const char *s Exact type and name match
|
||||||
const char * Exact type match
|
const char * Exact type match
|
||||||
char *s Type and name match (stripped qualifiers)
|
char *s Type and name match (qualifier stripped)
|
||||||
char * Type match (stripped qualifiers)
|
char * Type match (qualifier stripped)
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1097,6 +1100,11 @@ void F(int x[1000]); // int [ANY] rule (typemap 5)
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Compatibility note: </b> SWIG-2.0.0 introduced stripping the qualifiers one step at a time. Prior versions
|
||||||
|
stripped all qualifiers in one step.
|
||||||
|
</p>
|
||||||
|
|
||||||
<H3><a name="Typemaps_typedef_reductions"></a>10.3.2 Typedef reductions matching</H3>
|
<H3><a name="Typemaps_typedef_reductions"></a>10.3.2 Typedef reductions matching</H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1280,7 +1288,7 @@ If the basic pattern matching rules result in no match being made, even after ty
|
||||||
the default typemap matching rules are used to look for a suitable typemap match.
|
the default typemap matching rules are used to look for a suitable typemap match.
|
||||||
These rules match a generic typemap based on the reserved <tt>SWIGTYPE</tt> base type.
|
These rules match a generic typemap based on the reserved <tt>SWIGTYPE</tt> base type.
|
||||||
For example pointers will use <tt>SWIGTYPE *</tt> and references will use <tt>SWIGTYPE &</tt>.
|
For example pointers will use <tt>SWIGTYPE *</tt> and references will use <tt>SWIGTYPE &</tt>.
|
||||||
More precisely, the rules are based on the C++ template partial specialization matching rules used
|
More precisely, the rules are based on the C++ class template partial specialization matching rules used
|
||||||
by C++ compilers when looking for an appropriate partial template specialization.
|
by C++ compilers when looking for an appropriate partial template specialization.
|
||||||
This means that a match is chosen from the most specialized set of generic typemap types available. For example,
|
This means that a match is chosen from the most specialized set of generic typemap types available. For example,
|
||||||
when looking for a match to <tt>int const *</tt>, the rules will prefer to match <tt>SWIGTYPE const *</tt>
|
when looking for a match to <tt>int const *</tt>, the rules will prefer to match <tt>SWIGTYPE const *</tt>
|
||||||
|
|
@ -1407,11 +1415,10 @@ Finally the best way to view the typemap matching rules in action is via the <a
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Compatibility note: </b> The default typemap matching rules were modified in SWIG-2.0.0 from a slightly
|
<b>Compatibility note: </b> The default typemap matching rules were modified in SWIG-2.0.0 from a slightly
|
||||||
simpler scheme to match the current C++ template partial specialization matching rules.
|
simpler scheme to match the current C++ class template partial specialization matching rules.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<H3><a name="Typemaps_multi_argument_typemaps_patterns"></a>10.3.5 Multi-arguments typemaps</H3>
|
||||||
<H3><a name="Typemaps_multi_argument_typemaps_patterns"></a>10.3.4 Multi-arguments typemaps</H3>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1441,7 +1448,165 @@ but all subsequent arguments must match exactly.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<H3><a name="Typemaps_debugging_search"></a>10.3.5 Debugging typemap pattern matching</H3>
|
<H3><a name="Typemaps_matching_template_comparison"></a>10.3.4 Matching rules compared to C++ templates</H3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For those intimately familiar with C++ templates, a comparison of the typemap matching rules and template type deduction is interesting.
|
||||||
|
The two areas considered are firstly the default typemaps and their similarities to partial template specialization and secondly, non-default typemaps and their similarities to full template specialization.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For default (SWIGTYPE) typemaps the rules are inspired by C++ class template
|
||||||
|
partial specialization. For example, given partial specialization for <tt>T const&</tt> :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
template <typename T> struct X { void a(); };
|
||||||
|
template <typename T> struct X< T const& > { void b(); };
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The full (unspecialized) template is matched with most types, such as:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
X< int & > x1; x1.a();
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
and the following all match the <tt>T const&</tt> partial specialization:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
X< int *const& > x2; x2.b();
|
||||||
|
X< int const*const& > x3; x3.b();
|
||||||
|
X< int const& > x4; x4.b();
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Now, given just these two default typemaps, where T is analogous to SWIGTYPE:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%typemap(...) SWIGTYPE { ... }
|
||||||
|
%typemap(...) SWIGTYPE const& { ... }
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The generic default typemap <tt>SWIGTYPE</tt> is used with most types, such as
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
int &
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
and the following all match the <tt>SWIGTYPE const&</tt> typemap, just like the partial template matching:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
int *const&
|
||||||
|
int const*const&
|
||||||
|
int const&
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note that the template and typemap matching rules are not identical for all default typemaps though, for example, with arrays.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For non-default typemaps, one might expect SWIG to follow the fully specialized template rules.
|
||||||
|
This is nearly the case, but not quite.
|
||||||
|
Consider a very similar example to the earlier partially specialized template but this time there is a fully specialized template:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
template <typename T> struct Y { void a(); };
|
||||||
|
template <> struct Y< int const & > { void b(); };
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Only the one type matches the specialized template exactly:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
Y< int & > y1; y1.a();
|
||||||
|
Y< int *const& > y2; y2.a();
|
||||||
|
Y< int const *const& > y3; y3.a();
|
||||||
|
Y< int const& > y4; y4.b(); // fully specialized match
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Given typemaps with the same types used for the template declared above, where T is again analogous to SWIGTYPE:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%typemap(...) SWIGTYPE { ... }
|
||||||
|
%typemap(...) int const& { ... }
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The comparison between non-default typemaps and fully specialized single parameter templates turns out to be the same, as just the one type will match the non-default typemap:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
int &
|
||||||
|
int *const&
|
||||||
|
int const*const&
|
||||||
|
int const& // matches non-default typemap int const&
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
However, if a non-const type is used instead:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%typemap(...) SWIGTYPE { ... }
|
||||||
|
%typemap(...) int & { ... }
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
then there is a clear difference to template matching as both the const and non-const types match the typemap:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
int & // matches non-default typemap int &
|
||||||
|
int *const&
|
||||||
|
int const*const&
|
||||||
|
int const& // matches non-default typemap int &
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There are other subtle differences such as typedef handling, but at least it should be clear that the typemap matching rules
|
||||||
|
are similar to those for specialized template handling.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<H3><a name="Typemaps_debugging_search"></a>10.3.6 Debugging typemap pattern matching</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -393,6 +393,7 @@ CPP_TEST_CASES += \
|
||||||
typemap_numinputs \
|
typemap_numinputs \
|
||||||
typemap_template \
|
typemap_template \
|
||||||
typemap_out_optimal \
|
typemap_out_optimal \
|
||||||
|
typemap_qualifier_strip \
|
||||||
typemap_variables \
|
typemap_variables \
|
||||||
typemap_various \
|
typemap_various \
|
||||||
typename \
|
typename \
|
||||||
|
|
|
||||||
54
Examples/test-suite/python/typemap_qualifier_strip_runme.py
Normal file
54
Examples/test-suite/python/typemap_qualifier_strip_runme.py
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import typemap_qualifier_strip
|
||||||
|
|
||||||
|
val = typemap_qualifier_strip.create_int(111)
|
||||||
|
if typemap_qualifier_strip.testA1(val) != 1234:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testA2(val) != 1234:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testA3(val) != 1234:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testA4(val) != 1234:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testB1(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testB2(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testB3(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testB4(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testC1(val) != 5678:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testC2(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testC3(val) != 5678:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testC4(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testD1(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testD2(val) != 3456:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testD3(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
if typemap_qualifier_strip.testD4(val) != 111:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
76
Examples/test-suite/typemap_qualifier_strip.i
Normal file
76
Examples/test-suite/typemap_qualifier_strip.i
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
%module typemap_qualifier_strip
|
||||||
|
|
||||||
|
%typemap(in) int *ptr {
|
||||||
|
int temp = 1234;
|
||||||
|
$1 = &temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
%typemap(in) int *const ptrConst {
|
||||||
|
int temp = 5678;
|
||||||
|
$1 = &temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
%typemap(in) int const* constPtr {
|
||||||
|
int temp = 3456;
|
||||||
|
$1 = &temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
int *create_int(int newval) {
|
||||||
|
static int val = 0;
|
||||||
|
val = newval;
|
||||||
|
return &val;
|
||||||
|
}
|
||||||
|
int testA1(int const*const ptr) {
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
int testA2(int const* ptr) {
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
int testA3(int *const ptr) {
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
int testA4(int * ptr) {
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testB1(int const*const p) {
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
|
int testB2(int const* p) {
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
|
int testB3(int *const p) {
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
|
int testB4(int * p) {
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testC1(int const*const ptrConst) {
|
||||||
|
return *ptrConst;
|
||||||
|
}
|
||||||
|
int testC2(int const* ptrConst) {
|
||||||
|
return *ptrConst;
|
||||||
|
}
|
||||||
|
int testC3(int *const ptrConst) {
|
||||||
|
return *ptrConst;
|
||||||
|
}
|
||||||
|
int testC4(int * ptrConst) {
|
||||||
|
return *ptrConst;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testD1(int const*const constPtr) {
|
||||||
|
return *constPtr;
|
||||||
|
}
|
||||||
|
int testD2(int const* constPtr) {
|
||||||
|
return *constPtr;
|
||||||
|
}
|
||||||
|
int testD3(int *const constPtr) {
|
||||||
|
return *constPtr;
|
||||||
|
}
|
||||||
|
int testD4(int * constPtr) {
|
||||||
|
return *constPtr;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
@ -357,8 +357,8 @@ SwigType *SwigType_default_create(SwigType *ty) {
|
||||||
* SwigType_default_deduce()
|
* SwigType_default_deduce()
|
||||||
*
|
*
|
||||||
* This function implements type deduction used in the typemap matching rules
|
* This function implements type deduction used in the typemap matching rules
|
||||||
* and is very close to the type deduction used in partial template specialization
|
* and is very close to the type deduction used in partial template class
|
||||||
* matching in that the most specialized type is always chosen.
|
* specialization matching in that the most specialized type is always chosen.
|
||||||
* SWIGTYPE is used as the generic type. The basic idea is to repeatedly call
|
* SWIGTYPE is used as the generic type. The basic idea is to repeatedly call
|
||||||
* this function to find a deduced type unless until nothing matches.
|
* this function to find a deduced type unless until nothing matches.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ extern "C" {
|
||||||
extern int SwigType_isenum(SwigType *t);
|
extern int SwigType_isenum(SwigType *t);
|
||||||
extern int SwigType_check_decl(SwigType *t, const_String_or_char_ptr decl);
|
extern int SwigType_check_decl(SwigType *t, const_String_or_char_ptr decl);
|
||||||
extern SwigType *SwigType_strip_qualifiers(SwigType *t);
|
extern SwigType *SwigType_strip_qualifiers(SwigType *t);
|
||||||
|
extern SwigType *SwigType_strip_single_qualifier(SwigType *t);
|
||||||
extern SwigType *SwigType_functionpointer_decompose(SwigType *t);
|
extern SwigType *SwigType_functionpointer_decompose(SwigType *t);
|
||||||
extern String *SwigType_base(const SwigType *t);
|
extern String *SwigType_base(const SwigType *t);
|
||||||
extern String *SwigType_namestr(const SwigType *t);
|
extern String *SwigType_namestr(const SwigType *t);
|
||||||
|
|
|
||||||
|
|
@ -698,11 +698,11 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
||||||
Hash *backup = 0;
|
Hash *backup = 0;
|
||||||
SwigType *primitive = 0;
|
SwigType *primitive = 0;
|
||||||
SwigType *ctype = 0;
|
SwigType *ctype = 0;
|
||||||
|
SwigType *ctype_unstripped = 0;
|
||||||
int ts;
|
int ts;
|
||||||
int isarray;
|
int isarray;
|
||||||
const String *cname = 0;
|
const String *cname = 0;
|
||||||
const String *cqualifiedname = 0;
|
const String *cqualifiedname = 0;
|
||||||
SwigType *unstripped = 0;
|
|
||||||
String *tm_method = typemap_method_name(tmap_method);
|
String *tm_method = typemap_method_name(tmap_method);
|
||||||
int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug;
|
int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug;
|
||||||
|
|
||||||
|
|
@ -718,7 +718,8 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
||||||
Delete(typestr);
|
Delete(typestr);
|
||||||
}
|
}
|
||||||
while (ts >= 0) {
|
while (ts >= 0) {
|
||||||
ctype = type;
|
ctype = Copy(type);
|
||||||
|
ctype_unstripped = Copy(ctype);
|
||||||
while (ctype) {
|
while (ctype) {
|
||||||
/* Try to get an exact type-match */
|
/* Try to get an exact type-match */
|
||||||
tm = get_typemap(ts, ctype);
|
tm = get_typemap(ts, ctype);
|
||||||
|
|
@ -751,29 +752,25 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
||||||
goto ret_result;
|
goto ret_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No match so far. If the type is unstripped, we'll strip its
|
/* No match so far - try with a qualifier stripped (strip one qualifier at a time until none remain)
|
||||||
qualifiers and check. Otherwise, we'll try to resolve a typedef */
|
* The order of stripping in SwigType_strip_single_qualifier is used to provide some sort of consistency
|
||||||
|
* with the default (SWIGTYPE) typemap matching rules for the first qualifier to be stripped. */
|
||||||
if (!unstripped) {
|
|
||||||
unstripped = ctype;
|
|
||||||
ctype = SwigType_strip_qualifiers(ctype);
|
|
||||||
if (!Equal(ctype, unstripped))
|
|
||||||
continue; /* Types are different */
|
|
||||||
Delete(ctype);
|
|
||||||
ctype = unstripped;
|
|
||||||
unstripped = 0;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
String *octype;
|
SwigType *oldctype = ctype;
|
||||||
if (unstripped) {
|
ctype = SwigType_strip_single_qualifier(oldctype);
|
||||||
Delete(ctype);
|
if (!Equal(ctype, oldctype)) {
|
||||||
ctype = unstripped;
|
Delete(oldctype);
|
||||||
unstripped = 0;
|
continue;
|
||||||
}
|
}
|
||||||
octype = ctype;
|
Delete(oldctype);
|
||||||
ctype = SwigType_typedef_resolve(ctype);
|
}
|
||||||
if (octype != type)
|
|
||||||
Delete(octype);
|
/* Once all qualifiers are stripped try resolve a typedef */
|
||||||
|
{
|
||||||
|
SwigType *oldctype = ctype;
|
||||||
|
ctype = SwigType_typedef_resolve(ctype_unstripped);
|
||||||
|
Delete(oldctype);
|
||||||
|
ctype_unstripped = Copy(ctype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -802,12 +799,10 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
||||||
|
|
||||||
ret_result:
|
ret_result:
|
||||||
Delete(primitive);
|
Delete(primitive);
|
||||||
if ((unstripped) && (unstripped != type))
|
|
||||||
Delete(unstripped);
|
|
||||||
if (matchtype)
|
if (matchtype)
|
||||||
*matchtype = Copy(ctype);
|
*matchtype = Copy(ctype);
|
||||||
if (type != ctype)
|
Delete(ctype);
|
||||||
Delete(ctype);
|
Delete(ctype_unstripped);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1125,3 +1125,62 @@ SwigType *SwigType_strip_qualifiers(SwigType *t) {
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* SwigType_strip_single_qualifier()
|
||||||
|
*
|
||||||
|
* If the type contains a qualifier, strip one qualifier and return a new type.
|
||||||
|
* The left most qualifier is stripped first (when viewed as C source code) but
|
||||||
|
* this is the equivalent to the right most qualifier using SwigType notation.
|
||||||
|
* Example:
|
||||||
|
* r.q(const).p.q(const).int => r.q(const).p.int
|
||||||
|
* r.q(const).p.int => r.p.int
|
||||||
|
* r.p.int => r.p.int
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SwigType *SwigType_strip_single_qualifier(SwigType *t) {
|
||||||
|
static Hash *memoize_stripped = 0;
|
||||||
|
SwigType *r = 0;
|
||||||
|
List *l;
|
||||||
|
int numitems;
|
||||||
|
|
||||||
|
if (!memoize_stripped)
|
||||||
|
memoize_stripped = NewHash();
|
||||||
|
r = Getattr(memoize_stripped, t);
|
||||||
|
if (r)
|
||||||
|
return Copy(r);
|
||||||
|
|
||||||
|
l = SwigType_split(t);
|
||||||
|
|
||||||
|
numitems = Len(l);
|
||||||
|
if (numitems >= 2) {
|
||||||
|
int item;
|
||||||
|
/* iterate backwards from last but one item */
|
||||||
|
for (item = numitems - 2; item >= 0; --item) {
|
||||||
|
String *subtype = Getitem(l, item);
|
||||||
|
if (SwigType_isqualifier(subtype)) {
|
||||||
|
Iterator it;
|
||||||
|
Delitem(l, item);
|
||||||
|
r = NewStringEmpty();
|
||||||
|
for (it = First(l); it.item; it = Next(it)) {
|
||||||
|
Append(r, it.item);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!r)
|
||||||
|
r = Copy(t);
|
||||||
|
|
||||||
|
Delete(l);
|
||||||
|
{
|
||||||
|
String *key, *value;
|
||||||
|
key = Copy(t);
|
||||||
|
value = Copy(r);
|
||||||
|
Setattr(memoize_stripped, key, value);
|
||||||
|
Delete(key);
|
||||||
|
Delete(value);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue