mirror of https://github.com/swig/swig
Add support for "ret" typemap where missing and improve documentation on it.
This commit is contained in:
parent
7bfa5fb951
commit
08688d7d9d
|
@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Version 3.0.11 (in progress)
|
||||
============================
|
||||
|
||||
2016-09-29: wsfulton
|
||||
[Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab]
|
||||
Add missing support for the "ret" typemap in a few target languages.
|
||||
The documentation also now has info on the "ret" typemap.
|
||||
|
||||
2016-09-27: ahmed-usman
|
||||
[xml] Handle template parameters correctly.
|
||||
|
||||
|
|
|
@ -457,6 +457,7 @@
|
|||
<li><a href="Typemaps.html#Typemaps_nn32">"argout" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn33">"freearg" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn34">"newfree" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_ret">"ret" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn36">"varin" typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn37">"varout" typemap</a>
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
<li><a href="#Typemaps_nn32">"argout" typemap</a>
|
||||
<li><a href="#Typemaps_nn33">"freearg" typemap</a>
|
||||
<li><a href="#Typemaps_nn34">"newfree" typemap</a>
|
||||
<li><a href="#Typemaps_ret">"ret" typemap</a>
|
||||
<li><a href="#Typemaps_nn35">"memberin" typemap</a>
|
||||
<li><a href="#Typemaps_nn36">"varin" typemap</a>
|
||||
<li><a href="#Typemaps_nn37">"varout" typemap</a>
|
||||
|
@ -2802,7 +2803,46 @@ string *foo();
|
|||
See <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for further details.
|
||||
</p>
|
||||
|
||||
<H3><a name="Typemaps_nn35">11.5.10 "memberin" typemap</a></H3>
|
||||
<H3><a name="Typemaps_ret">11.5.10 "ret" typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The "ret" typemap is not used very often, but can be useful for anything associated with
|
||||
the return type, such as resource management, return value error checking, etc.
|
||||
Usually this can all be done in the "out" typemap, but sometimes it is handy to use the
|
||||
"out" typemap code untouched and add to the generated code using the code in the "ret" typemap.
|
||||
One such case is memory clean up. For example, a <tt>stringheap_t</tt> type is defined indicating
|
||||
that the returned memory must be deleted and a <tt>string_t</tt> type is defined indicating
|
||||
that the returned memory must not be deleted.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(ret) stringheap_t %{
|
||||
free($1);
|
||||
%}
|
||||
|
||||
typedef char * string_t;
|
||||
typedef char * stringheap_t;
|
||||
|
||||
string_t MakeString1();
|
||||
stringheap_t MakeString2();
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The "ret" typemap above will only be used for <tt>MakeString2</tt>, but both functions
|
||||
will use the default "out" typemap for <tt>char *</tt> provided by SWIG.
|
||||
The code above would ensure the appropriate memory is freed in all target languages as the need
|
||||
to provide custom "out" typemaps (which involve target language specific code) is not necessary.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This approach is an alternative to using the "newfree" typemap and <tt>%newobject</tt> as there
|
||||
is no need to list all the functions that require the memory cleanup, it is purely done on types.
|
||||
</p>
|
||||
|
||||
<H3><a name="Typemaps_nn35">11.5.11 "memberin" typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -2824,7 +2864,7 @@ It is rarely necessary to write "memberin" typemaps---SWIG already provides
|
|||
a default implementation for arrays, strings, and other objects.
|
||||
</p>
|
||||
|
||||
<H3><a name="Typemaps_nn36">11.5.11 "varin" typemap</a></H3>
|
||||
<H3><a name="Typemaps_nn36">11.5.12 "varin" typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -2832,7 +2872,7 @@ The "varin" typemap is used to convert objects in the target language to C for t
|
|||
purposes of assigning to a C/C++ global variable. This is implementation specific.
|
||||
</p>
|
||||
|
||||
<H3><a name="Typemaps_nn37">11.5.12 "varout" typemap</a></H3>
|
||||
<H3><a name="Typemaps_nn37">11.5.13 "varout" typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
@ -2840,7 +2880,7 @@ The "varout" typemap is used to convert a C/C++ object to an object in the targe
|
|||
language when reading a C/C++ global variable. This is implementation specific.
|
||||
</p>
|
||||
|
||||
<H3><a name="throws_typemap">11.5.13 "throws" typemap</a></H3>
|
||||
<H3><a name="throws_typemap">11.5.14 "throws" typemap</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
@ -25,23 +25,33 @@ void foo1(Foo<int> f, const Foo<int>& ff) {}
|
|||
void foo2(Foo<short> f, const Foo<short>& ff) {}
|
||||
%}
|
||||
|
||||
#ifdef SWIGUTL
|
||||
%typemap(ret) int Bar1::foo() { /* hello1 */ };
|
||||
%typemap(ret) int Bar2::foo() { /* hello2 */ };
|
||||
%typemap(ret) int foo() {/* hello3 */ };
|
||||
#endif
|
||||
// Check "ret" typemap is implemented
|
||||
%{
|
||||
template<typename T> struct NeededForTest {};
|
||||
%}
|
||||
%fragment("NeededForTest", "header") %{
|
||||
template<> struct NeededForTest<short> { NeededForTest(short) {} };
|
||||
%}
|
||||
|
||||
%typemap(ret) short "_ret_typemap_for_short_no_compile"
|
||||
%typemap(ret, fragment="NeededForTest") short Bar1::foofunction() { /* ret typemap for short */ NeededForTest<short> needed($1); };
|
||||
%typemap(ret, fragment="NeededForTest") short globalfoofunction() { /* ret typemap for short */ NeededForTest<short> needed($1); };
|
||||
|
||||
%inline %{
|
||||
struct Bar1 {
|
||||
int foo() { return 1;}
|
||||
};
|
||||
|
||||
struct Bar2 {
|
||||
int foo() { return 1;}
|
||||
short foofunction() { return 1;}
|
||||
};
|
||||
short globalfoofunction() { return 1;}
|
||||
%}
|
||||
|
||||
|
||||
%{
|
||||
void CheckRetTypemapUsed() {
|
||||
// If the "ret" typemap is not used, the NeededForTest template specialization will not have been
|
||||
// generated and so the following code will result in a compile failure
|
||||
NeededForTest<short> needed(111);
|
||||
(void)needed;
|
||||
}
|
||||
%}
|
||||
|
||||
%newobject FFoo::Bar(bool) const ;
|
||||
%typemap(newfree) char* Bar(bool) {
|
||||
|
@ -62,7 +72,7 @@ void foo2(Foo<short> f, const Foo<short>& ff) {}
|
|||
#endif
|
||||
|
||||
// Test obscure bug where named typemaps where not being applied when symbol name contained a number
|
||||
%typemap(out) double "_typemap_for_double_no_compile_"
|
||||
%typemap(out) double "_out_typemap_for_double_no_compile_"
|
||||
%typemap(out) double ABCD::meth {$1 = 0.0; TYPEMAP_OUT_INIT}
|
||||
%typemap(out) double ABCD::m1 {$1 = 0.0; TYPEMAP_OUT_INIT}
|
||||
%typemap(out) double ABCD::_x2 {$1 = 0.0; TYPEMAP_OUT_INIT}
|
||||
|
|
|
@ -2722,6 +2722,13 @@ int ALLEGROCL::functionWrapper(Node *n) {
|
|||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
emit_return_variable(n, t, f);
|
||||
|
||||
if (CPlusPlus) {
|
||||
|
|
|
@ -543,6 +543,14 @@ int CFFI::functionWrapper(Node *n) {
|
|||
|
||||
cleanupFunction(n, f, parms);
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
String *tm = 0;
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
if (!is_void_return) {
|
||||
Printf(f->code, " return lresult;\n");
|
||||
}
|
||||
|
|
|
@ -2599,6 +2599,14 @@ private:
|
|||
Replaceall(f->code, "$cleanup", cleanup);
|
||||
Delete(cleanup);
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
String *tm;
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
Replaceall(f->code, "$symname", Getattr(n, "sym:name"));
|
||||
}
|
||||
|
||||
|
|
|
@ -1354,6 +1354,11 @@ void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) {
|
|||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Printf(wrapper->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
}
|
||||
|
||||
int JSEmitter::switchNamespace(Node *n) {
|
||||
|
|
|
@ -676,6 +676,14 @@ public:
|
|||
Printv(f->code, tm, "\n", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
// Free any memory allocated by the function being wrapped..
|
||||
|
||||
if ((tm = Swig_typemap_lookup("swig_result", n, Swig_cresult_name(), 0))) {
|
||||
|
|
|
@ -2097,6 +2097,13 @@ int R::functionWrapper(Node *n) {
|
|||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(f->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
Printv(f->code, UnProtectWrapupCode, NIL);
|
||||
|
||||
/*If the user gave us something to convert the result in */
|
||||
|
|
|
@ -412,7 +412,7 @@ public:
|
|||
emit_return_variable(node, functionReturnType, wrapper);
|
||||
|
||||
/* Return the function value if necessary */
|
||||
String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, "result", wrapper, functionActionCode);
|
||||
String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, Swig_cresult_name(), wrapper, functionActionCode);
|
||||
if (functionReturnTypemap) {
|
||||
// Result is actually the position of output value on stack
|
||||
if (Len(functionReturnTypemap) > 0) {
|
||||
|
@ -471,6 +471,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/* See if there is any return cleanup code */
|
||||
String *tm;
|
||||
if ((tm = Swig_typemap_lookup("ret", node, Swig_cresult_name(), 0))) {
|
||||
Replaceall(tm, "$source", Swig_cresult_name());
|
||||
Printf(wrapper->code, "%s\n", tm);
|
||||
Delete(tm);
|
||||
}
|
||||
|
||||
/* Close the function(ok) */
|
||||
Printv(wrapper->code, "return SWIG_OK;\n", NIL);
|
||||
|
|
Loading…
Reference in New Issue