merge from trunk
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-sploving@12011 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
commit
75d2abfddb
21 changed files with 466 additions and 76 deletions
|
|
@ -1,6 +1,17 @@
|
||||||
Version 2.0.0 (in progress)
|
Version 2.0.0 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
2010-05-05: wsfulton
|
||||||
|
[R] Memory leak fix handling const std::string & inputs, reported by Will Nolan.
|
||||||
|
|
||||||
|
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 +48,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>
|
||||||
|
|
|
||||||
|
|
@ -2124,8 +2124,8 @@ Object 'RCObj', which implements the ref/unref idiom.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To tell SWIG that 'RCObj' and all its derived classes are reference
|
To tell SWIG that 'RCObj' and all its derived classes are reference
|
||||||
counted objects, you use the "ref" and "unref" features, or
|
counted objects, you use the "ref" and "unref" features.
|
||||||
<tt>%ref</tt> and <tt>%unref</tt> directives (since 1.3.28). For example:
|
For example:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2143,25 +2143,6 @@ counted objects, you use the "ref" and "unref" features, or
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
or, using the directive form:
|
|
||||||
|
|
||||||
|
|
||||||
<div class="code">
|
|
||||||
<pre>
|
|
||||||
%module example
|
|
||||||
...
|
|
||||||
|
|
||||||
%ref RCObj "$this->ref();"
|
|
||||||
%unref RCObj "$this->unref();"
|
|
||||||
|
|
||||||
%include "rcobj.h"
|
|
||||||
%include "A.h"
|
|
||||||
...
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
where the code passed to the "ref" and "unref" features will be
|
where the code passed to the "ref" and "unref" features will be
|
||||||
executed as needed whenever a new object is passed to python, or when
|
executed as needed whenever a new object is passed to python, or when
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ below.
|
||||||
static char *global_str = NULL;
|
static char *global_str = NULL;
|
||||||
const int UINT_DIGITS = 10; // max unsigned int is 4294967295
|
const int UINT_DIGITS = 10; // max unsigned int is 4294967295
|
||||||
|
|
||||||
bool check(const char *str, unsigned int number) {
|
bool check(const char *const str, unsigned int number) {
|
||||||
static char expected[256];
|
static char expected[256];
|
||||||
sprintf(expected, "%s%d", OTHERLAND_MSG, number);
|
sprintf(expected, "%s%d", OTHERLAND_MSG, number);
|
||||||
bool matches = (strcmp(str, expected) == 0);
|
bool matches = (strcmp(str, expected) == 0);
|
||||||
|
|
@ -105,6 +105,18 @@ bool SetConstCharArrayStaticString(const char str[], unsigned int number) {
|
||||||
return check(static_str, number);
|
return check(static_str, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SetCharConstStaticString(char *const str, unsigned int number) {
|
||||||
|
static char static_str[] = CPLUSPLUS_MSG;
|
||||||
|
strcpy(static_str, str);
|
||||||
|
return check(static_str, number);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetConstCharConstStaticString(const char *const str, unsigned int number) {
|
||||||
|
static char static_str[] = CPLUSPLUS_MSG;
|
||||||
|
strcpy(static_str, str);
|
||||||
|
return check(static_str, number);
|
||||||
|
}
|
||||||
|
|
||||||
// get set function
|
// get set function
|
||||||
char *CharPingPong(char *str) {
|
char *CharPingPong(char *str) {
|
||||||
return str;
|
return str;
|
||||||
|
|
|
||||||
|
|
@ -387,12 +387,14 @@ CPP_TEST_CASES += \
|
||||||
typedef_scope \
|
typedef_scope \
|
||||||
typedef_sizet \
|
typedef_sizet \
|
||||||
typedef_struct \
|
typedef_struct \
|
||||||
|
typemap_delete \
|
||||||
typemap_global_scope \
|
typemap_global_scope \
|
||||||
typemap_namespace \
|
typemap_namespace \
|
||||||
typemap_ns_using \
|
typemap_ns_using \
|
||||||
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 \
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,16 @@ public class char_strings_runme {
|
||||||
throw new Exception("Test char set 6 failed, iteration " + i);
|
throw new Exception("Test char set 6 failed, iteration " + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
if (!char_strings.SetCharConstStaticString(OTHERLAND_MSG + i, i))
|
||||||
|
throw new Exception("Test char set 7 failed, iteration " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
if (!char_strings.SetConstCharConstStaticString(OTHERLAND_MSG + i, i))
|
||||||
|
throw new Exception("Test char set 8 failed, iteration " + i);
|
||||||
|
}
|
||||||
|
|
||||||
// get set function
|
// get set function
|
||||||
for (i=0; i<count*10; i++) {
|
for (i=0; i<count*10; i++) {
|
||||||
string ping = OTHERLAND_MSG + i;
|
string ping = OTHERLAND_MSG + i;
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ public class runme {
|
||||||
throw new Exception("test failed");
|
throw new Exception("test failed");
|
||||||
if (special_variable_macros.testJim(name) != "multiname num")
|
if (special_variable_macros.testJim(name) != "multiname num")
|
||||||
throw new Exception("test failed");
|
throw new Exception("test failed");
|
||||||
if (special_variable_macros.testJohn(new PairIntBool(10, false)) != 123)
|
|
||||||
throw new Exception("test failed");
|
|
||||||
NewName newName = NewName.factory("factoryname");
|
NewName newName = NewName.factory("factoryname");
|
||||||
name = newName.getStoredName();
|
name = newName.getStoredName();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,16 @@ public class char_strings_runme {
|
||||||
throw new RuntimeException("Test char set 6 failed, iteration " + i);
|
throw new RuntimeException("Test char set 6 failed, iteration " + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
if (!char_strings.SetCharConstStaticString(OTHERLAND_MSG + i, i))
|
||||||
|
throw new RuntimeException("Test char set 7 failed, iteration " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
if (!char_strings.SetConstCharConstStaticString(OTHERLAND_MSG + i, i))
|
||||||
|
throw new RuntimeException("Test char set 8 failed, iteration " + i);
|
||||||
|
}
|
||||||
|
|
||||||
// get set function
|
// get set function
|
||||||
for (i=0; i<count; i++) {
|
for (i=0; i<count; i++) {
|
||||||
String ping = OTHERLAND_MSG + i;
|
String ping = OTHERLAND_MSG + i;
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ public class special_variable_macros_runme {
|
||||||
throw new RuntimeException("test failed");
|
throw new RuntimeException("test failed");
|
||||||
if (!special_variable_macros.testJim(name).equals("multiname num"))
|
if (!special_variable_macros.testJim(name).equals("multiname num"))
|
||||||
throw new RuntimeException("test failed");
|
throw new RuntimeException("test failed");
|
||||||
if (special_variable_macros.testJohn(new PairIntBool(10, false)) != 123)
|
|
||||||
throw new RuntimeException("test failed");
|
|
||||||
NewName newName = NewName.factory("factoryname");
|
NewName newName = NewName.factory("factoryname");
|
||||||
name = newName.getStoredName();
|
name = newName.getStoredName();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,4 @@ if special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap":
|
||||||
raise "test failed"
|
raise "test failed"
|
||||||
if special_variable_macros.testJim(name) != "multiname num":
|
if special_variable_macros.testJim(name) != "multiname num":
|
||||||
raise "test failed"
|
raise "test failed"
|
||||||
if special_variable_macros.testJohn(special_variable_macros.PairIntBool(10, False)) != 123:
|
|
||||||
raise "test failed"
|
|
||||||
|
|
||||||
|
|
|
||||||
5
Examples/test-suite/python/typemap_delete_runme.py
Normal file
5
Examples/test-suite/python/typemap_delete_runme.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import typemap_delete
|
||||||
|
|
||||||
|
r = typemap_delete.Rect(123)
|
||||||
|
if r.val != 123:
|
||||||
|
raise RuntimeError
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ const char * testMary(Name *mary) {
|
||||||
%{
|
%{
|
||||||
/*%typemap(in) (Name *multiname, int num) start */
|
/*%typemap(in) (Name *multiname, int num) start */
|
||||||
temp_name = $*1_ltype("multiname num");
|
temp_name = $*1_ltype("multiname num");
|
||||||
temp_count = (int)strlen(temp_name.getNamePtr()->getName());
|
temp_count = strlen(temp_name.getNamePtr()->getName());
|
||||||
(void)$input;
|
(void)$input;
|
||||||
$1 = temp_name.getNamePtr();
|
$1 = temp_name.getNamePtr();
|
||||||
$2 = temp_count + 100;
|
$2 = temp_count + 100;
|
||||||
|
|
@ -103,7 +103,7 @@ $typemap(in, (Name *multiname, int num))
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
const char * testJim(Name *jim, int count) {
|
const char * testJim(Name *jim, int count) {
|
||||||
if (count != (int)strlen(jim->getNamePtr()->getName()) + 100)
|
if (count != strlen(jim->getNamePtr()->getName()) + 100)
|
||||||
return "size check failed";
|
return "size check failed";
|
||||||
else
|
else
|
||||||
return jim->getName();
|
return jim->getName();
|
||||||
|
|
|
||||||
16
Examples/test-suite/typemap_delete.i
Normal file
16
Examples/test-suite/typemap_delete.i
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
%module typemap_delete
|
||||||
|
|
||||||
|
%typemap(in) Rect* (Rect temp) {
|
||||||
|
$1 = 0;
|
||||||
|
will_not_compile
|
||||||
|
}
|
||||||
|
|
||||||
|
%typemap(in) Rect*;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Rect
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
Rect(int v) : val(v) {}
|
||||||
|
};
|
||||||
|
%}
|
||||||
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;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ SWIGINTERN int
|
||||||
SWIG_AsCharPtrAndSize(SEXP obj, char** cptr, size_t* psize, int *alloc)
|
SWIG_AsCharPtrAndSize(SEXP obj, char** cptr, size_t* psize, int *alloc)
|
||||||
{
|
{
|
||||||
if (cptr && Rf_isString(obj)) {
|
if (cptr && Rf_isString(obj)) {
|
||||||
const char *cstr = CHAR(STRING_ELT(obj, 0));
|
char *cstr = %const_cast(CHAR(STRING_ELT(obj, 0)), char *);
|
||||||
int len = strlen(cstr);
|
int len = strlen(cstr);
|
||||||
|
|
||||||
if (alloc) {
|
if (alloc) {
|
||||||
|
|
@ -130,9 +130,7 @@ SWIG_AsCharPtrAndSize(SEXP obj, char** cptr, size_t* psize, int *alloc)
|
||||||
*cptr = %new_copy_array(cstr, len + 1, char);
|
*cptr = %new_copy_array(cstr, len + 1, char);
|
||||||
*alloc = SWIG_NEWOBJ;
|
*alloc = SWIG_NEWOBJ;
|
||||||
} else {
|
} else {
|
||||||
*cptr = %reinterpret_cast(malloc(len + 1), char *);
|
*cptr = cstr;
|
||||||
*cptr = strcpy(*cptr, cstr);
|
|
||||||
*alloc = SWIG_OLDOBJ;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*cptr = %reinterpret_cast(malloc(len + 1), char *);
|
*cptr = %reinterpret_cast(malloc(len + 1), char *);
|
||||||
|
|
|
||||||
|
|
@ -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,12 +718,13 @@ 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);
|
||||||
result = typemap_search_helper(debug_display, tm, tm_method, ctype, cqualifiedname, cname, &backup);
|
result = typemap_search_helper(debug_display, tm, tm_method, ctype, cqualifiedname, cname, &backup);
|
||||||
if (result)
|
if (result && Getattr(result, "code"))
|
||||||
goto ret_result;
|
goto ret_result;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -733,7 +734,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
||||||
tm = get_typemap(ts, template_prefix);
|
tm = get_typemap(ts, template_prefix);
|
||||||
result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup);
|
result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup);
|
||||||
Delete(template_prefix);
|
Delete(template_prefix);
|
||||||
if (result)
|
if (result && Getattr(result, "code"))
|
||||||
goto ret_result;
|
goto ret_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -747,33 +748,29 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
||||||
tm = get_typemap(ts, noarrays);
|
tm = get_typemap(ts, noarrays);
|
||||||
result = typemap_search_helper(debug_display, tm, tm_method, noarrays, cqualifiedname, cname, &backup);
|
result = typemap_search_helper(debug_display, tm, tm_method, noarrays, cqualifiedname, cname, &backup);
|
||||||
Delete(noarrays);
|
Delete(noarrays);
|
||||||
if (result)
|
if (result && Getattr(result, "code"))
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -783,7 +780,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
||||||
while (primitive) {
|
while (primitive) {
|
||||||
tm = get_typemap(ts, primitive);
|
tm = get_typemap(ts, primitive);
|
||||||
result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup);
|
result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup);
|
||||||
if (result)
|
if (result && Getattr(result, "code"))
|
||||||
goto ret_result;
|
goto ret_result;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -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