Fix %import and %fragment forced inclusion to not generate code.
This commit is contained in:
parent
857a62425c
commit
57a89f987d
8 changed files with 186 additions and 7 deletions
|
|
@ -7,6 +7,28 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.0.0 (in progress)
|
Version 4.0.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2017-06-03: wsfulton
|
||||||
|
Fix %import on a file containing a file scope %fragment forced inclusion to not
|
||||||
|
generate the fragment contents as %import should not result in code being generated.
|
||||||
|
The behaviour is now the same as importing code insertion blocks.
|
||||||
|
Wrapping FileC.i in the following example will result in no generated code, whereas
|
||||||
|
previously "#include <limits.h>" was generated:
|
||||||
|
|
||||||
|
// FileA.i
|
||||||
|
%fragment("<limits.h>", "header") %{
|
||||||
|
#include <limits.h>
|
||||||
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
%}
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
|
||||||
|
// FileC.i
|
||||||
|
%import "FileA.i"
|
||||||
|
|
||||||
|
*** POTENTIAL INCOMPATIBILITY ***
|
||||||
|
|
||||||
2017-05-26: Volker Diels-Grabsch, vadz
|
2017-05-26: Volker Diels-Grabsch, vadz
|
||||||
[Java] Implement java.util.List<> for std::vector. This notably allows to
|
[Java] Implement java.util.List<> for std::vector. This notably allows to
|
||||||
iterate over wrapped vectors in a natural way.
|
iterate over wrapped vectors in a natural way.
|
||||||
|
|
|
||||||
|
|
@ -3904,9 +3904,9 @@ A fragment can use one or more additional fragments, for example:
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%fragment("<limits.h>", "header") {
|
%fragment("<limits.h>", "header") %{
|
||||||
%#include <limits.h>
|
#include <limits.h>
|
||||||
}
|
%}
|
||||||
|
|
||||||
|
|
||||||
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
||||||
|
|
@ -3989,8 +3989,91 @@ Finally, you can force the inclusion of a fragment at any point in the generated
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
which is very useful inside a template class, for example.
|
which, for example, is very useful inside a template class.
|
||||||
|
Another useful case is when using <tt>%extend</tt> inside a class
|
||||||
|
where the additional code in the <tt>%extend</tt> block depends on the contents of the fragment.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%fragment("<limits.h>", "header") %{
|
||||||
|
#include <limits.h>
|
||||||
|
%}
|
||||||
|
|
||||||
|
struct X {
|
||||||
|
...
|
||||||
|
%extend {
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
bool check(short val) {
|
||||||
|
if (val < SHRT_MIN /*defined in <limits.h>*/) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Forced inclusion of fragments can be used as a replacement for <a href="SWIG.html#SWIG_nn42">code insertion block</a>, ensuring the
|
||||||
|
code block is only generated once.
|
||||||
|
Consider the contents of FileA.i below which first uses a code insertion block and then a forced fragment inclusion to generate code:
|
||||||
|
<p>
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
// FileA.i
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
%}
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
and another file including the above:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
// FileB.i
|
||||||
|
%include "FileA.i"
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The resulting code in the wrappers for FileB.i is:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A note of caution must be mentioned when using <tt>%fragment</tt> forced inclusion or code insertion blocks with <tt>%import</tt>.
|
||||||
|
If <tt>%import</tt> is used instead:
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
// FileC.i
|
||||||
|
%import "FileA.i"
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
then nothing is generated in the resulting code in the wrappers for FileC.i.
|
||||||
|
This is because <tt>%import</tt> is for collecting type information and does not result in any code
|
||||||
|
being generated, see <a href="Preprocessor.html#Preprocessor_nn3">File Imports</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,7 @@ CPP_TEST_CASES += \
|
||||||
global_vars \
|
global_vars \
|
||||||
grouping \
|
grouping \
|
||||||
ignore_parameter \
|
ignore_parameter \
|
||||||
|
import_fragments \
|
||||||
import_nomodule \
|
import_nomodule \
|
||||||
inherit \
|
inherit \
|
||||||
inherit_member \
|
inherit_member \
|
||||||
|
|
|
||||||
18
Examples/test-suite/import_fragments.i
Normal file
18
Examples/test-suite/import_fragments.i
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
%module import_fragments
|
||||||
|
|
||||||
|
// Check %fragments forced inclusion does not result in code generation when using %import
|
||||||
|
%import "import_fragments_a.i"
|
||||||
|
|
||||||
|
%{
|
||||||
|
template<typename T>
|
||||||
|
struct TemplateA4 {};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%template(TemplateA4Int) TemplateA4<int>;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
int getImport4() {
|
||||||
|
// Requires the ImportA4 fragment to be generated in order to compile
|
||||||
|
return ImportA4;
|
||||||
|
}
|
||||||
|
%}
|
||||||
45
Examples/test-suite/import_fragments_a.i
Normal file
45
Examples/test-suite/import_fragments_a.i
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
%module import_fragments_a
|
||||||
|
|
||||||
|
%fragment("ImportA1", "header") %{
|
||||||
|
ImportA1_this_will_not_compile;
|
||||||
|
%}
|
||||||
|
%fragment("ImportA2", "header") %{
|
||||||
|
ImportA2_this_will_not_compile;
|
||||||
|
%}
|
||||||
|
%fragment("ImportA3", "header") %{
|
||||||
|
ImportA3_this_will_not_compile;
|
||||||
|
%}
|
||||||
|
%fragment("ImportA4", "header") %{
|
||||||
|
static int ImportA4 = 99;
|
||||||
|
%}
|
||||||
|
%fragment("ImportA5", "header") %{
|
||||||
|
ImportA5_this_will_not_compile;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%fragment("ImportA1");
|
||||||
|
|
||||||
|
%{
|
||||||
|
Import_will_not_compile;
|
||||||
|
%}
|
||||||
|
|
||||||
|
struct StructA {
|
||||||
|
%fragment("ImportA2");
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct TemplateA3 {
|
||||||
|
%fragment("ImportA3");
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct TemplateA4 {
|
||||||
|
%fragment("ImportA4");
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct TemplateA5 {
|
||||||
|
%fragment("ImportA5");
|
||||||
|
};
|
||||||
|
%template(TemplateA5Double) TemplateA5<double>;
|
||||||
|
|
||||||
|
%include "import_fragments_b.i"
|
||||||
9
Examples/test-suite/import_fragments_b.i
Normal file
9
Examples/test-suite/import_fragments_b.i
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
%module import_fragments_b
|
||||||
|
|
||||||
|
%fragment("ImportB", "header") %{
|
||||||
|
ImportB_this_will_not_compile;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%fragment("ImportB");
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -462,10 +462,10 @@ int JAVASCRIPT::fragmentDirective(Node *n) {
|
||||||
// and register them at the emitter.
|
// and register them at the emitter.
|
||||||
String *section = Getattr(n, "section");
|
String *section = Getattr(n, "section");
|
||||||
|
|
||||||
if (Equal(section, "templates")) {
|
if (Equal(section, "templates") && !ImportMode) {
|
||||||
emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code"));
|
emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code"));
|
||||||
} else {
|
} else {
|
||||||
Swig_fragment_register(n);
|
return Language::fragmentDirective(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
|
|
|
||||||
|
|
@ -624,7 +624,8 @@ int Language::constantDirective(Node *n) {
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
int Language::fragmentDirective(Node *n) {
|
int Language::fragmentDirective(Node *n) {
|
||||||
Swig_fragment_register(n);
|
if (!(Getattr(n, "emitonly") && ImportMode))
|
||||||
|
Swig_fragment_register(n);
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue