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)
|
||||
============================
|
||||
|
||||
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
|
||||
[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
|
||||
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
|
||||
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
|
||||
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_typedef_reductions">Typedef reductions matching</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_debugging_search">Debugging typemap pattern matching</a>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -2124,8 +2124,8 @@ Object 'RCObj', which implements the ref/unref idiom.
|
|||
|
||||
<p>
|
||||
To tell SWIG that 'RCObj' and all its derived classes are reference
|
||||
counted objects, you use the "ref" and "unref" features, or
|
||||
<tt>%ref</tt> and <tt>%unref</tt> directives (since 1.3.28). For example:
|
||||
counted objects, you use the "ref" and "unref" features.
|
||||
For example:
|
||||
</p>
|
||||
|
||||
|
||||
|
|
@ -2143,25 +2143,6 @@ counted objects, you use the "ref" and "unref" features, or
|
|||
</pre>
|
||||
</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>
|
||||
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
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
<li><a href="#Typemaps_nn17">Basic matching rules</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_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_debugging_search">Debugging typemap pattern matching</a>
|
||||
</ul>
|
||||
|
|
@ -1026,8 +1027,10 @@ is used.
|
|||
</ul>
|
||||
|
||||
<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.
|
||||
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>
|
||||
|
|
@ -1056,8 +1059,8 @@ To find a typemap for the argument <tt>const char *s</tt>, SWIG will search for
|
|||
<pre>
|
||||
const char *s Exact type and name match
|
||||
const char * Exact type match
|
||||
char *s Type and name match (stripped qualifiers)
|
||||
char * Type match (stripped qualifiers)
|
||||
char *s Type and name match (qualifier stripped)
|
||||
char * Type match (qualifier stripped)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1097,6 +1100,11 @@ void F(int x[1000]); // int [ANY] rule (typemap 5)
|
|||
</pre>
|
||||
</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>
|
||||
|
||||
|
||||
|
|
@ -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.
|
||||
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>.
|
||||
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.
|
||||
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>
|
||||
|
|
@ -1407,11 +1415,10 @@ Finally the best way to view the typemap matching rules in action is via the <a
|
|||
|
||||
<p>
|
||||
<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>
|
||||
|
||||
|
||||
<H3><a name="Typemaps_multi_argument_typemaps_patterns"></a>10.3.4 Multi-arguments typemaps</H3>
|
||||
<H3><a name="Typemaps_multi_argument_typemaps_patterns"></a>10.3.5 Multi-arguments typemaps</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1441,7 +1448,165 @@ but all subsequent arguments must match exactly.
|
|||
</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>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ below.
|
|||
static char *global_str = NULL;
|
||||
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];
|
||||
sprintf(expected, "%s%d", OTHERLAND_MSG, number);
|
||||
bool matches = (strcmp(str, expected) == 0);
|
||||
|
|
@ -105,6 +105,18 @@ bool SetConstCharArrayStaticString(const char str[], unsigned int 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
|
||||
char *CharPingPong(char *str) {
|
||||
return str;
|
||||
|
|
|
|||
|
|
@ -387,12 +387,14 @@ CPP_TEST_CASES += \
|
|||
typedef_scope \
|
||||
typedef_sizet \
|
||||
typedef_struct \
|
||||
typemap_delete \
|
||||
typemap_global_scope \
|
||||
typemap_namespace \
|
||||
typemap_ns_using \
|
||||
typemap_numinputs \
|
||||
typemap_template \
|
||||
typemap_out_optimal \
|
||||
typemap_qualifier_strip \
|
||||
typemap_variables \
|
||||
typemap_various \
|
||||
typename \
|
||||
|
|
|
|||
|
|
@ -76,6 +76,16 @@ public class char_strings_runme {
|
|||
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
|
||||
for (i=0; i<count*10; i++) {
|
||||
string ping = OTHERLAND_MSG + i;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ public class runme {
|
|||
throw new Exception("test failed");
|
||||
if (special_variable_macros.testJim(name) != "multiname num")
|
||||
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");
|
||||
name = newName.getStoredName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,16 @@ public class char_strings_runme {
|
|||
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
|
||||
for (i=0; i<count; i++) {
|
||||
String ping = OTHERLAND_MSG + i;
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ public class special_variable_macros_runme {
|
|||
throw new RuntimeException("test failed");
|
||||
if (!special_variable_macros.testJim(name).equals("multiname num"))
|
||||
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");
|
||||
name = newName.getStoredName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,4 @@ if special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap":
|
|||
raise "test failed"
|
||||
if special_variable_macros.testJim(name) != "multiname num":
|
||||
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 */
|
||||
temp_name = $*1_ltype("multiname num");
|
||||
temp_count = (int)strlen(temp_name.getNamePtr()->getName());
|
||||
temp_count = strlen(temp_name.getNamePtr()->getName());
|
||||
(void)$input;
|
||||
$1 = temp_name.getNamePtr();
|
||||
$2 = temp_count + 100;
|
||||
|
|
@ -103,7 +103,7 @@ $typemap(in, (Name *multiname, int num))
|
|||
|
||||
%inline %{
|
||||
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";
|
||||
else
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
*alloc = SWIG_NEWOBJ;
|
||||
} else {
|
||||
*cptr = %reinterpret_cast(malloc(len + 1), char *);
|
||||
*cptr = strcpy(*cptr, cstr);
|
||||
*alloc = SWIG_OLDOBJ;
|
||||
*cptr = cstr;
|
||||
}
|
||||
} else {
|
||||
*cptr = %reinterpret_cast(malloc(len + 1), char *);
|
||||
|
|
|
|||
|
|
@ -357,8 +357,8 @@ SwigType *SwigType_default_create(SwigType *ty) {
|
|||
* SwigType_default_deduce()
|
||||
*
|
||||
* This function implements type deduction used in the typemap matching rules
|
||||
* and is very close to the type deduction used in partial template specialization
|
||||
* matching in that the most specialized type is always chosen.
|
||||
* and is very close to the type deduction used in partial template class
|
||||
* 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
|
||||
* 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_check_decl(SwigType *t, const_String_or_char_ptr decl);
|
||||
extern SwigType *SwigType_strip_qualifiers(SwigType *t);
|
||||
extern SwigType *SwigType_strip_single_qualifier(SwigType *t);
|
||||
extern SwigType *SwigType_functionpointer_decompose(SwigType *t);
|
||||
extern String *SwigType_base(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;
|
||||
SwigType *primitive = 0;
|
||||
SwigType *ctype = 0;
|
||||
SwigType *ctype_unstripped = 0;
|
||||
int ts;
|
||||
int isarray;
|
||||
const String *cname = 0;
|
||||
const String *cqualifiedname = 0;
|
||||
SwigType *unstripped = 0;
|
||||
String *tm_method = typemap_method_name(tmap_method);
|
||||
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);
|
||||
}
|
||||
while (ts >= 0) {
|
||||
ctype = type;
|
||||
ctype = Copy(type);
|
||||
ctype_unstripped = Copy(ctype);
|
||||
while (ctype) {
|
||||
/* Try to get an exact type-match */
|
||||
tm = get_typemap(ts, ctype);
|
||||
result = typemap_search_helper(debug_display, tm, tm_method, ctype, cqualifiedname, cname, &backup);
|
||||
if (result)
|
||||
if (result && Getattr(result, "code"))
|
||||
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);
|
||||
result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup);
|
||||
Delete(template_prefix);
|
||||
if (result)
|
||||
if (result && Getattr(result, "code"))
|
||||
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);
|
||||
result = typemap_search_helper(debug_display, tm, tm_method, noarrays, cqualifiedname, cname, &backup);
|
||||
Delete(noarrays);
|
||||
if (result)
|
||||
if (result && Getattr(result, "code"))
|
||||
goto ret_result;
|
||||
}
|
||||
|
||||
/* No match so far. If the type is unstripped, we'll strip its
|
||||
qualifiers and check. Otherwise, we'll try to resolve a typedef */
|
||||
|
||||
if (!unstripped) {
|
||||
unstripped = ctype;
|
||||
ctype = SwigType_strip_qualifiers(ctype);
|
||||
if (!Equal(ctype, unstripped))
|
||||
continue; /* Types are different */
|
||||
Delete(ctype);
|
||||
ctype = unstripped;
|
||||
unstripped = 0;
|
||||
}
|
||||
/* No match so far - try with a qualifier stripped (strip one qualifier at a time until none remain)
|
||||
* 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. */
|
||||
{
|
||||
String *octype;
|
||||
if (unstripped) {
|
||||
Delete(ctype);
|
||||
ctype = unstripped;
|
||||
unstripped = 0;
|
||||
SwigType *oldctype = ctype;
|
||||
ctype = SwigType_strip_single_qualifier(oldctype);
|
||||
if (!Equal(ctype, oldctype)) {
|
||||
Delete(oldctype);
|
||||
continue;
|
||||
}
|
||||
octype = ctype;
|
||||
ctype = SwigType_typedef_resolve(ctype);
|
||||
if (octype != type)
|
||||
Delete(octype);
|
||||
Delete(oldctype);
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
tm = get_typemap(ts, primitive);
|
||||
result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup);
|
||||
if (result)
|
||||
if (result && Getattr(result, "code"))
|
||||
goto ret_result;
|
||||
|
||||
{
|
||||
|
|
@ -802,12 +799,10 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
|
|||
|
||||
ret_result:
|
||||
Delete(primitive);
|
||||
if ((unstripped) && (unstripped != type))
|
||||
Delete(unstripped);
|
||||
if (matchtype)
|
||||
*matchtype = Copy(ctype);
|
||||
if (type != ctype)
|
||||
Delete(ctype);
|
||||
Delete(ctype);
|
||||
Delete(ctype_unstripped);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1125,3 +1125,62 @@ SwigType *SwigType_strip_qualifiers(SwigType *t) {
|
|||
}
|
||||
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