Merge branch 'master' into C

Perform only minimum conflict resolution, C backend tests don't pass
yet.
This commit is contained in:
Vadim Zeitlin 2024-06-16 16:24:15 +02:00
commit 19c0b351e6
244 changed files with 6808 additions and 2457 deletions

View File

@ -27,7 +27,7 @@ jobs:
# By default, the name of the build is the language used and SWIG options, but matrix entries
# can define the additional "desc" field with any additional information to include in the name.
name: ${{ matrix.SWIGLANG || 'none' }}${{ matrix.PY2 }} ${{ matrix.ENGINE}} ${{ matrix.VER }} ${{ matrix.SWIG_FEATURES }} ${{ (matrix.compiler || 'gcc') }}${{ matrix.GCC }} ${{ matrix.CPPSTD }} ${{ matrix.CSTD }} ${{ matrix.EXTRA_CXXFLAGS }} ${{ matrix.desc }} ${{ matrix.continue-on-error && '(can fail)' }}
name: ${{ matrix.SWIGLANG || 'none' }}${{ matrix.PY2 }} ${{ matrix.ENGINE}} ${{ matrix.VER }} ${{ matrix.PY_ABI_VER && format('abi={0}', matrix.PY_ABI_VER) }} ${{ matrix.SWIG_FEATURES }} ${{ (matrix.compiler || 'gcc') }}${{ matrix.GCC }} ${{ matrix.CPPSTD }} ${{ matrix.CSTD }} ${{ matrix.desc }} ${{ matrix.continue-on-error && '(can fail)' }}
strategy:
matrix:
@ -164,10 +164,8 @@ jobs:
- SWIGLANG: python
SWIG_FEATURES: -builtin -O
- SWIGLANG: python
EXTRA_CXXFLAGS: -DPy_LIMITED_API=0x03040000
CPPSTD: c++20
GCC: 13
os: ubuntu-22.04
VER: '3.8'
PY_ABI_VER: '3.4'
- SWIGLANG: r
- SWIGLANG: ruby
VER: '2.0'
@ -189,7 +187,7 @@ jobs:
VER: '3.0'
CPPSTD: c++11
- SWIGLANG: ruby
VER: '3.1'
VER: '3.1.4' # import_fragments testcase started to fail on upgrade to 3.1.5, see https://github.com/swig/swig/issues/2800
CPPSTD: c++11
- SWIGLANG: ruby
CPPSTD: c++11
@ -363,7 +361,7 @@ jobs:
CSTD: ${{ matrix.CSTD }}
CPPSTD: ${{ matrix.CPPSTD }}
CPPFLAGS: ${{ matrix.CPPFLAGS }}
EXTRA_CXXFLAGS: ${{ matrix.EXTRA_CXXFLAGS }}
PY_ABI_VER: ${{ matrix.PY_ABI_VER }}
steps:
- name: Machine Info
@ -504,12 +502,12 @@ jobs:
esac
# Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic.
cflags="$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC) $EXTRA_CFLAGS"
cxxflags="$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC) $EXTRA_CXXFLAGS"
cflags="$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC)"
cxxflags="$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC)"
make check-$SWIGLANG-version
make check-$SWIGLANG-enabled
make $SWIGJOBS check-$SWIGLANG-examples CFLAGS="$cflags" CXXFLAGS="$cxxflags"
make $SWIGJOBS check-$SWIGLANG-test-suite CFLAGS="$cflags" CXXFLAGS="$cxxflags"
make $SWIGJOBS check-$SWIGLANG-examples CFLAGS="$cflags" CXXFLAGS="$cxxflags" PY_ABI_VER="$PY_ABI_VER"
make $SWIGJOBS check-$SWIGLANG-test-suite CFLAGS="$cflags" CXXFLAGS="$cxxflags" PY_ABI_VER="$PY_ABI_VER"
fi
- name: Install

1
.gitignore vendored
View File

@ -196,6 +196,7 @@ Examples/php/pragmas/example.php
# Python
# Based on https://github.com/github/gitignore/blob/master/Python.gitignore
*.py[cod]
*_abi3_report.json
*/__pycache__/
/__pycache__/
Examples/test-suite/python/*.py

View File

@ -7,8 +7,151 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.3.0 (in progress)
===========================
2024-06-15: wsfulton
[Python] Removed deprecated pytuplehlp.swg file and t_output_helper.
Use SWIG_Python_AppendOutput instead of t_output_helper.
2024-06-15: vadz
[Python] #2907 Fix returning null from functions with output parameters.
Ensures OUTPUT typemaps are handled consistently.
New declaration of SWIG_Python_AppendOutput is now:
SWIG_Python_AppendOutput(PyObject* result, PyObject* obj, int is_void);
The 3rd parameter is new and the new $isvoid special variable should be
passed to it, indicating whether or not the wrapped function returns void.
*** POTENTIAL INCOMPATIBILITY ***
2024-06-15: wsfulton
#2907 Add $isvoid special variable which expands to 1 if the
wrapped function has a void return, otherwise expands to 0.
2024-06-14: jschueller
#2863 Support Python 3.13 (currently in prerelease).
2024-06-13: erezgeva
#2609 Fix Java typemap (const char *STRING, size_t LENGTH) to
marshall as Java String instead of Java byte[]. If the old behaviour
is required, replace with typemap (const void *BYTES, size_t LENGTH).
Add multi-argument typemaps to most languages:
(const char *STRING, size_t LENGTH)
All languages now use a target language string type for this typemap.
New multi-argument typemaps have been added to most target languages
for use with C raw data (cdata):
(const void *BYTES, size_t LENGTH) to
Statically typed languages use a byte array for this typemap, while
scripting languages remain using a string.
*** POTENTIAL INCOMPATIBILITY ***
* Raw C data: Go uses byte array and int64 for size.
Users can use the (const char *STRING, size_t LENGTH) typemaps for strings.
2024-06-06: olly
Support alignof(T) for arbitrary type T, and deduce the type of
alignof(T) as size_t.
2024-06-06: olly
#2919 Support parsing `sizeof(X)` for any expression or type X by
skipping balanced parentheses. We don't need to actually parse X
since the type of sizeof is always size_t.
2024-06-05: leakec
#2873 Fix -fvirtual and using declarations for inheriting base class methods
corner case.
2024-05-31: wsfulton
[C#, D, Java, Javascript, Lua] Fix %nspace and %nspacemove for nested
classes and enums in a class. For example:
%nspace Space::OuterClass80;
namespace Space {
struct OuterClass80 {
struct InnerClass80 {
struct BottomClass80 {};
};
enum InnerEnum80 { ie80a, ie80b };
};
}
Previously the following were additionally required for some languages:
%nspace Space::OuterClass80::InnerClass80;
%nspace Space::OuterClass80::InnerClass80::Bottom80;
Now the appropriate nspace setting is taken from the outer class.
A new warning has also been introduced to check and correct conflicting
nspace usage, for example if the following is additionally added:
%nspacemove(AnotherSpace) Space::OuterClass80::InnerClass80;
The following warning appears as an inner class can't be moved outside
of the outer class:
Warning 406: Ignoring nspace setting (AnotherSpace) for 'Space::OuterClass80::InnerClass80',
Warning 406: as it conflicts with the nspace setting (Space) for outer class 'Space::OuterClass80'.
2024-05-31: wsfulton
[C#, D, Java, Javascript, Lua] #2782 Enhance the nspace feature with
%nspacemove for moving a class or enum into a differently named target
language equivalent of a namespace.
2024-05-31: binaire10
[Ruby] #2906 Fix SWIG wrappers for std::map and std::vector to
work with Ruby's "select".
2024-05-30: olly
#2914 Handle alternative operator names in C++ preprocessor
expressions. Handle full set of alternative operator names in
C++ expressions (previously only "and", "or" and "not" were
understood).
2024-05-15: olly
#2868 Support C++17 fold expressions.
2024-05-15: olly
#2876 Report error if parser stack depth exceeded. Previously SWIG
would quietly exit with status 0 in this situation.
2024-04-12: pfusik
[Javascript] #2869 Fix JavaScript _wrap_getCPtr on 64-bit Windows
2024-04-12: wsfulton
[Javascript, MzScheme, Python, Ruby] #202 Remove the vast majority of the
/*@SWIG:...*/ locator strings in the generated wrappers for these 4 languages
to help with reproducible builds.
2024-04-08: thewtex
[Python] #2856 Include stdlib.h for more recent Python Stable ABI
2024-03-28: olly
Fix preprocessor to handle C-style comment ending **/ in macro argument.
2024-03-27: wsfulton
[Python] #2844 Fix for using more than one std::string_view type in a method.
2024-03-27: wsfulton
[R] #2847 Add missing std::vector<long> and std::vector<long long> typemaps
which were missing depending on whether or not SWIGWORDSIZE64 was defined.
2024-03-25: wsfulton
[Python] #2826 Stricter stable ABI conformance.
1. Use Py_DecRef and Py_IncRef when Py_LIMITED_API is defined instead of
macro equivalents, such as Py_INCREF.
2. Don't use PyUnicode_GetLength from python-3.7 and later.
3. Use PyObject_Free instead of deprecated equivalents.
2024-03-25: olly
#2848 Fix elision of comma before ##__VA_ARGS__ which we document
as supported but seems to have not worked since before 2009.
2024-03-11: wsfulton
[C#] Improve handling and documentation of missing enum base type information.
[C#] #2829 Improve handling and documentation of missing enum base type
information.
2024-03-07: wsfulton
[Ocaml] Fix SWIGTYPE MOVE 'in' typemap to fix compilation error.

View File

@ -979,7 +979,7 @@ but do not use any additional mangling for normal enumerations. For example, in
</p>
<div class="targetlang"><pre>
print Color.RainbowColors_Red, Color.WarmColors_Red, Color.Red
print(Color.RainbowColors_Red, Color.WarmColors_Red, Color.Red)
</pre></div>
<p>

View File

@ -17,6 +17,7 @@
<li><a href="#CPlusPlus17_nested_namespaces">Nested namespace definitions</a>
<li><a href="#CPlusPlus17_u8_char_literals">UTF-8 character literals</a>
<li><a href="#CPlusPlus17_hexadecimal_floating_literals">Hexadecimal floating literals</a>
<li><a href="#CPlusPlus17_fold_expressions">Fold expressions</a>
</ul>
<li><a href="#CPlusPlus17_standard_library_changes">Standard library changes</a>
</ul>
@ -102,6 +103,16 @@ double f = 0xF.68p2;
</pre>
</div>
<H3><a name="CPlusPlus17_fold_expressions">9.2.4 Fold expressions</a></H3>
<p>
C++17 added template fold expressions. SWIG 4.3.0 and later support
parsing these with a few restrictions. Unary left fold expressions are
not supported currently. Also the same restrictions that apply to other
expressions apply here too.
</p>
<H2><a name="CPlusPlus17_standard_library_changes">9.3 Standard library changes</a></H2>

View File

@ -18,6 +18,10 @@
<li><a href="#CPlusPlus20_lambda_templates">Lambda templates</a>
<li><a href="#CPlusPlus20_constexpr_destructors">Constexpr destructors</a>
</ul>
<li><a href="#CPlusPlus20_preprocessor_changes">Preprocessor changes</a>
<ul>
<li><a href="#CPlusPlus20_va_opt">__VA_OPT__()</a>
</ul>
<li><a href="#CPlusPlus20_standard_library_changes">Standard library changes</a>
</ul>
</div>
@ -84,7 +88,18 @@ public:
</pre>
</div>
<H2><a name="CPlusPlus20_standard_library_changes">10.3 Standard library changes</a></H2>
<H2><a name="CPlusPlus20_preprocessor_changes">10.3 Preprocessor changes</a></H2>
<H3><a name="CPlusPlus20_va_opt">10.3.1 __VA_OPT__()</a></H3>
<p>
Support for <tt>__VA_OPT__()</tt> was added in SWIG 4.3.0.
</p>
<H2><a name="CPlusPlus20_standard_library_changes">10.4 Standard library changes</a></H2>
</body>

View File

@ -275,6 +275,11 @@
<li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
<ul>
<li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
<ul>
<li><a href="SWIGPlus.html#SWIGPlus_nspace_feature_flag">%nspace for mirroring namespace hierarchies</a>
<li><a href="SWIGPlus.html#SWIGPlus_nspacemove">%nspacemove for modifying namespace hierarchies</a>
<li><a href="SWIGPlus.html#SWIGPlus_nspace_more">More about the nspace feature</a>
</ul>
</ul>
<li><a href="SWIGPlus.html#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
<li><a href="SWIGPlus.html#SWIGPlus_exception_specifications">Exception specifications</a>
@ -383,6 +388,7 @@
<li><a href="CPlusPlus17.html#CPlusPlus17_nested_namespaces">Nested namespace definitions</a>
<li><a href="CPlusPlus17.html#CPlusPlus17_u8_char_literals">UTF-8 character literals</a>
<li><a href="CPlusPlus17.html#CPlusPlus17_hexadecimal_floating_literals">Hexadecimal floating literals</a>
<li><a href="CPlusPlus17.html#CPlusPlus17_fold_expressions">Fold expressions</a>
</ul>
<li><a href="CPlusPlus17.html#CPlusPlus17_standard_library_changes">Standard library changes</a>
</ul>
@ -401,6 +407,10 @@
<li><a href="CPlusPlus20.html#CPlusPlus20_lambda_templates">Lambda templates</a>
<li><a href="CPlusPlus20.html#CPlusPlus20_constexpr_destructors">Constexpr destructors</a>
</ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_preprocessor_changes">Preprocessor changes</a>
<ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_va_opt">__VA_OPT__()</a>
</ul>
<li><a href="CPlusPlus20.html#CPlusPlus20_standard_library_changes">Standard library changes</a>
</ul>
</div>
@ -416,7 +426,7 @@
<li><a href="Preprocessor.html#Preprocessor_condition_compilation">Conditional Compilation</a>
<li><a href="Preprocessor.html#Preprocessor_nn5">Macro Expansion</a>
<li><a href="Preprocessor.html#Preprocessor_nn6">SWIG Macros</a>
<li><a href="Preprocessor.html#Preprocessor_nn7">C99 and GNU Extensions</a>
<li><a href="Preprocessor.html#Preprocessor_nn7">Variadic Macros</a>
<li><a href="Preprocessor.html#Preprocessor_delimiters">Preprocessing and delimiters</a>
<ul>
<li><a href="Preprocessor.html#Preprocessor_nn8">Preprocessing and %{ ... %} &amp; " ... " delimiters</a>
@ -425,6 +435,8 @@
<li><a href="Preprocessor.html#Preprocessor_typemap_delimiters">Preprocessor and Typemaps</a>
<li><a href="Preprocessor.html#Preprocessor_nn10">Viewing preprocessor output</a>
<li><a href="Preprocessor.html#Preprocessor_warning_error">The #error and #warning directives</a>
<li><a href="Preprocessor.html#Preprocessor_trigraphs">Trigraphs</a>
<li><a href="Preprocessor.html#Preprocessor_digraphs">Digraphs</a>
</ul>
</div>
<!-- INDEX -->
@ -446,7 +458,7 @@
<li><a href="Library.html#Library_nn8">C string handling</a>
<ul>
<li><a href="Library.html#Library_nn9">Default string handling</a>
<li><a href="Library.html#Library_nn10">Passing binary data</a>
<li><a href="Library.html#Library_nn10">Passing a string with length</a>
<li><a href="Library.html#Library_nn11">Using %newobject to release memory</a>
<li><a href="Library.html#Library_nn12">cstring.i</a>
</ul>
@ -465,6 +477,10 @@
<li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
</ul>
<li><a href="Library.html#Library_std_unique_ptr">unique_ptr smart pointer</a>
<ul>
<li><a href="Library.html#Library_std_unique_ptr_by_value">unique_ptr passed by value</a>
<li><a href="Library.html#Library_std_unique_ptr_by_ref">unique_ptr passed by reference</a>
</ul>
<li><a href="Library.html#Library_std_auto_ptr">auto_ptr smart pointer</a>
</ul>
<li><a href="Library.html#Library_nn16">Utility Libraries</a>
@ -540,6 +556,10 @@
<li><a href="Typemaps.html#Typemaps_nn22">Scope</a>
<li><a href="Typemaps.html#Typemaps_nn23">Declaring new local variables</a>
<li><a href="Typemaps.html#Typemaps_special_variables">Special variables</a>
<ul>
<li><a href="Typemaps.html#Typemaps_type_special_variables">Type related special variables</a>
<li><a href="Typemaps.html#Typemaps_additional_special_variables">Non-type related special variables</a>
</ul>
<li><a href="Typemaps.html#Typemaps_special_variable_macros">Special variable macros</a>
<ul>
<li><a href="Typemaps.html#Typemaps_special_macro_descriptor">$descriptor(type)</a>
@ -1076,7 +1096,7 @@
<li><a href="Java.html#Java_simple_pointers">Simple pointers</a>
<li><a href="Java.html#Java_c_arrays">Wrapping C arrays with Java arrays</a>
<li><a href="Java.html#Java_unbounded_c_arrays">Unbounded C Arrays</a>
<li><a href="Java.html#Java_binary_char">Binary data vs Strings</a>
<li><a href="Java.html#Java_string_length">Passing a string with length</a>
<li><a href="Java.html#Java_heap_allocations">Overriding new and delete to allocate from Java heap</a>
</ul>
<li><a href="Java.html#Java_typemaps">Java typemaps</a>
@ -1451,7 +1471,6 @@
<li><a href="Python.html#Python_nn37">Overhead and code bloat</a>
<li><a href="Python.html#Python_nn38">Typemaps</a>
<li><a href="Python.html#Python_nn39">Miscellaneous</a>
<li><a href="Python.html#Python_stable_abi">Stable ABI</a>
</ul>
<li><a href="Python.html#Python_nn40">Common customization features</a>
<ul>
@ -1463,6 +1482,7 @@
<ul>
<li><a href="Python.html#Python_fastproxy">-fastproxy</a>
</ul>
<li><a href="Python.html#Python_stable_abi">Stable ABI</a>
</ul>
<li><a href="Python.html#Python_nn45">Tips and techniques</a>
<ul>

View File

@ -443,36 +443,32 @@ variables are replaced with.
<td>The actual operation to be performed (a function call, method invocation, variable access, etc.)</td>
</tr>
<tr>
<td>$decl</td>
<td>The fully qualified C/C++ declaration of the method being wrapped without the return type.</td>
</tr>
<tr>
<td>$fulldecl</td>
<td>The fully qualified C/C++ declaration of the method being wrapped including the return type.</td>
</tr>
<tr>
<td>$isvoid</td>
<td>Expands to 1 if the wrapped function has a void return, otherwise expands to 0.
Note that it expands to 1 in destructors and 0 in constructors.</td>
</tr>
<tr>
<td>$name</td>
<td>The C/C++ symbol name for the function.</td>
</tr>
<tr>
<td>$symname</td>
<td>The symbol name used internally by SWIG</td>
</tr>
<tr>
<td>$overname</td>
<td>The extra mangling used in the symbol name for overloaded method. Expands to nothing if the wrapped method is not overloaded.</td>
</tr>
<tr>
<td>$wrapname</td>
<td>The language specific wrapper name (usually a C function name exported from the shared object/dll)</td>
</tr>
<tr>
<td>$decl</td>
<td>The fully qualified C/C++ declaration of the method being wrapped without the return type</td>
</tr>
<tr>
<td>$fulldecl</td>
<td>The fully qualified C/C++ declaration of the method being wrapped including the return type</td>
</tr>
<tr>
<td>$parentclassname</td>
<td>The parent class name (if any) for a method.</td>
@ -483,6 +479,16 @@ variables are replaced with.
<td>The target language parent class name (if any) for a method.</td>
</tr>
<tr>
<td>$symname</td>
<td>The symbol name used internally by SWIG.</td>
</tr>
<tr>
<td>$wrapname</td>
<td>The language specific wrapper name (usually a C function name exported from the shared object/dll).</td>
</tr>
</table>
<p>

View File

@ -425,7 +425,11 @@ struct A {
<H3><a name="D_nspace">24.8.1 Extended namespace support (nspace)</a></H3>
<p>By default, SWIG flattens all C++ namespaces into a single target language namespace, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D. If it is active, C++ namespaces are mapped to D packages/modules. Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all allows written to the main proxy D module.</p>
<p>By default, SWIG flattens all C++ namespaces into a flattened D module hierarchy, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D.
If the feature is active, C++ namespaces are mapped to D packages/modules.
This includes the <tt>nspace</tt> feature flag for mirroring the C++ namespaces into D namespaces as a scoped D module/package name.
It also includes <tt>%nspacemove</tt> for transforming a C++ namespace into a completely different scoped D module/package name.
Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all available in the main proxy D module.</p>
<H3><a name="D_native_pointer_support">24.8.2 Native pointer support</a></H3>

View File

@ -114,7 +114,7 @@
<li><a href="#Java_simple_pointers">Simple pointers</a>
<li><a href="#Java_c_arrays">Wrapping C arrays with Java arrays</a>
<li><a href="#Java_unbounded_c_arrays">Unbounded C Arrays</a>
<li><a href="#Java_binary_char">Binary data vs Strings</a>
<li><a href="#Java_string_length">Passing a string with length</a>
<li><a href="#Java_heap_allocations">Overriding new and delete to allocate from Java heap</a>
</ul>
<li><a href="#Java_typemaps">Java typemaps</a>
@ -1929,7 +1929,7 @@ Each SWIG module can be placed into a separate package.
<p>
The default behaviour described above can be improved via the <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a>.
Note that it only works for classes, structs, unions and enums declared within a named C++ namespace.
When the nspace feature is used, the C++ namespaces are converted into Java packages of the same name.
When the nspace feature is used (either the <tt>nspace</tt> feature flag or <tt>%nspacemove</tt>), the C++ namespaces are converted into Java packages of the same name.
Proxy classes are thus declared within a package and this proxy makes numerous calls to the JNI intermediary class which is declared in the unnamed package by default.
As Java does not support types declared in a named package accessing types declared in an unnamed package, the <tt>-package</tt> commandline option described earlier generally should be used to provide a parent package.
So if SWIG is run using the <tt>-package com.myco</tt> option, a wrapped class, <tt>MyWorld::Material::Color</tt>, can then be accessed as <tt>com.myco.MyWorld.Material.Color</tt>.
@ -5512,12 +5512,12 @@ well suited for applications in which you need to create buffers,
package binary data, etc.
</p>
<H3><a name="Java_binary_char">27.8.5 Binary data vs Strings</a></H3>
<H3><a name="Java_string_length">27.8.5 Passing a string with length</a></H3>
<p>
By default SWIG handles <tt>char *</tt> as a string but there is a handy multi-argument typemap available as mentioned in <a href="Library.html#Library_nn10">Passing binary data</a>.
The following simple example demonstrates using a byte array instead of passing the default string type and length to the wrapped function.
SWIG provides multi-argument typemap available as mentioned in <a href="Library.html#Library_nn10">Passing a string with length</a>.
The following simple example demonstrates passing a string to the wrapped function.
</p>
@ -5536,13 +5536,13 @@ void binaryChar1(const char data[], size_t len) {
</div>
<p>
Calling from Java requires just the byte array to be passed in as the multi-argument typemap being applied reduces the number of arguments in the target language to one, from the original two:
Calling from Java requires a string to be passed in as the multi-argument typemap being applied reduces the number of arguments in the target language to one, from the original two:
</p>
<div class="code">
<pre>
byte[] data = "hi\0jk".getBytes();
example.binaryChar1(data);
String str = "hi\0jk";
example.binaryChar1(str);
</pre>
</div>
@ -5555,6 +5555,15 @@ $ java runme
len: 5 data: 68 69 0 6a 6b
</pre></div>
<p>
The typemap uses Java <tt>String::getBytes()</tt> to convert the string to the default system encoding. If you wish to use another encoding, you can modify the typemap. For example to convert the string to UTF-8 use:
</p>
<div class="code"><pre>
%typemap(javain, throws="java.io.IllegalCharsetNameException")<br>
(const char *STRING, size_t LENGTH) %{($javainput == null) ? null : $javainput.getBytes("UTF-8")%}
</pre></div>
<H3><a name="Java_heap_allocations">27.8.6 Overriding new and delete to allocate from Java heap</a></H3>

View File

@ -98,6 +98,7 @@ uses V8 5.0, v12.0 - 7.4, v14.0 - 8.1...</p>
This Node-API is available starting from Node.js v10.20 on the v10.x branch,
Node.js v12.17 on the v12.x branch and all versions starting from v14.0.
</p>
<p>The oldest Node version we regularly test with is Node 12.</p>
<p>To generate code for V8, you would run swig like so:</p>
<div class="shell">
<pre>

View File

@ -23,7 +23,7 @@
<li><a href="#Library_nn8">C string handling</a>
<ul>
<li><a href="#Library_nn9">Default string handling</a>
<li><a href="#Library_nn10">Passing binary data</a>
<li><a href="#Library_nn10">Passing a string with length</a>
<li><a href="#Library_nn11">Using %newobject to release memory</a>
<li><a href="#Library_nn12">cstring.i</a>
</ul>
@ -42,6 +42,10 @@
<li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
</ul>
<li><a href="#Library_std_unique_ptr">unique_ptr smart pointer</a>
<ul>
<li><a href="#Library_std_unique_ptr_by_value">unique_ptr passed by value</a>
<li><a href="#Library_std_unique_ptr_by_ref">unique_ptr passed by reference</a>
</ul>
<li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a>
</ul>
<li><a href="#Library_nn16">Utility Libraries</a>
@ -719,11 +723,22 @@ Now, in a script:
<p>
The <tt>cdata.i</tt> module defines functions for converting raw C data to and from strings
in the target language. The primary applications of this module would be packing/unpacking of
The <tt>cdata.i</tt> module defines functions for converting raw C data to and from a target language type.
The target language type is either:
</p>
<ul>
<li> A string for the scripting languages. The scripting language must support strings with embedded binary data in order for this to work.</li>
<li> A byte array for the statically typed languages; namely, <tt>byte[]</tt> for C# and Java, <tt>ubyte[]</tt> for D, <tt>[]byte</tt> for Go.</li>
</ul>
<p>
The primary applications of this module would be packing/unpacking of
binary data structures---for instance, if you needed to extract data from a buffer.
The target language must support strings with embedded binary data
in order for this to work.
</p>
<p>
The available APIs are:
</p>
<p>
@ -731,7 +746,7 @@ in order for this to work.
</p>
<div class="indent"><p>
Converts <tt>nbytes</tt> of data at <tt>ptr</tt> into a string. <tt>ptr</tt> can be any
Converts <tt>nbytes</tt> of data at <tt>ptr</tt> into the target language type. <tt>ptr</tt> can be any
pointer.
</p></div>
@ -740,13 +755,13 @@ pointer.
</p>
<div class="indent"><p>
Copies all of the string data in <tt>s</tt> into the memory pointed to by
<tt>ptr</tt>. The string may contain embedded NULL bytes.
This is actually a wrapper to the standard C library <tt>memmove</tt> function, which is
declared as
<b><tt>void memmove(void *ptr, const void *src, size_t n)</tt></b>.
The <tt>src</tt> and length <tt>n</tt> parameters are
extracted from the language specific string <tt>s</tt> in the underlying wrapper code.
This is actually a wrapper of the standard C library <tt>memmove</tt> function,
<b><tt>void *memmove(void *ptr, const void *src, size_t n)</tt></b>,
which copies <tt>n</tt> bytes of data from <tt>src</tt> into the destination pointed to by <tt>ptr</tt>.
Multi-argument typemaps are used so that the last two parameters, <tt>src</tt> and <tt>n</tt> are replaced by
<tt>s</tt>, a string or byte array target language type, mentioned earlier.
The string/byte array may contain embedded NULL bytes.
Unlike the C library function nothing is returned by the wrapper function.
</p></div>
<p>
@ -878,11 +893,11 @@ interpreter and lead to a crash). Furthermore, the default behavior does
not work well with binary data. Instead, strings are assumed to be NULL-terminated.
</p>
<H3><a name="Library_nn10">12.3.2 Passing binary data</a></H3>
<H3><a name="Library_nn10">12.3.2 Passing a string with length</a></H3>
<p>
If you have a function that expects binary data,
If you have a function that expects string with a length,
</p>
<div class="code">
@ -905,7 +920,7 @@ size_t parity(char *str, size_t len, size_t initial);
</div>
<p>
Now, in the target language, you can use binary string data like this:
Now, in the target language, you can use the string like this:
</p>
<div class="targetlang">
@ -2107,7 +2122,8 @@ The ownership and move semantics described here can of course be modified if not
by copying and customising the typemaps in the appropriate <tt>std_unique_ptr.i</tt> library file.
</p>
<H4><a name="Library_std_unique_ptr_by_value">12.4.6 unique_ptr passed by value</a></H4>
<H4><a name="Library_std_unique_ptr_by_value">12.4.6.1 unique_ptr passed by value</a></H4>
<p>
Example usage of a <tt>std::unique_ptr</tt> being returned from a function by value is shown below.
@ -2214,7 +2230,8 @@ Attempts to pass ownership from a proxy class to a <tt>std::unique</tt> paramete
in a "Cannot release ownership as memory is not owned" exception. For example, if <tt>example.take(k)</tt> in the example above is called twice.
</p>
<H4><a name="Library_std_unique_ptr_by_ref">12.4.6 unique_ptr passed by reference</a></H4>
<H4><a name="Library_std_unique_ptr_by_ref">12.4.6.2 unique_ptr passed by reference</a></H4>
<p>
The effect of passing a <tt>std::unique_ptr</tt> by rvalue reference into a function is identical to passing it by value.

View File

@ -1377,13 +1377,15 @@ add exception specification to functions or globally (respectively).
<p>
Since SWIG-3.0.0 C++ namespaces are supported via the %nspace feature.
C++ namespaces are supported via the %nspace feature.
</p>
<p> Namespaces are mapped into Lua tables. Each of those tables contains names that were defined within appropriate namespace. Namespaces structure (a.k.a nested namespaces) is preserved. Consider the following C++ code:
<p> Namespaces are mapped into Lua tables. Each of those tables contains names that were defined within an appropriate namespace. Namespace hierarchies (a.k.a nested namespaces) are preserved. Consider the following C++ code:
</p>
<div class="code"><pre>%module example
%nspace MyWorld::Nested::Dweller;
<div class="code"><pre>
%module example
%nspace MyWorld::World;
%nspace MyWorld::Nested::Dweller;
int module_function() { return 7; }
int module_variable = 9;
@ -1411,34 +1413,69 @@ Now, from Lua usage is as follows:
<div class="targetlang"><pre>
&gt; print(example.module_function())
7
7.0
&gt; print(example.module_variable)
9
9.0
&gt; print(example.MyWorld.World():create_world())
17
&gt; print(example.MyWorld.World.world_max_count)
9
17.0
&gt; print(example.MyWorld.World().world_max_count)
9.0
&gt; print(example.MyWorld.Nested.Dweller.MALE)
0
&gt; print(example.MyWorld.Nested.Dweller.count())
19
&gt;
19.0
</pre></div>
<p>
The hierarchies in Lua are the same as the C++ hierarchies when using <tt>%nspace</tt>,
however, we could instead completely change these hierarchies with <tt>%nspacemove</tt>.
Consider the code above with the two <tt>%nspace</tt> lines of code removed and replaced with the following:
</p>
<div class="code"><pre>
%nspacemove(DifferentWorld::SubSpace1::SubSpace2) MyWorld::World;
%nspacemove(DifferentWorld) MyWorld::Nested::Dweller;
</pre></div>
<p>
The Lua code uses the completely modified hierarchies:
</p>
<div class="targetlang"><pre>
&gt; print(example.module_function())
7.0
&gt; print(example.module_variable)
9.0
&gt; print(example.DifferentWorld.SubSpace1.SubSpace2.World():create_world())
17.0
&gt; print(example.DifferentWorld.SubSpace1.SubSpace2.World().world_max_count)
9.0
&gt; print(example.DifferentWorld.Dweller.MALE)
0
&gt; print(example.DifferentWorld.Dweller.count())
19.0
</pre></div>
<H4><a name="Lua_nn27">29.3.17.1 Compatibility Note </a></H4>
<p>
The nspace feature was first supported by the Lua module in SWIG-3.0.0
</p>
<p>
If SWIG is running in a backwards compatible way, i.e. without the <tt>-no-old-metatable-bindings</tt> option, then additional old-style names are generated (notice the underscore):
</p>
<div class="targetlang"><pre>
9
&gt; print(example.MyWorld.Nested.Dweller_MALE)
0
&gt; print(example.MyWorld.Nested.Dweller_count())
11
&gt;
19.0
</pre></div>
<p>
The ability to move symbols into different namespaces via <tt>%nspacemove</tt> was introduced in SWIG-4.3.0.
</p>
<H4><a name="Lua_nn29">29.3.17.2 Names </a></H4>

View File

@ -257,6 +257,7 @@ option is not needed when you build native code.
<H3><a name="Ocaml_nn7">39.1.5 Compilation problems and compiling with C++</a></H3>
<p>
Ocaml's C extension API unfortunately defines a <tt>value</tt> typedef - this
overly-generic name can collide with the C or C++ API being wrapped if it

View File

@ -16,7 +16,7 @@
<li><a href="#Preprocessor_condition_compilation">Conditional Compilation</a>
<li><a href="#Preprocessor_nn5">Macro Expansion</a>
<li><a href="#Preprocessor_nn6">SWIG Macros</a>
<li><a href="#Preprocessor_nn7">C99 and GNU Extensions</a>
<li><a href="#Preprocessor_nn7">Variadic Macros</a>
<li><a href="#Preprocessor_delimiters">Preprocessing and delimiters</a>
<ul>
<li><a href="#Preprocessor_nn8">Preprocessing and %{ ... %} &amp; " ... " delimiters</a>
@ -25,6 +25,8 @@
<li><a href="#Preprocessor_typemap_delimiters">Preprocessor and Typemaps</a>
<li><a href="#Preprocessor_nn10">Viewing preprocessor output</a>
<li><a href="#Preprocessor_warning_error">The #error and #warning directives</a>
<li><a href="#Preprocessor_trigraphs">Trigraphs</a>
<li><a href="#Preprocessor_digraphs">Digraphs</a>
</ul>
</div>
<!-- INDEX -->
@ -322,11 +324,12 @@ many of SWIG's advanced features and libraries are built using this mechanism (s
support).
</p>
<H2><a name="Preprocessor_nn7">11.6 C99 and GNU Extensions</a></H2>
<H2><a name="Preprocessor_nn7">11.6 Variadic Macros</a></H2>
<p>
SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example:
SWIG-1.3.12 and newer releases support variadic preprocessor macros which were
standardised by C99 and C++11. For example:
</p>
<div class="code">
@ -342,8 +345,9 @@ macros defined using <tt>%define</tt>.
</p>
<p>
SWIG allows a variable number of arguments to be empty. However, this often results
in an extra comma (, ) and syntax error in the resulting expansion. For example:
The variable arguments can be empty. However, this often results
in an extra comma (<tt>,</tt>) and syntax error in the resulting expansion. For
example:
</p>
<div class="code">
@ -353,7 +357,25 @@ DEBUGF("hello"); --&gt; fprintf(stderr, "hello", );
</div>
<p>
To get rid of the extra comma, use <tt>##</tt> like this:
C++20 and C23 added <tt>__VA_OPT__()</tt> as a solution to this, which SWIG
4.3.0 added support for. <tt>__VA_OPT__()</tt> expands to its argument if the
variable arguments contain any tokens, and to nothing otherwise. It can be
used to solve the problem above like so:
</p>
<div class="code">
<pre>
#define DEBUGF(fmt, ...) fprintf(stderr, fmt __VA_OPT__(,) __VA_ARGS__)
</pre>
</div>
<p>
An early non-standardised solution to this problem which gave a special
meaning to the token sequence <tt>, ## __VA_ARGS__</tt> is supported by
several C and C++ compilers, and also by SWIG 4.3.0 and later (it was
documented as supported by earlier SWIG versions, but didn't actually work in
at least SWIG 2.x and 3.x). Using this feature you can get rid of the extra
comma like this:
</p>
<div class="code">
@ -363,7 +385,8 @@ To get rid of the extra comma, use <tt>##</tt> like this:
</div>
<p>
SWIG also supports GNU-style variadic macros. For example:
SWIG also supports GNU-style variadic macros, which specify a name for the
variable arguments instead of using <tt>__VA_ARGS__</tt>. For example:
</p>
<div class="code">
@ -373,11 +396,12 @@ SWIG also supports GNU-style variadic macros. For example:
</div>
<p>
<b>Comment:</b> It's not entirely clear how variadic macros might be useful to
interface building. However, they are used internally to implement a number of
SWIG directives and are provided to make SWIG more compatible with C99 code.
SWIG supports <tt>__VA_OPT__()</tt> in combination with GNU-style variadic
macros (following the lead of GCC and clang which also support this, albeit
with a warning by default).
</p>
<H2><a name="Preprocessor_delimiters">11.7 Preprocessing and delimiters</a></H2>
@ -537,8 +561,10 @@ This might be useful as an aid to debugging and viewing the results of macro exp
<p>
SWIG supports the commonly used <tt>#warning</tt> and <tt>#error</tt> preprocessor directives.
SWIG supports the standard <tt>#warning</tt> and <tt>#error</tt> preprocessor directives.
The <tt>#warning</tt> directive will cause SWIG to issue a warning then continue processing.
It was standardised in C++23 and C23, and has been widely supported as an extension by
most C and C++ compilers for a long time.
The <tt>#error</tt> directive will cause SWIG to exit with a fatal error.
Example usage:
</p>
@ -564,5 +590,29 @@ commandline option is used. Alternatively, the <tt>#pragma</tt> directive can be
</pre>
</div>
<H2><a name="Preprocessor_trigraphs">11.11 Trigraphs</a></H2>
<p>
SWIG's preprocessor does not implement trigraphs (such as <tt>??!</tt> being
mapped to <tt>|</tt>). They are very rarely used deliberately but these
character sequences sometimes occur in code where they aren't intended as
trigraphs. Compilers typically don't enable trigraph support by default, and
they've been removed in C++17 and C23.
</p>
<H2><a name="Preprocessor_digraphs">11.12 Digraphs</a></H2>
<p>
SWIG's preprocessor does not currently implement digraphs (such as
<tt>&lt;%</tt> being an alternative way to write the token <tt>{</tt>).
These are standard in C++ and C95, but they're intended to support working with
code on systems with very restricted character sets which are really rare
these days so digraphs just don't seem to be used in practice.
</p>
</body>
</html>

View File

@ -65,7 +65,6 @@
<li><a href="#Python_nn37">Overhead and code bloat</a>
<li><a href="#Python_nn38">Typemaps</a>
<li><a href="#Python_nn39">Miscellaneous</a>
<li><a href="#Python_stable_abi">Stable ABI</a>
</ul>
<li><a href="#Python_nn40">Common customization features</a>
<ul>
@ -77,6 +76,7 @@
<ul>
<li><a href="#Python_fastproxy">-fastproxy</a>
</ul>
<li><a href="#Python_stable_abi">Stable ABI</a>
</ul>
<li><a href="#Python_nn45">Tips and techniques</a>
<ul>
@ -157,7 +157,8 @@
<p>
This chapter describes SWIG's support of Python. SWIG is compatible
with all recent Python versions (Python 2.7 and Python &gt;= 3.3). SWIG 4.0.x
with all recent Python versions (Python 2.7 and Python &gt;= 3.3), though
the oldest Python 3 version we regularly test with is Python 3.5. SWIG 4.0.x
supported Python 3.2. SWIG 3.0.x supported older Python 2.x and 3.x.
</p>
@ -888,7 +889,7 @@ and use the <tt>import</tt> command as normal. For example :
<div class="targetlang"><pre>
$ python
&gt;&gt;&gt; import example
&gt;&gt;&gt; print example.fact(4)
&gt;&gt;&gt; print(example.fact(4))
24
&gt;&gt;&gt;
</pre></div>
@ -1015,7 +1016,7 @@ like you think it does:
<div class="targetlang"><pre>
&gt;&gt;&gt; import example
&gt;&gt;&gt; print example.fact(4)
&gt;&gt;&gt; print(example.fact(4))
24
&gt;&gt;&gt;
</pre></div>
@ -1075,7 +1076,7 @@ Now look at the Python interface:
<div class="targetlang"><pre>
&gt;&gt;&gt; import example
&gt;&gt;&gt; # Print out value of a C global variable
&gt;&gt;&gt; print example.cvar.My_variable
&gt;&gt;&gt; print(example.cvar.My_variable)
4
&gt;&gt;&gt; # Set the value of a C global variable
&gt;&gt;&gt; example.cvar.density = 0.8442
@ -1237,7 +1238,7 @@ simply represented as opaque values using an especial Python container object:
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; print f
&gt;&gt;&gt; print(f)
&lt;Swig Object of type 'FILE *' at 0xb7d6f470&gt;
</pre></div>
@ -1255,7 +1256,7 @@ always retrieve it by casting the pointer object to a string:
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; print str(f)
&gt;&gt;&gt; print(str(f))
_c0671108_p_FILE
</pre></div>
@ -1266,7 +1267,7 @@ integer:
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; print int(f)
&gt;&gt;&gt; print(int(f))
135833352
</pre></div>
@ -1362,7 +1363,7 @@ is used as follows:
&gt;&gt;&gt; v = example.Vector()
&gt;&gt;&gt; v.x = 3.5
&gt;&gt;&gt; v.y = 7.2
&gt;&gt;&gt; print v.x, v.y, v.z
&gt;&gt;&gt; print(v.x, v.y, v.z)
3.5 7.2 0.0
&gt;&gt;&gt;
</pre></div>
@ -1378,7 +1379,7 @@ something like this:
<div class="targetlang">
<pre>
&gt;&gt;&gt; print v
&gt;&gt;&gt; print(v)
&lt;C Vector instance at _18e31408_p_Vector&gt;
</pre>
</div>
@ -1392,7 +1393,7 @@ attribute. For example:
<div class="targetlang">
<pre>
&gt;&gt;&gt; print v.this
&gt;&gt;&gt; print(v.this)
_18e31408_p_Vector
&gt;&gt;&gt;
</pre>
@ -1448,7 +1449,7 @@ If accessed in Python, you will see behavior like this:
<div class="targetlang">
<pre>
&gt;&gt;&gt; b = example.Bar()
&gt;&gt;&gt; print b.x
&gt;&gt;&gt; print(b.x)
_801861a4_p_int
&gt;&gt;&gt;
</pre>
@ -1580,7 +1581,7 @@ you can use it in Python like this:
&gt;&gt;&gt; l.insert("Lager")
&gt;&gt;&gt; l.get(1)
'Stout'
&gt;&gt;&gt; print l.length
&gt;&gt;&gt; print(l.length)
3
&gt;&gt;&gt;
</pre></div>
@ -2022,7 +2023,7 @@ it works in Python as follows:
6
&gt;&gt;&gt; v = example.Vector()
&gt;&gt;&gt; v.x = 3.4
&gt;&gt;&gt; print v.y
&gt;&gt;&gt; print(v.y)
0.0
&gt;&gt;&gt;
</pre>
@ -2766,7 +2767,7 @@ public:
<pre>
&gt;&gt;&gt; f = Foo()
&gt;&gt;&gt; s = f.spam()
&gt;&gt;&gt; print s.thisown
&gt;&gt;&gt; print(s.thisown)
0
&gt;&gt;&gt;
</pre>
@ -3016,7 +3017,7 @@ class MyFoo(mymodule.Foo):
# super().__init__(foo) # Alternative construction for Python3
def one(self):
print "one from Python"
print("one from Python")
</pre>
</div>
@ -3319,41 +3320,6 @@ director feature for reentrant, recursive or threaded member
methods that return const references.
</p>
<H3><a name="Python_stable_abi">33.5.8 Stable ABI</a></H3>
<p>
By default, the version of Python used to compile the wrappers needs to be the same as that used during runtime.
Alternatvely, the <a href="https://docs.python.org/3/c-api/stable.html">Python Stable ABI</a> enables a single compiled binary to be used by different versions of Python.
This is enabled by defining <tt>Py_LIMITED_API</tt> during the compilation of the C/C++ wrapper code and setting this macro to a particular minimum version of Python that one wants to support.
</p>
<p>
SWIG supports the stable ABI, but only version 3.4 of Python and later is supported.
There are two recommended approaches for using SWIG and the stable ABI and both require setting the <tt>Py_LIMITED_API</tt> macro to be set to <tt>0x03040000</tt> as a minimum value (Python 3.4).
Either set this using <tt>%begin</tt> by adding the following into your interface file so that this macro appears at the beginning of the generated C/C++ code:
</p>
<div class="code"><pre>
%begin %{
#define Py_LIMITED_API 0x03040000
%}
</pre></div>
<p>
or simply define the macro using your C/C++ compiler's <tt>-D</tt> command line option, for example, <tt>-DPy_LIMITED_API=0x03040000</tt>.
</p>
<p>
The default SWIG command line options generate code that enable the limited API/stable ABI.
Some options, such as <tt>-builtin</tt>, <tt>-fast</tt> (used by <tt>-O</tt>) do not use the limited API and hence when <tt>Py_LIMITED_API</tt> is defined there will be missing symbols during compilation.
Compatibility of user's custom typemaps is of course dependent on the Python APIs used in the typemaps.
</p>
<p>
<b>Compatibility Note:</b> Support for the stable ABI was added in SWIG-4.2.0.
</p>
<H2><a name="Python_nn40">33.6 Common customization features</a></H2>
@ -3755,7 +3721,7 @@ Now, in Python
<div class="targetlang">
<pre>
&gt;&gt;&gt; v = example.Vector(2, 3, 4)
&gt;&gt;&gt; print v
&gt;&gt;&gt; print(v)
Vector(2, 3, 4)
&gt;&gt;&gt;
</pre>
@ -3789,7 +3755,7 @@ Use it like this:
&gt;&gt;&gt; import example
&gt;&gt;&gt; v = example.Vector(2, 3, 4)
&gt;&gt;&gt; w = example.Vector(10, 11, 12)
&gt;&gt;&gt; print v+w
&gt;&gt;&gt; print(v+w)
Vector(12, 14, 16)
&gt;&gt;&gt;
</pre>
@ -4070,6 +4036,93 @@ While this possibly provides the best of both worlds, the time to import the mod
The command line options mentioned above also apply to wrapped C/C++ global functions, not just class methods.
</p>
<H3><a name="Python_stable_abi">33.6.6 Stable ABI</a></H3>
<p>
By default, the version of Python used to compile the wrappers needs to be the same as that used during runtime.
Alternatvely, the <a href="https://docs.python.org/3/c-api/stable.html">Python Stable ABI</a> enables a single compiled binary to be used by different versions of Python.
This is enabled by defining <tt>Py_LIMITED_API</tt> during the compilation of the C/C++ wrapper code and setting this macro to a particular minimum version of Python that one wants to support.
</p>
<p>
SWIG supports the stable ABI, but only version 3.4 of Python and later is supported.
There are two recommended approaches for using SWIG and the stable ABI and both require setting the <tt>Py_LIMITED_API</tt> macro to be set to <tt>0x03040000</tt> as a minimum value (Python 3.4).
Either set this using <tt>%begin</tt> by adding the following into your interface file so that this macro appears at the beginning of the generated C/C++ code:
</p>
<div class="code"><pre>
%begin %{
#define Py_LIMITED_API 0x03040000
%}
</pre></div>
<p>
or simply define the macro using your C/C++ compiler's <tt>-D</tt> command line option, for example, <tt>-DPy_LIMITED_API=0x03040000</tt>.
</p>
<p>
The default SWIG command line options generate code that enable the limited API/stable ABI.
Some options, such as <tt>-builtin</tt>, <tt>-fast</tt> (used by <tt>-O</tt>) do not use the limited API and hence when <tt>Py_LIMITED_API</tt> is defined there will be missing symbols during compilation.
Compatibility of user's custom typemaps is of course dependent on the Python APIs used in the typemaps.
</p>
<p>
As discussed in the official <a href="https://docs.python.org/3/c-api/stable.html">Python Stable ABI</a> documentation, there is no guarantee that code conforms to the Limited API or Stable ABI when defining <tt>Py_LIMITED_API</tt>.
There are a number of recommendations and caveats detailed there which are worth studying.
The Stable ABI is also evolving and being modified with each Python release.
In fact there is a Python C API working group, <a href="https://github.com/capi-workgroup/">capi-workgroup</a>, which was setup in the first half of 2023.
The <a href="https://github.com/capi-workgroup/problems/issues">capi-workgroup/problems issues</a> is very enlightening reading for anyone using the Stable ABI.
<a href="https://peps.python.org/pep-0733/">PEP 733</a> came out of the working group and is an evaluation of Python's C API.
</p>
<p>
There is a lot of information to digest in this space, but a simple approach would be to follow the offical recommendation of testing an extension with all minor Python versions you want to support,
and to build with the lowest supported version.
SWIG supports at least Python 3.4 for the Stable ABI so this would be a good version to compile a SWIG extension against.
There is also a useful tool <a href="https://github.com/trailofbits/abi3audit/">abi3audit</a> which can be used to check the compiled extension for Stable ABI conformance.
It can be easily installed with pip and then used to check a SWIG generated shared object or wheel even.
Note that if you are using it to check a shared object, the shared object must be renamed to have abi3 in the name.
For example, below is the output on Linux for the class example shipped with SWIG, if <tt>Py_LIMITED_API</tt> is set as described earlier:
</p>
<div class="shell">
<pre>
~/swig/Examples/python/class $ mv _example.so _example.abi3.so
~/swig/Examples/python/class $ abi3audit --assume-minimum-abi3 3.4 _example.abi3.so
[22:12:18] WARNING no wheel to infer abi3 version from; assuming (3.4)
[22:12:18] _example.abi3.so: 1 extensions scanned; 0 ABI version mismatches and 0 ABI violations found
</pre>
</div>
<p>
If <tt>Py_LIMITED_API</tt> is not set, the check fails, but this should be expected:
</p>
<div class="shell">
<pre>
~/swig/Examples/python/class $ mv _example.so _example.abi3.so
~/swig/Examples/python/class $ abi3audit --report --assume-minimum-abi3 3.4 _example.abi3.so
[22:22:27] WARNING no wheel to infer abi3 version from; assuming (3.4)
[22:22:27] _example.abi3.so: 1 extensions scanned; 1 ABI version mismatches and 0 ABI violations found
{"specs": {"_example.abi3.so": {"kind": "object", "object": {"name": "_example.abi3.so",
"result": {"is_abi3": true, "is_abi3_baseline_compatible": false, "baseline": "3.4", "computed": "3.10",
"non_abi3_symbols": [], "future_abi3_objects": {"PyUnicode_AsUTF8AndSize": "3.10"}}}}}}
</pre>
</div>
<p>
Note that ABI conformance as measured by <tt>abi3audit</tt> is far from simple and can depend on function inlining.
There are functions in Python.h, which if inlined, become ABI compliant.
Your chances of your C or C++ compiler inlining functions is greater with higher compiler optimisation levels.
So merely by changing your compiler optimisation level may switch your Python extension from being identified as ABI compliant or not.
</p>
<p>
<b>Compatibility Note:</b> Support for the stable ABI was added in SWIG-4.2.0.
</p>
<H2><a name="Python_nn45">33.7 Tips and techniques</a></H2>
@ -4129,10 +4182,10 @@ In Python, this allows you to pass simple values. For example:
<div class="targetlang">
<pre>
&gt;&gt;&gt; a = add(3, 4)
&gt;&gt;&gt; print a
&gt;&gt;&gt; print(a)
7
&gt;&gt;&gt; b = sub(7, 4)
&gt;&gt;&gt; print b
&gt;&gt;&gt; print(b)
3
&gt;&gt;&gt;
</pre>
@ -4192,7 +4245,7 @@ In Python, a mutated parameter shows up as a return value. For example:
<div class="targetlang">
<pre>
&gt;&gt;&gt; a = negate(3)
&gt;&gt;&gt; print a
&gt;&gt;&gt; print(a)
-3
&gt;&gt;&gt;
</pre>
@ -4238,9 +4291,9 @@ When used in Python, the function will return multiple values.
<pre>
bytes, success = send_message("Hello World")
if not success:
print "Whoa!"
print("Whoa!")
else:
print "Sent", bytes
print("Sent", bytes)
</pre>
</div>
@ -4336,10 +4389,10 @@ In Python, you would use the functions like this:
<div class="targetlang">
<pre>
&gt;&gt;&gt; result = new_intp()
&gt;&gt;&gt; print result
&gt;&gt;&gt; print(result)
_108fea8_p_int
&gt;&gt;&gt; add(3, 4, result)
&gt;&gt;&gt; print intp_value(result)
&gt;&gt;&gt; print(intp_value(result))
7
&gt;&gt;&gt;
</pre>
@ -4353,7 +4406,7 @@ If you replace <tt>%pointer_functions()</tt> by <tt>%pointer_class(type, name)</
<pre>
&gt;&gt;&gt; result = intp()
&gt;&gt;&gt; add(3, 4, result)
&gt;&gt;&gt; print result.value()
&gt;&gt;&gt; print(result.value())
7
</pre>
</div>
@ -4471,9 +4524,9 @@ just such a typemap is already defined. Just do this:
<div class="code">
<pre>
%apply (char *STRING, int LENGTH) { (char *data, int size) };
%apply (char *STRING, size_t LENGTH) { (char *data, size_t size) };
...
int parity(char *data, int size, int initial);
int parity(char *data, size_t size, int initial);
</pre>
</div>
@ -5149,8 +5202,8 @@ A typemap can be used to handle this case as follows :
PyTuple_SetItem(o3, 0, o);
o2 = $result;
$result = PySequence_Concat(o2, o3);
Py_DECREF(o2);
Py_DECREF(o3);
Py_DecRef(o2);
Py_DecRef(o3);
}
}
@ -5187,7 +5240,7 @@ function can now be used as follows:
<div class="targetlang"><pre>
&gt;&gt;&gt; a = spam(4, 5)
&gt;&gt;&gt; print a
&gt;&gt;&gt; print(a)
(0, 2.45, 5.0)
&gt;&gt;&gt; x, y, z = spam(4, 5)
&gt;&gt;&gt;
@ -5265,12 +5318,12 @@ arrays of different sizes. To do this, you might write a typemap as follows:
for (i =0; i &lt; $1_dim0; i++) {
PyObject *o = PySequence_GetItem($input, i);
if (!PyFloat_Check(o)) {
Py_XDECREF(o);
Py_DecRef(o);
PyErr_SetString(PyExc_ValueError, "Expecting a sequence of floats");
SWIG_fail;
}
temp[i] = PyFloat_AsDouble(o);
Py_DECREF(o);
Py_DecRef(o);
}
$1 = &amp;temp[0];
}
@ -5311,12 +5364,12 @@ static int convert_darray(PyObject *input, double *ptr, int size) {
for (i =0; i &lt; size; i++) {
PyObject *o = PySequence_GetItem(input, i);
if (!PyFloat_Check(o)) {
Py_XDECREF(o);
Py_DecRef(o);
PyErr_SetString(PyExc_ValueError, "Expecting a sequence of floats");
return 0;
}
ptr[i] = PyFloat_AsDouble(o);
Py_DECREF(o);
Py_DecRef(o);
}
return 1;
}
@ -6602,9 +6655,9 @@ example:
<pre>
%define MODULEIMPORT
"
print 'Loading low-level module $module'
print('Loading low-level module $module')
import $module
print 'Module has loaded'
print('Module has loaded')
"
%enddef
@ -6618,9 +6671,9 @@ This will of course generate the following into the pure Python module:
<div class="targetlang">
<pre>
print 'Loading low-level module $module'
print('Loading low-level module $module')
import _foo
print 'Module has loaded'
print('Module has loaded')
</pre>
</div>

View File

@ -732,7 +732,7 @@ puts $foo ;# Print the value of foo
# Python
cvar.foo = 3.5 # Set foo to 3.5
print cvar.foo # Print value of foo
print(cvar.foo) # Print value of foo
# Perl
$foo = 3.5; # Set foo to 3.5
@ -1383,7 +1383,7 @@ Vector *wrap_cross_product(Vector *v1, Vector *v2) {
Vector y = *v2;
Vector *result;
result = (Vector *) malloc(sizeof(Vector));
*(result) = cross(x, y);
*(result) = cross_product(x, y);
return result;
}
</pre></div>
@ -1392,10 +1392,10 @@ Vector *wrap_cross_product(Vector *v1, Vector *v2) {
or if SWIG was run with the <tt>-c++</tt> option:</p>
<div class="code"><pre>
Vector *wrap_cross(Vector *v1, Vector *v2) {
Vector *wrap_cross_product(Vector *v1, Vector *v2) {
Vector x = *v1;
Vector y = *v2;
Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
Vector *result = new Vector(cross_product(x, y)); // Uses default copy constructor
return result;
}
</pre></div>
@ -3007,7 +3007,7 @@ this :</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; v = Vector(3, 4, 0) # Create a new vector
&gt;&gt;&gt; print v.magnitude() # Print magnitude
&gt;&gt;&gt; print(v.magnitude()) # Print magnitude
5.0
&gt;&gt;&gt; v.print() # Print it out
[ 3, 4, 0 ]

View File

@ -72,6 +72,11 @@
<li><a href="#SWIGPlus_namespaces">Namespaces</a>
<ul>
<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
<ul>
<li><a href="#SWIGPlus_nspace_feature_flag">%nspace for mirroring namespace hierarchies</a>
<li><a href="#SWIGPlus_nspacemove">%nspacemove for modifying namespace hierarchies</a>
<li><a href="#SWIGPlus_nspace_more">More about the nspace feature</a>
</ul>
</ul>
<li><a href="#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
<li><a href="#SWIGPlus_exception_specifications">Exception specifications</a>
@ -1660,14 +1665,14 @@ $ python
&gt;&gt;&gt; import shapes
&gt;&gt;&gt; circle = shapes.new_Circle(7)
&gt;&gt;&gt; square = shapes.new_Square(10)
&gt;&gt;&gt; print shapes.Circle_area(circle)
&gt;&gt;&gt; print(shapes.Circle_area(circle))
153.93804004599999757
&gt;&gt;&gt; print shapes.Shape_area(circle)
&gt;&gt;&gt; print(shapes.Shape_area(circle))
153.93804004599999757
&gt;&gt;&gt; print shapes.Shape_area(square)
&gt;&gt;&gt; print(shapes.Shape_area(square))
100.00000000000000000
&gt;&gt;&gt; shapes.Shape_set_location(square, 2, -3)
&gt;&gt;&gt; print shapes.Shape_perimeter(square)
&gt;&gt;&gt; print(shapes.Shape_perimeter(square))
40.00000000000000000
&gt;&gt;&gt;
</pre></div>
@ -4763,15 +4768,31 @@ More advanced handling of namespaces is discussed next.
<p>
Some target languages provide support for the <tt>nspace</tt> <a href="Customization.html#Customization_features">feature</a>.
The feature can be applied to any class, struct, union or enum declared within a named namespace.
The feature wraps the type within the target language specific concept of a namespace,
for example, a Java package or C# namespace.
Please see the language specific sections to see if the target language you are interested in supports the nspace feature.
The <tt>nspace</tt> feature operates in two modes.
Firstly, in a simple enable/disable mode to mirror the C++ namespaces into the target language specific concept of a C++ namespace.
Secondly, a complex mode for modifying, renaming or moving the hierarchies of the language specific concept of a C++ namespace.
</p>
<p>
The feature is demonstrated below for C# using the following example:
The types of symbols that the feature can be applied to are any class, struct, union or enum declared within a named namespace.
This also includes templates of the aforementioned types.
The feature wraps the type within the target language specific concept of a namespace,
such as a Java package or C# namespace.
Only some target languages provide support for the <tt>nspace</tt> feature.
Please see the target language specific sections to see if the language you are interested in supports the nspace feature.
</p>
<H4><a name="SWIGPlus_nspace_feature_flag">6.19.1.1 %nspace for mirroring namespace hierarchies</a></H4>
<p>
In this simple mode the <tt>nspace</tt> feature works as a <a href="Customization.html#Customization_feature_flags">feature flag</a> to enable or disable the feature for a given C++ symbol.
As described earlier, all namespace are flattened by default, hence the <tt>nspace</tt> feature is disabled by default.
When the feature is enabled, the C++ namespace hierarchies are mirrored into the target language concept of a namespace.
</p>
<p>
The feature flag is demonstrated below using the following example:
</p>
<div class="code">
@ -4795,7 +4816,7 @@ namespace MyWorld {
</div>
<p>
Without the <tt>nspace</tt> feature directives above or <tt>%rename</tt>, you would get the following warning resulting in just one of the <tt>Color</tt> classes being available for use from the target language:
By default, without the above <tt>nspace</tt> feature flags (or an appropriate <tt>%rename</tt>), SWIG outputs the following warning resulting in just one of the <tt>Color</tt> classes being available for use from the target language:
</p>
<div class="shell">
@ -4806,14 +4827,24 @@ example.i:5: Error: Previous declaration of 'Color'
</div>
<p>
With the <tt>nspace</tt> feature the two <tt>Color</tt> classes are wrapped into the equivalent C# namespaces.
Let's consider C# as the target language.
With the two <tt>nspace</tt> feature flags, the two C# <tt>Color</tt> proxy classes are generated into the equivalent C# namespaces that mirror the C++ namespace hierarchies.
A fully qualified constructor call of each these two types in C# is then:
</p>
<div class="targetlang">
<pre>
MyWorld.Material.Color materialColor = new MyWorld.Material.Color();
MyWorld.Wrapping.Color wrappingColor = new MyWorld.Wrapping.Color();
var materialColor = new MyWorld.Material.Color();
var wrappingColor = new MyWorld.Wrapping.Color();
</pre>
</div>
<p>
Without the <tt>nspace</tt> feature flag, no namespaces are available in C# and the fully qualified constructor call of the type in C# would simply be:
</p>
<div class="targetlang">
<pre>
var materialColor = new Color();
</pre>
</div>
@ -4837,9 +4868,186 @@ namespace MyWorld {
</div>
<p>
<b>Compatibility Note:</b> The nspace feature was first introduced in SWIG-2.0.0.
<b>Compatibility Note:</b> The simple <tt>%nspace</tt> feature flag was first introduced in SWIG-2.0.0.
</p>
<H4><a name="SWIGPlus_nspacemove">6.19.1.2 %nspacemove for modifying namespace hierarchies</a></H4>
<p>
The more complex mode for <tt>nspace</tt> provides the ability to move a type into a differently named target language equivalent of a namespace.
This allows a fully flexible approach to mapping C++ namespaces into a target language equivalent of a namespace, such as:
</p>
<ul>
<li> Renaming a namespace.</li>
<li> Renaming any number of sub-namespaces of a namespace.</li>
<li> Moving a type to a completely different namespace.</li>
<li> Splitting many types in one namespace into multiple different namespaces.</li>
<li> Adding nested sub-namespaces to a namespace.</li>
<li> Removing nested sub-namespaces of namespace.</li>
<li> Combinations of the above.</li>
</ul>
<p>
The <tt>nspace</tt> feature attaches to a C++ symbol and provides a target language namespace for that symbol to move to.
The <tt>%nspacemove</tt> directive is a macro for the <tt>nspace</tt> feature as follows:
</p>
<div class="code">
<pre>
#define %nspacemove(NAMESPACE) %feature("nspace", #NAMESPACE)
</pre>
</div>
<p>
where the target namespace is provided in <tt>NAMESPACE</tt> and is specified in valid C++ syntax, such as <tt>A::B::C</tt>.
Internally, SWIG converts the C++ namespace into a target language equivalent,
so this might for example, result in a C# namespace called <tt>A.B.C</tt> or a Java package named <tt>A.B.C</tt>.
Note that the target namespace does not have to actually exist in any of the C++ code that SWIG parses; it could be entirely made-up.
</p>
<p>
Either the <tt>%nspacemove</tt> macro or the more verbose <tt>%feature</tt> syntax can be used. Please see the <a href="Customization.html#Customization_features">Features and the %feature directive</a> section for more details of SWIG features.
</p>
<p>
An example follows:
</p>
<div class="code">
<pre>
// Enable the nspace feature flag for all symbols
%nspace;
// Override the nspace feature for a subset of symbols by moving them into different namespaces
%nspacemove(A) A::B::C::Struct1;
%feature("nspace", "A::B::X") A::B::C::Struct2;
%nspacemove(A::B::C::D) A::B::C::Struct4;
%nspacemove(Somewhere::Else) A::B::C::Struct5;
%inline %{
namespace A {
namespace B {
namespace C {
struct Struct1 {
// ...
};
struct Struct2 {
// ...
};
struct Struct3 {
// ...
};
struct Struct4 {
// ...
};
struct Struct5 {
// ...
};
}
}
}
%}
</pre>
</div>
<p>
The C# code below constructs each of the above classes.
It shows the namespaces that the C# proxy classes have been moved into,
noting though that <tt>Struct4</tt> merely exactly mirrors the C++ namespace hierarchy as it has the <tt>nspace</tt> feature flag attached to it.
</p>
<div class="targetlang">
<pre>
var s1 = new A.Struct1();
var s2 = new A.B.X.Struct2();
var s3 = new A.B.C.Struct3();
var s4 = new A.B.C.D.Struct4();
var s5 = new Somewhere.Else.Struct5();
</pre>
</div>
<H4><a name="SWIGPlus_nspace_more">6.19.1.3 More about the nspace feature</a></H4>
<p>
When the <tt>nspace</tt> feature is attached to a class or enum, all contained symbols (members) are also automatically moved into the target language namespace.
Contained symbols include all enum values, static and non-static class members as well as nested classes.
There is no need for additional <tt>nspace</tt> features to be specified for all the contained symbols.
Below is an example showing this.
It also shows the nspace feature working for templates.
</p>
<div class="code">
<pre>
// Easy way to move all the Structure template instantiations into a different namespace
%nspacemove(A::Different::Space) Space::Structure;
%inline %{
namespace Space {
template&lt;typename T&gt;
struct Structure {
static int Count;
static void StaticMethod(T t) {
// ...
}
struct NestedStruct {
// ...
};
};
template&lt;typename T&gt;
int Structure&lt;T&gt;::Count = 0;
}
%}
%template(StructureInt) Space::Structure&lt;int&gt;;
%template(StructureString) Space::Structure&lt;const char *&gt;;
</pre>
</div>
<p>
The C# code below shows the full C# namespace <tt>A.Different.Space</tt> being used as one would expect for all the contained symbols within a C# class.
</p>
<div class="targetlang">
<pre>
var s = new A.Different.Space.StructureInt();
int count = A.Different.Space.StructureInt.Count;
var n = new A.Different.Space.StructureInt.NestedStruct();
A.Different.Space.StructureInt.StaticMethod(99);
A.Different.Space.StructureString.StaticMethod("hi");
</pre>
</div>
<p>
Any attempt to give a different namespace value to a nested class or enum will issue a warning.
For example, adding the following to the above in an attempt to move one of the instantiated nested classes into another namespace like this:
</p>
<div class="code">
<pre>
%nspacemove(Bad::Space) Space::Structure&lt;int&gt;::NestedStruct;
... rest of example above ...
</pre>
</div>
<p>
will result in the following warning:
</p>
<div class="shell">
<pre>
Warning 406: Ignoring nspace setting (Bad::Space) for 'Space::Structure&lt; int &gt;::NestedStruct',
Warning 406: as it conflicts with the nspace setting (A::Different::Space) for outer class 'Space::Structure&lt; int &gt;'.
</pre>
</div>
<p>
<b>Compatibility Note:</b> Modifying namespace hierarchies via <tt>%nspacemove</tt> was first introduced in SWIG-4.3.0.
</p>
<H2><a name="SWIGPlus_renaming_templated_types_namespaces">6.20 Renaming templated types in namespaces</a></H2>
@ -5050,7 +5258,7 @@ string like this:
<div class="targetlang">
<pre>
&gt;&gt;&gt; print example.FOO
&gt;&gt;&gt; print(example.FOO)
_ff0d54a800000000_m_Object__f_double_double__double
&gt;&gt;&gt;
</pre>
@ -5184,7 +5392,7 @@ example, you could do this in Python:
<div class="targetlang">
<pre>
&gt;&gt;&gt; f = make_Foo()
&gt;&gt;&gt; print f.x
&gt;&gt;&gt; print(f.x)
0
&gt;&gt;&gt; f.bar()
&gt;&gt;&gt;
@ -5928,7 +6136,7 @@ the virtual <tt>handle</tt> method, that is, the Python method <tt>handle</tt> i
<pre>
handler = PythonBinaryOp()
result = example.binary_op_wrapper(10, 20, handler)
print result
print(result)
</pre>
</div>

View File

@ -44,6 +44,10 @@
<li><a href="#Typemaps_nn22">Scope</a>
<li><a href="#Typemaps_nn23">Declaring new local variables</a>
<li><a href="#Typemaps_special_variables">Special variables</a>
<ul>
<li><a href="#Typemaps_type_special_variables">Type related special variables</a>
<li><a href="#Typemaps_non_type_special_variables">Non-type related special variables</a>
</ul>
<li><a href="#Typemaps_special_variable_macros">Special variable macros</a>
<ul>
<li><a href="#Typemaps_special_macro_descriptor">$descriptor(type)</a>
@ -246,7 +250,7 @@ that is inserted directly into the SWIG generated wrapper functions.
The code is usually C or C++ code which will be generated into the C/C++ wrapper functions.
Note that this isn't always the case as some target language modules allow target language
code within the typemaps which gets generated into target language specific files.
Within this code, a number of special variables prefixed with a $ are expanded. These are
Within this code, a number of special variables prefixed with a <tt>$</tt> are expanded. These are
really just placeholders for C/C++ variables that are generated in the course
of creating the wrapper function. In this case, <tt>$input</tt> refers to an
input object that needs to be converted to C/C++ and <tt>$result</tt>
@ -2129,13 +2133,22 @@ each type must have its own local variable declaration.
<H3><a name="Typemaps_special_variables">14.4.3 Special variables</a></H3>
<p>
Special variables are prefixed with a <tt>$</tt> and are expanded by SWIG as part of the code generation process.
</p>
<H4><a name="Typemaps_type_special_variables">14.4.3.1 Type related special variables</a></H4>
<p>
Within all typemaps, the following special variables are expanded.
These are related in some way to a typemap's type.
This is by no means a complete list as some target languages have additional special variables which are documented in the language specific chapters.
</p>
<center>
<table border=1 summary="Typemap special variables">
<table border=1 summary="Typemap type related special variables">
<tr><th>Variable</th><th>Meaning</th></tr>
<tr>
@ -2378,6 +2391,38 @@ Another approach, which only works for arrays is to use the <tt>$1_basetype</tt>
</pre>
</div>
<H4><a name="Typemaps_non_type_special_variables">14.4.3.2 Non-type related special variables</a></H4>
<p>
The following are additional special variables.
These are not specifically related to a typemap's type.
</p>
<center>
<table border=1 summary="Non-type related special variables">
<tr><th>Variable</th><th>Meaning</th></tr>
<tr>
<td>$<em>isvoid</em></td>
<td>
Expands to 1 if the wrapped function has a void return, otherwise expands to 0.
Note that it expands to 1 in destructors and 0 in constructors.
</td>
</tr>
<tr>
<td>$<em>symname</em></td>
<td>
Name of function/method being wrapped.
</td>
</tr>
</table>
</center>
<H3><a name="Typemaps_special_variable_macros">14.4.4 Special variable macros</a></H3>
@ -2588,13 +2633,12 @@ to C. For example:
</div>
<p>
The following special variables are available:
The following additional special variables are available:
</p>
<div class="code">
<pre>
$input - Input object holding value to be converted.
$symname - Name of function/method being wrapped
</pre>
</div>
@ -2670,13 +2714,12 @@ into the target language. For example:
</div>
<p>
The following special variables are available.
The following additional special variables are available.
</p>
<div class="code">
<pre>
$result - Result object returned to target language.
$symname - Name of function/method being wrapped
</pre>
</div>
@ -2780,14 +2823,13 @@ with an "in" typemap---possibly to ignore the input value. For example:
</div>
<p>
The following special variables are available.
The following additional special variables are available.
</p>
<div class="diagram">
<pre>
$result - Result object returned to target language.
$input - The original input object passed.
$symname - Name of function/method being wrapped
</pre>
</div>
@ -3719,7 +3761,7 @@ might write typemaps like this:
// Return the buffer. Discarding any previous return result
%typemap(argout) (void *rbuffer, size_t len) {
Py_XDECREF($result); /* Blow away any previous result */
Py_DecRef($result); /* Blow away any previous result */
if (result &lt; 0) { /* Check for I/O error */
free($1);
PyErr_SetFromErrno(PyExc_IOError);

View File

@ -537,7 +537,7 @@ like this:
str = (char *)malloc(strlen(strtmp) + 1);
if (str)
strcpy(str, strtmp);
Py_DECREF(pystr);
Py_DecRef(pystr);
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");

View File

@ -478,6 +478,7 @@ example.i(4) : Syntax error in input(1).
<li>403. Class 'name' might be abstract.
<li>404. Duplicate template instantiation of '<em>type</em>' with name '<em>name</em>' ignored, previous instantiation of '<em>type</em>' with name '<em>name</em>'.
<li>405. Method with rvalue ref-qualifier <em>name</em> ignored.
<li>406. Ignoring nspace setting (<em>setting</em>) for '<em>type</em>', as it conflicts with the nspace setting (<em>setting</em>) for outer class '<em>type</em>'
<li>450. Reserved
<li>451. Setting const char * variable may leak memory.
<li>452. Reserved

View File

@ -45,10 +45,10 @@ endif
TARGET =
CC = @CC@
CXX = @CXX@
CPPFLAGS = $(SRCDIR_INCLUDE)
CPPFLAGS = $(SRCDIR_INCLUDE) $(EXTRA_CPPFLAGS)
CFLAGS = @PLATCFLAGS@ $(EXTRA_CFLAGS)
CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ $(EXTRA_CXXFLAGS)
LDFLAGS =
LDFLAGS = $(EXTRA_LDFLAGS)
prefix = @prefix@
exec_prefix= @exec_prefix@
SRCS =
@ -356,8 +356,8 @@ D_RUNME = ./$(RUNME)
d: $(SRCDIR_SRCS)
$(SWIGD) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(DCFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(DCFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
# ----------------------------------------------------------------
# Build a dynamically loadable D wrapper for a C++ module
@ -365,8 +365,8 @@ d: $(SRCDIR_SRCS)
d_cpp: $(SRCDIR_SRCS)
$(SWIGD) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(DCFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(DCFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
# ----------------------------------------------------------------
# Compile D files
@ -1334,10 +1334,19 @@ else
PYTHON_DLNK = @PYTHON3DYNAMICLINKING@
PYTHON_LINK = @PY3LINK@
endif
PYTHON_SO = @PYTHON_SO@
# Set PY_ABI_VER to the target ABI version, such as 3.4, if wanting a stable ABI build
PY_ABI_VER =
ifneq (,$(PY_ABI_VER))
PYTHON_SO = .abi3@PYTHON_SO@
EXTRA_CPPFLAGS := -DPy_LIMITED_API=$(shell printf "0x%02X%02X0000" $(subst ., ,$(PY_ABI_VER)))
else
PYTHON_SO = @PYTHON_SO@
endif
PYCODESTYLE = @PYCODESTYLE@
PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
PYABI3AUDIT = @PYABI3AUDIT@
# ----------------------------------------------------------------
# Build a C dynamically loadable module
@ -1347,6 +1356,11 @@ python: $(SRCDIR_SRCS)
$(SWIG) -python $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
ifneq (,$(PY_ABI_VER))
ifneq (,$(PYABI3AUDIT))
$(COMPILETOOL) $(PYABI3AUDIT) --assume-minimum-abi3 $(PY_ABI_VER) --report -o $(TARGET)_abi3_report.json $(LIBPREFIX)_$(TARGET)$(PYTHON_SO) || (cat $(TARGET)_abi3_report.json && false)
endif
endif
# -----------------------------------------------------------------
# Build a C++ dynamically loadable module
@ -1356,6 +1370,11 @@ python_cpp: $(SRCDIR_SRCS)
$(SWIG) -python -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
ifneq (,$(PY_ABI_VER))
ifneq (,$(PYABI3AUDIT))
$(COMPILETOOL) $(PYABI3AUDIT) --assume-minimum-abi3 $(PY_ABI_VER) --report -o $(TARGET)_abi3_report.json $(LIBPREFIX)_$(TARGET)$(PYTHON_SO) || (cat $(TARGET)_abi3_report.json && false)
endif
endif
# -----------------------------------------------------------------
# Build statically linked Python interpreter
@ -1412,6 +1431,7 @@ python_clean:
rm -f core @EXTRA_CLEAN@
rm -f *.@OBJEXT@ *@SO@ *$(PYTHON_SO)
rm -f $(TARGET).py
rm -f *_abi3_report.json
case "x$(SRCDIR)" in x|x./);; *) rm -f $(RUNME).py;; esac
##################################################################

View File

@ -9,6 +9,7 @@ EXAMPLES_TOP = ../../..
SWIG_TOP = ../../../..
SWIGEXE = $(SWIG_TOP)/swig
SWIG_LIB_DIR = $(SWIG_TOP)/$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
EXTRA_CPPFLAGS =
EXTRA_CFLAGS =
EXTRA_CXXFLAGS =
EXTRA_LDFLAGS =
@ -29,15 +30,15 @@ check: build
build:
mkdir -p d2/
if [ -f $(SRCDIR)example.cxx ]; then \
$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CXXFLAGS='$(EXTRA_CXXFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CPPFLAGS='$(EXTRA_CPPFLAGS)' EXTRA_CXXFLAGS='$(EXTRA_CXXFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' CXXSRCS='example.cxx' d_cpp; \
elif [ -f $(SRCDIR)example.c ]; then \
$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CPPFLAGS='$(EXTRA_CPPFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' SRCS='example.c' d; \
else \
$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CPPFLAGS='$(EXTRA_CPPFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' SRCS='' d; \
fi

View File

@ -15,6 +15,7 @@ functor
import
import_packages
import_template
#libffi
multimap
operator
pointer

View File

@ -23,5 +23,7 @@ build:
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' python_clean
rm -f foo.py bar.py spam.py base.py
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='base' python_clean
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='bar' python_clean
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='spam' python_clean

View File

@ -23,5 +23,7 @@ build:
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' python_clean
rm -f foo.py bar.py spam.py base.py
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='base' python_clean
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='bar' python_clean
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='spam' python_clean

View File

@ -0,0 +1,22 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS =
TARGET = example
INTERFACE = example.i
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' LIBS='-L/usr/local/lib -lffi' python
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mypython' INTERFACE='$(INTERFACE)' python_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' python_clean

View File

@ -0,0 +1,181 @@
/* File : example.i */
%module example
%{
#ifdef _WIN32
# include <process.h>
# define execlp _execlp
#else
# include <unistd.h>
#endif
#include <ffi.h>
%}
/* A wrapper for execlp() using libffi to handle an arbitrary
number of arguments */
%typemap(in) (...) {
char **argv;
int argc;
int i;
argc = PyTuple_Size(varargs);
argv = (char **) malloc(sizeof(char *)*(argc+1));
for (i = 0; i < argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (!PyString_Check(o)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
SWIG_fail;
}
argv[i] = PyString_AsString(o);
}
argv[i] = NULL;
$1 = (void *) argv;
}
/* Rewrite the function call, using libffi */
%feature("action") execlp {
int i, vc;
ffi_cif cif;
ffi_type **types;
void **values;
char **args;
vc = PyTuple_Size(varargs);
types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *));
values = (void **) malloc((vc+3)*sizeof(void *));
args = (char **) arg3;
/* Set up path parameter */
types[0] = &ffi_type_pointer;
values[0] = &arg1;
/* Set up first argument */
types[1] = &ffi_type_pointer;
values[1] = &arg2;
/* Set up rest of parameters */
for (i = 0; i <= vc; i++) {
types[2+i] = &ffi_type_pointer;
values[2+i] = &args[i];
}
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
&ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) execlp, &result, values);
} else {
free(types);
free(values);
free(arg3);
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
SWIG_fail;
}
free(types);
free(values);
free(arg3);
}
int execlp(const char *path, const char *arg1, ...);
/* A wrapper for printf() using libffi */
%{
typedef struct {
int type;
union {
int ivalue;
double dvalue;
void *pvalue;
} val;
} vtype;
enum { VT_INT, VT_DOUBLE, VT_POINTER };
%}
%typemap(in) (const char *fmt, ...) {
vtype *argv;
int argc;
int i;
$1 = PyString_AsString($input);
argc = PyTuple_Size(varargs);
argv = (vtype *) malloc(argc*sizeof(vtype));
for (i = 0; i < argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (PyInt_Check(o)) {
argv[i].type = VT_INT;
argv[i].val.ivalue = PyInt_AsLong(o);
} else if (PyFloat_Check(o)) {
argv[i].type = VT_DOUBLE;
argv[i].val.dvalue = PyFloat_AsDouble(o);
} else if (PyString_Check(o)) {
argv[i].type = VT_POINTER;
argv[i].val.pvalue = (void *) PyString_AsString(o);
} else {
free(argv);
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
SWIG_fail;
}
}
$2 = (void *) argv;
}
/* Rewrite the function call, using libffi */
%feature("action") printf {
int i, vc;
ffi_cif cif;
ffi_type **types;
void **values;
vtype *args;
vc = PyTuple_Size(varargs);
types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *));
values = (void **) malloc((vc+1)*sizeof(void *));
args = (vtype *) arg2;
/* Set up fmt parameter */
types[0] = &ffi_type_pointer;
values[0] = &arg1;
/* Set up rest of parameters */
for (i = 0; i < vc; i++) {
switch(args[i].type) {
case VT_INT:
types[1+i] = &ffi_type_uint;
values[1+i] = &args[i].val.ivalue;
break;
case VT_DOUBLE:
types[1+i] = &ffi_type_double;
values[1+i] = &args[i].val.dvalue;
break;
case VT_POINTER:
types[1+i] = &ffi_type_pointer;
values[1+i] = &args[i].val.pvalue;
break;
default:
abort(); /* Whoa! We're seriously hosed */
break;
}
}
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
&ffi_type_uint, types) == FFI_OK) {
ffi_call(&cif, (void (*)()) printf, &result, values);
} else {
free(types);
free(values);
free(args);
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
SWIG_fail;
}
free(types);
free(values);
free(args);
}
int printf(const char *fmt, ...);

View File

@ -0,0 +1,11 @@
# file: runme.py
import example
# The first parameter and any strings passed here need to be byte strings.
example.printf(b'Testing\n')
example.printf(b'Testing %s %d %c %.0f\n', b'libffi', 1, 50, 3.0)
# The first two arguments need to be Unicode strings for Python 3, but the
# remaining arguments need to be bytes!
example.execlp('/bin/ls', 'ls', b'-l')

View File

@ -15,7 +15,7 @@ extern int squareCubed (int n, int *OUTPUT);
extern int gcd(int x, int y);
%typemap(in,fragment="t_output_helper") (int argc, char *argv[]) {
%typemap(in) (int argc, char *argv[]) {
int i;
if (!PyList_Check($input)) {
SWIG_exception(SWIG_ValueError, "Expecting a list");
@ -47,7 +47,7 @@ extern int gcd(int x, int y);
$2[i] = (char *)malloc(strlen(strtmp) + 1);
if ($2[i])
strcpy($2[i], strtmp);
Py_DECREF(utf8str);
Py_DecRef(utf8str);
}
%#else
$2[i] = PyString_AsString(s);
@ -84,7 +84,7 @@ extern int gcdmain(int argc, char *argv[]);
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
$2 = (int)len;
Py_DECREF(utf8str);
Py_DecRef(utf8str);
%#else
if (!PyString_Check($input)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
@ -120,7 +120,7 @@ extern int count(char *bytes, int len, char c);
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
$1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
$2 = (int)len;
Py_DECREF(utf8str);
Py_DecRef(utf8str);
%#else
$2 = (int)PyString_Size($input);
$1 = (char *) malloc($2+1);
@ -128,7 +128,7 @@ extern int count(char *bytes, int len, char c);
%#endif
}
/* Return the mutated string as a new object. The t_output_helper
/* Return the mutated string as a new object. The SWIG_Python_AppendOutput
function takes an object and appends it to the output object
to create a tuple */
@ -139,7 +139,7 @@ extern int count(char *bytes, int len, char c);
%#else
o = PyString_FromStringAndSize($1,$2);
%#endif
$result = t_output_helper($result,o);
$result = SWIG_Python_AppendOutput($result, o, $isvoid);
free($1);
}

View File

@ -335,8 +335,6 @@ CPP_TEST_CASES += \
namespace_typemap \
namespace_union \
namespace_virtual_method \
nspace \
nspace_extend \
native_directive \
naturalvar \
naturalvar_more \
@ -352,6 +350,11 @@ CPP_TEST_CASES += \
nested_workaround \
newobject1 \
newobject3 \
nspace \
nspace_extend \
nspacemove \
nspacemove_nested \
nspacemove_stl \
null_pointer \
numeric_bounds_checking \
operator_overload \
@ -554,6 +557,7 @@ CPP_TEST_CASES += \
typemap_directorout \
typemap_documentation \
typemap_global_scope \
typemap_isvoid \
typemap_manyargs \
typemap_namespace \
typemap_ns_using \
@ -944,7 +948,6 @@ swig_and_compile_cpp_helper = \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT=$(2) NOLINK=true \
TARGET="$(TARGETPREFIX)$(1)$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$(1).i" \
EXTRA_CXXFLAGS="$(3)" \
$(LANGUAGE)$(VARIANT)_cpp
swig_and_compile_cpp = \

View File

@ -35,3 +35,32 @@ namespace fakestd {
void bar(fakestd::array<int, (1<2? 100 : 50)> *x) { }
%}
// Regression test for #2919, fixed in 4.3.0.
//
// sizeof() didn't work on complex expressions or types.
//
// This is just a parsing test for SWIG as it uses C++11 features.
#include <type_traits>
template <typename T>
class InternalHelper {
public:
// Original source: https://github.com/protocolbuffers/protobuf/blob/v20.2/src/google/protobuf/arena.h#L449-L458
template <typename U>
static char DestructorSkippable(const typename U::DestructorSkippable_*);
template <typename U>
static double DestructorSkippable(...);
typedef std::integral_constant<
bool, sizeof(DestructorSkippable<T>(static_cast<const T*>(0))) ==
sizeof(char) ||
std::is_trivially_destructible<T>::value>
is_destructor_skippable;
// This is nonsensical, but provides a regression test for this not working with alignof() either.
typedef std::integral_constant<
bool, alignof(DestructorSkippable<T>(static_cast<const T*>(0))) ==
alignof(char) ||
std::is_trivially_destructible<T>::value>
test_alignof_too;
};

View File

@ -73,5 +73,7 @@ const int s7a = sizeof(3.14);
const int s7b = sizeof 3.14;
const int s8a = sizeof(2.1e-6);
const int s8b = sizeof 2.1e-6;
const int s9a = sizeof(-s8a);
// const int s9b = sizeof -s8a; /* not currently supported */
%}

View File

@ -5,6 +5,8 @@
%{
#if defined(_MSC_VER)
#include <iso646.h> // for alternative operator names, e.g. 'compl'
#pragma warning(disable : 4804) // warning C4804: '-': unsafe use of type 'bool' in operation
// For: decltype(-false) should_be_int2;
#endif
@ -66,6 +68,10 @@
enum e { E1 };
decltype(+E1) should_be_int10;
decltype(sizeof(i+j)) should_be_ulong;
decltype(sizeof(-i)) should_be_ulong2;
decltype(alignof(int)) should_be_ulong3;
static constexpr decltype(*"abc") should_be_char = 0;
static constexpr decltype(&hidden_global_char) should_be_string = "xyzzy";
@ -74,6 +80,9 @@
// so this would end up wrapped as int.
decltype(!0) should_be_bool;
// Test alternative operator names work in this context.
decltype(((compl 42) and (not 1)) or (2 xor 4)) should_be_bool2;
decltype(E1) should_be_enum;
auto get_number_sum(decltype(i+j) a) -> decltype(i+j) {

View File

@ -87,3 +87,32 @@ void tester2() {
// xxx<TestStruct>(); // compilation error
}
%}
// Check fold expressions parse (#2868):
#define FOLD_EXPR_TEST(OP, FUNC) \
template< \
typename... Ts, \
typename R = typename std::common_type_t<Ts...>, \
std::enable_if_t< \
(std::is_same_v<typename std::decay_t<Ts>,HalfInt> OP ...) \
&& (std::is_constructible_v<HalfInt, R> \
|| std::is_convertible_v<R, HalfInt>) \
>* = nullptr \
> \
constexpr inline R FUNC(const Ts&... t) { return std::min(static_cast<R>(t)...); }
FOLD_EXPR_TEST(+, f1)
FOLD_EXPR_TEST(-, f2)
FOLD_EXPR_TEST(*, f3)
FOLD_EXPR_TEST(/, f4)
FOLD_EXPR_TEST(%, f5)
FOLD_EXPR_TEST(&, f6)
FOLD_EXPR_TEST(|, f7)
FOLD_EXPR_TEST(^, f8)
FOLD_EXPR_TEST(<<, f9)
FOLD_EXPR_TEST(>>, f10)
FOLD_EXPR_TEST(&&, f11)
FOLD_EXPR_TEST(||, f12)
FOLD_EXPR_TEST(==, f13)
FOLD_EXPR_TEST(!=, f14)
FOLD_EXPR_TEST(>=, f15)
FOLD_EXPR_TEST(<=, f16)

View File

@ -52,6 +52,9 @@ std::string_view test_reference_input(std::string_view &input) {
return input;
}
void test_multiple(std::string_view aa, std::string_view bb, const std::string_view &cc, const std::string_view &dd) {
}
void test_throw() TESTCASE_THROW1(std::string_view){
static std::string_view x = "test_throw message";
throw x;

View File

@ -0,0 +1,52 @@
using System;
using char_binaryNamespace;
public class char_binary_runme {
public static void Main() {
Test t = new Test();
string hile = "hile";
string hil0 = "hil\0";
if (t.strlen(hile) != 4)
throw new Exception("bad multi-arg typemap");
if (t.strlen(hil0) != 4)
throw new Exception("bad multi-arg typemap");
if (t.ustrlen(hile) != 4)
throw new Exception("bad multi-arg typemap");
if (t.ustrlen(hil0) != 4)
throw new Exception("bad multi-arg typemap");
SWIGTYPE_p_char pc = char_binary.new_pchar(5);
char_binary.pchar_setitem(pc, 0, 'h');
char_binary.pchar_setitem(pc, 1, 'o');
char_binary.pchar_setitem(pc, 2, 'l');
char_binary.pchar_setitem(pc, 3, 'a');
char_binary.pchar_setitem(pc, 4, '\0');
/* FIXME: pc is NOT a string
if (t.strlen(pc) != 4)
throw new Exception("bad multi-arg typemap");
if (t.ustrlen(pc) != 4)
throw new Exception("bad multi-arg typemap");
*/
/* FIXME: pc is NOT a string
char_binary.var_pchar = pc;
*/
char_binary.var_pchar = "hola";
if (char_binary.var_pchar != "hola")
throw new Exception("bad pointer case");
/* FIXME: pc is NOT a string
char_binary.var_namet = pc;
*/
char_binary.var_namet = "hola";
if (char_binary.var_namet != "hola")
throw new Exception("bad pointer case");
char_binary.delete_pchar(pc);
}
}

View File

@ -0,0 +1,56 @@
using System;
using director_binary_stringNamespace;
public class director_binary_string_runme
{
static void Main()
{
Caller caller = new Caller();
Callback callback = new DirectorBinaryStringCallback();
caller.setCallback(callback);
int sum = caller.call();
int sumData = caller.callWriteData();
caller.delCallback();
if (sum != 9*2*8 + 13*3*5)
throw new Exception("Unexpected sum: " + sum);
if (sumData != 9*2*8)
throw new Exception("Unexpected sumData: " + sumData);
new Callback().run(null, null);
callback = new DirectorBinaryStringCallback();
caller.setCallback(callback);
caller.call_null();
}
}
public class DirectorBinaryStringCallback : Callback {
public DirectorBinaryStringCallback() : base() {}
public override int run(string dataBufferAA, string dataBufferBB)
{
int ret = 0;
if (dataBufferAA != null) {
for (int i = 0; i < dataBufferAA.Length; i++)
ret += (int)dataBufferAA[i] * 2;
}
if (dataBufferBB != null) {
for (int i = 0; i < dataBufferBB.Length; i++) {
ret += (int)dataBufferBB[i] * 3;
}
}
return ret;
}
public override int writeData(string dataBufferAA)
{
int ret = 0;
if (dataBufferAA != null) {
for (int i = 0; i < dataBufferAA.Length; i++)
ret += (int)dataBufferAA[i] * 2;
}
return ret;
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Text;
using li_cdata_cppNamespace;
public class li_cdata_cpp_runme {
public static void Main() {
Encoding utf8 = Encoding.UTF8;
string s0 = "ABC\0abc";
byte[] s = utf8.GetBytes(s0);
SWIGTYPE_p_void m = li_cdata_cpp.malloc(256);
li_cdata_cpp.memmove(m, s);
byte[] ss = li_cdata_cpp.cdata(m, 7);
string ss_string = utf8.GetString(ss);
if (!ss_string.Equals("ABC\0abc"))
throw new Exception("failed got: " + ss_string);
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Text;
using li_cdataNamespace;
public class li_cdata_runme {
public static void Main() {
Encoding utf8 = Encoding.UTF8;
string s0 = "ABC\0abc";
byte[] s = utf8.GetBytes(s0);
SWIGTYPE_p_void m = li_cdata.malloc(256);
li_cdata.memmove(m, s);
byte[] ss = li_cdata.cdata(m, 7);
string ss_string = utf8.GetString(ss);
if (!ss_string.Equals("ABC\0abc"))
throw new Exception("failed got: " + ss_string);
}
}

View File

@ -0,0 +1,61 @@
using System;
public class runme
{
static void Main()
{
// outer classes
nspacemove_nestedNamespace.Space.OuterClass1 oc1 = new nspacemove_nestedNamespace.Space.OuterClass1();
nspacemove_nestedNamespace.Space.OuterClass2 oc2 = new nspacemove_nestedNamespace.Space.OuterClass2();
nspacemove_nestedNamespace.NewSpace3.OuterClass3 oc3 = new nspacemove_nestedNamespace.NewSpace3.OuterClass3();
nspacemove_nestedNamespace.NewSpace4.OuterClass4 oc4 = new nspacemove_nestedNamespace.NewSpace4.OuterClass4();
nspacemove_nestedNamespace.OuterClass5 oc5 = new nspacemove_nestedNamespace.OuterClass5();
nspacemove_nestedNamespace.OuterClass6 oc6 = new nspacemove_nestedNamespace.OuterClass6();
nspacemove_nestedNamespace.OuterClass7 oc7 = new nspacemove_nestedNamespace.OuterClass7();
nspacemove_nestedNamespace.Space.OuterClass10 oc10 = new nspacemove_nestedNamespace.Space.OuterClass10();
nspacemove_nestedNamespace.Space.OuterClass20 oc20 = new nspacemove_nestedNamespace.Space.OuterClass20();
nspacemove_nestedNamespace.NewOkay30.OuterClass30 oc30 = new nspacemove_nestedNamespace.NewOkay30.OuterClass30();
nspacemove_nestedNamespace.NewOkay40.OuterClass40 oc40 = new nspacemove_nestedNamespace.NewOkay40.OuterClass40();
nspacemove_nestedNamespace.NewOkay50.OuterClass50 oc50 = new nspacemove_nestedNamespace.NewOkay50.OuterClass50();
nspacemove_nestedNamespace.OuterClass60 oc60 = new nspacemove_nestedNamespace.OuterClass60();
nspacemove_nestedNamespace.OuterClass70 oc70 = new nspacemove_nestedNamespace.OuterClass70();
nspacemove_nestedNamespace.Space.OuterClass80 oc80 = new nspacemove_nestedNamespace.Space.OuterClass80();
// inner classes
nspacemove_nestedNamespace.Space.OuterClass1.InnerClass1 ic1 = new nspacemove_nestedNamespace.Space.OuterClass1.InnerClass1();
nspacemove_nestedNamespace.Space.OuterClass2.InnerClass2 ic2 = new nspacemove_nestedNamespace.Space.OuterClass2.InnerClass2();
nspacemove_nestedNamespace.NewSpace3.OuterClass3.InnerClass3 ic3 = new nspacemove_nestedNamespace.NewSpace3.OuterClass3.InnerClass3();
nspacemove_nestedNamespace.NewSpace4.OuterClass4.InnerClass4 ic4 = new nspacemove_nestedNamespace.NewSpace4.OuterClass4.InnerClass4();
nspacemove_nestedNamespace.OuterClass5.InnerClass5 ic5 = new nspacemove_nestedNamespace.OuterClass5.InnerClass5();
nspacemove_nestedNamespace.OuterClass6.InnerClass6 ic6 = new nspacemove_nestedNamespace.OuterClass6.InnerClass6();
nspacemove_nestedNamespace.OuterClass7.InnerClass7 ic7 = new nspacemove_nestedNamespace.OuterClass7.InnerClass7();
nspacemove_nestedNamespace.Space.OuterClass10.InnerClass10 ic10 = new nspacemove_nestedNamespace.Space.OuterClass10.InnerClass10();
nspacemove_nestedNamespace.Space.OuterClass20.InnerClass20 ic20 = new nspacemove_nestedNamespace.Space.OuterClass20.InnerClass20();
nspacemove_nestedNamespace.NewOkay30.OuterClass30.InnerClass30 ic30 = new nspacemove_nestedNamespace.NewOkay30.OuterClass30.InnerClass30();
nspacemove_nestedNamespace.NewOkay40.OuterClass40.InnerClass40 ic40 = new nspacemove_nestedNamespace.NewOkay40.OuterClass40.InnerClass40();
nspacemove_nestedNamespace.NewOkay50.OuterClass50.InnerClass50 ic50 = new nspacemove_nestedNamespace.NewOkay50.OuterClass50.InnerClass50();
nspacemove_nestedNamespace.OuterClass60.InnerClass60 ic60 = new nspacemove_nestedNamespace.OuterClass60.InnerClass60();
nspacemove_nestedNamespace.OuterClass70.InnerClass70 ic70 = new nspacemove_nestedNamespace.OuterClass70.InnerClass70();
nspacemove_nestedNamespace.Space.OuterClass80.InnerClass80 ic80 = new nspacemove_nestedNamespace.Space.OuterClass80.InnerClass80();
// inner enums
oc1.take(nspacemove_nestedNamespace.Space.OuterClass1.InnerEnum1.ie1a, ic1);
oc2.take(nspacemove_nestedNamespace.Space.OuterClass2.InnerEnum2.ie2a, ic2);
oc3.take(nspacemove_nestedNamespace.NewSpace3.OuterClass3.InnerEnum3.ie3a, ic3);
oc4.take(nspacemove_nestedNamespace.NewSpace4.OuterClass4.InnerEnum4.ie4a, ic4);
oc5.take(nspacemove_nestedNamespace.OuterClass5.InnerEnum5.ie5a, ic5);
oc6.take(nspacemove_nestedNamespace.OuterClass6.InnerEnum6.ie6a, ic6);
oc7.take(nspacemove_nestedNamespace.OuterClass7.InnerEnum7.ie7a, ic7);
oc10.take(nspacemove_nestedNamespace.Space.OuterClass10.InnerEnum10.ie10a, ic10);
oc20.take(nspacemove_nestedNamespace.Space.OuterClass20.InnerEnum20.ie20a, ic20);
oc30.take(nspacemove_nestedNamespace.NewOkay30.OuterClass30.InnerEnum30.ie30a, ic30);
oc40.take(nspacemove_nestedNamespace.NewOkay40.OuterClass40.InnerEnum40.ie40a, ic40);
oc50.take(nspacemove_nestedNamespace.NewOkay50.OuterClass50.InnerEnum50.ie50a, ic50);
oc60.take(nspacemove_nestedNamespace.OuterClass60.InnerEnum60.ie60a, ic60);
oc70.take(nspacemove_nestedNamespace.OuterClass70.InnerEnum70.ie70a, ic70);
oc80.take(nspacemove_nestedNamespace.Space.OuterClass80.InnerEnum80.ie80a, ic80);
}
}

View File

@ -0,0 +1,82 @@
using System;
public class runme
{
static void Main()
{
// constructors and destructors
nspacemoveNamespace.Ooter.Extra.Inner1.Color color1 = new nspacemoveNamespace.Ooter.Extra.Inner1.Color();
nspacemoveNamespace.Ooter.Extra.Inner1.Color color = new nspacemoveNamespace.Ooter.Extra.Inner1.Color(color1);
color1.Dispose();
color1 = null;
// class methods
color.colorInstanceMethod(20.0);
nspacemoveNamespace.Ooter.Extra.Inner1.Color.colorStaticMethod(20.0);
nspacemoveNamespace.Ooter.Extra.Inner1.Color created = nspacemoveNamespace.Ooter.Extra.Inner1.Color.create();
created.Dispose();
// class enums
nspacemoveNamespace.Outer.SomeClass someClass = new nspacemoveNamespace.Outer.SomeClass();
nspacemoveNamespace.Ooter.Extra.Inner1.Color.Channel channel = someClass.GetInner1ColorChannel();
if (channel != nspacemoveNamespace.Ooter.Extra.Inner1.Color.Channel.Transmission)
throw new ApplicationException("Transmission wrong");
// class anonymous enums
int val1 = nspacemoveNamespace.Ooter.Extra.Inner1.Color.ColorEnumVal1;
int val2 = nspacemoveNamespace.Ooter.Extra.Inner1.Color.ColorEnumVal2;
if (val1 != 0 || val2 != 0x22)
throw new ApplicationException("ColorEnumVal wrong");
// instance member variables
color.instanceMemberVariable = 123;
if (color.instanceMemberVariable != 123)
throw new ApplicationException("instance member variable failed");
// static member variables
nspacemoveNamespace.Ooter.Extra.Inner1.Color.staticMemberVariable = 789;
if (nspacemoveNamespace.Ooter.Extra.Inner1.Color.staticMemberVariable != 789)
throw new ApplicationException("static member variable failed");
if (nspacemoveNamespace.Ooter.Extra.Inner1.Color.staticConstMemberVariable != 222)
throw new ApplicationException("static const member variable failed");
if (nspacemoveNamespace.Ooter.Extra.Inner1.Color.staticConstEnumMemberVariable != nspacemoveNamespace.Ooter.Extra.Inner1.Color.Channel.Transmission)
throw new ApplicationException("static const enum member variable failed");
// check globals in a namespace don't get mangled with the nspacemoveNamespace option
nspacemoveNamespace.nspacemove.namespaceFunction(color);
nspacemoveNamespace.nspacemove.namespaceVar = 111;
if (nspacemoveNamespace.nspacemove.namespaceVar != 111)
throw new ApplicationException("global var failed");
// Same class different namespaces
nspacemoveNamespace.Ooter.Extra.Inner1.Color col1 = new nspacemoveNamespace.Ooter.Extra.Inner1.Color();
nspacemoveNamespace.Outer.Snner2.Color col2 = nspacemoveNamespace.Outer.Snner2.Color.create();
col2.colors(col1, col1, col2, col2, col2);
// global enums
nspacemoveNamespace.Euter.Extra.Inner1.Channel outerChannel1 = someClass.GetInner1Channel();
if (outerChannel1 != nspacemoveNamespace.Euter.Extra.Inner1.Channel.Transmission1)
throw new ApplicationException("Transmission1 wrong");
nspacemoveNamespace.Outer.Enner2.Channel outerChannel2 = someClass.GetInner2Channel();
if (outerChannel2 != nspacemoveNamespace.Outer.Enner2.Channel.Transmission2)
throw new ApplicationException("Transmission2 wrong");
nspacemoveNamespace.nspacemove.takeGlobalEnum(nspacemoveNamespace.More.GlobalEnum.bbb);
// global class
nspacemoveNamespace.Additional.GlobalClass gc = new nspacemoveNamespace.Additional.GlobalClass();
gc.gmethod();
// turn feature off / ignoring
nspacemoveNamespace.Outer.namespce ns = new nspacemoveNamespace.Outer.namespce();
ns.Dispose();
nspacemoveNamespace.NoNSpacePlease nons = new nspacemoveNamespace.NoNSpacePlease();
nons.Dispose();
// Derived class
nspacemoveNamespace.Outer.Inner3.Blue blue3 = new nspacemoveNamespace.Outer.Inner3.Blue();
blue3.blueInstanceMethod();
nspacemoveNamespace.Outer.Inner4.Blue blue4 = new nspacemoveNamespace.Outer.Inner4.Blue();
blue4.blueInstanceMethod();
}
}

View File

@ -0,0 +1,17 @@
using System;
public class runme
{
static void Main()
{
nspacemove_stlNamespace.CPlusPlus.Standard.Ints.VectorInt vi = new nspacemove_stlNamespace.CPlusPlus.Standard.Ints.VectorInt();
nspacemove_stlNamespace.CPlusPlus.Standard.Strings.VectorString vs = new nspacemove_stlNamespace.CPlusPlus.Standard.Strings.VectorString();
nspacemove_stlNamespace.CPlusPlus.Maps.MapIntInt mii = new nspacemove_stlNamespace.CPlusPlus.Maps.MapIntInt();
nspacemove_stlNamespace.CPlusPlus.Maps.MapIntString mis = new nspacemove_stlNamespace.CPlusPlus.Maps.MapIntString();
nspacemove_stlNamespace.nspacemove_stl.test_vector_int(vi);
nspacemove_stlNamespace.nspacemove_stl.test_vector_string(vs);
nspacemove_stlNamespace.nspacemove_stl.test_map_int(mii);
nspacemove_stlNamespace.nspacemove_stl.test_map_string(mis);
}
}

View File

@ -23,5 +23,31 @@ void main() {
pchar_setitem(pc, 2, 'l');
pchar_setitem(pc, 3, 'a');
pchar_setitem(pc, 4, 0);
/* FIXME: pc is not string
if (t.strlen(pc) != 4) {
throw new Exception("bad multi-arg typemap");
}
if (t.ustrlen(pc) != 4) {
throw new Exception("bad multi-arg typemap");
}
*/
/* FIXME: pc is not string
var_pchar = pc;
*/
var_pchar = "hola";
if (var_pchar != "hola") {
throw new Exception("bad pointer case");
}
/* FIXME: pc is not string
var_namet = pc;
*/
var_namet = "hola";
if (var_namet != "hola") {
throw new Exception("bad pointer case");
}
delete_pchar(pc);
}

View File

@ -0,0 +1,51 @@
module director_binary_string_runme;
import director_binary_string.Callback;
import director_binary_string.Caller;
import std.string;
import std.conv : text;
import std.exception : enforce;
void main() {
auto caller = new Caller();
Callback callback = new DirectorBinaryStringCallback();
caller.setCallback(callback);
int sum = caller.call();
int sumData = caller.callWriteData();
caller.delCallback();
enforce(sum == 9*2*8 + 13*3*5, text("Unexpected sum: ", sum));
enforce(sumData == 9*2*8, text("Unexpected sumData: ", sumData));
new Callback().run(null, null);
callback = new DirectorBinaryStringCallback();
caller.setCallback(callback);
caller.call_null();
caller.delCallback();
}
class DirectorBinaryStringCallback : Callback {
public:
this() {
super();
}
override int run(string dataBufferAA, string dataBufferBB)
{
int ret = 0;
char[] aa = dataBufferAA.dup;
for (int i = 0; i < aa.length; i++)
ret += aa[i] * 2;
char[] bb = dataBufferBB.dup;
for (int i = 0; i < bb.length; i++)
ret += bb[i] * 3;
return ret;
}
override int writeData(string dataBufferAA)
{
int ret = 0;
char[] aa = dataBufferAA.dup;
for (int i = 0; i < aa.length; i++)
ret += aa[i] * 2;
return ret;
}
}

View File

@ -0,0 +1,13 @@
module li_cdata_cpp_runme;
import li_cdata_cpp.li_cdata_cpp;
import std.conv;
void main() {
ubyte[] s = cast(ubyte[]) "ABC\0abc".dup;
auto m = malloc(256);
memmove(m, s);
string ss = std.conv.text(cast(char[]) cdata(m, 7));
if (ss != "ABC\0abc")
throw new Exception("failed got: " ~ ss);
}

View File

@ -0,0 +1,13 @@
module li_cdata_runme;
import li_cdata.li_cdata;
import std.conv;
void main() {
ubyte[] s = cast(ubyte[]) "ABC\0abc".dup;
auto m = malloc(256);
memmove(m, s);
string ss = std.conv.text(cast(char[]) cdata(m, 7));
if (ss != "ABC\0abc")
throw new Exception("failed got: " ~ ss);
}

View File

@ -0,0 +1,75 @@
module nspacemove_nested_runme;
import std.exception;
import nspacemove_nested.nspacemove_nested;
static import nspacemove_nested.Space.OuterClass1;
static import nspacemove_nested.Space.OuterClass2;
static import nspacemove_nested.NewSpace3.OuterClass3;
static import nspacemove_nested.NewSpace4.OuterClass4;
static import nspacemove_nested.OuterClass5;
static import nspacemove_nested.OuterClass6;
static import nspacemove_nested.OuterClass7;
static import nspacemove_nested.Space.OuterClass10;
static import nspacemove_nested.Space.OuterClass20;
static import nspacemove_nested.NewOkay30.OuterClass30;
static import nspacemove_nested.NewOkay40.OuterClass40;
static import nspacemove_nested.NewOkay50.OuterClass50;
static import nspacemove_nested.OuterClass60;
static import nspacemove_nested.OuterClass70;
static import nspacemove_nested.Space.OuterClass80;
void main() {
// outer classes
auto oc1 = new nspacemove_nested.Space.OuterClass1.OuterClass1();
auto oc2 = new nspacemove_nested.Space.OuterClass2.OuterClass2();
auto oc3 = new nspacemove_nested.NewSpace3.OuterClass3.OuterClass3();
auto oc4 = new nspacemove_nested.NewSpace4.OuterClass4.OuterClass4();
auto oc5 = new nspacemove_nested.OuterClass5.OuterClass5();
auto oc6 = new nspacemove_nested.OuterClass6.OuterClass6();
auto oc7 = new nspacemove_nested.OuterClass7.OuterClass7();
auto oc10 = new nspacemove_nested.Space.OuterClass10.OuterClass10();
auto oc20 = new nspacemove_nested.Space.OuterClass20.OuterClass20();
auto oc30 = new nspacemove_nested.NewOkay30.OuterClass30.OuterClass30();
auto oc40 = new nspacemove_nested.NewOkay40.OuterClass40.OuterClass40();
auto oc50 = new nspacemove_nested.NewOkay50.OuterClass50.OuterClass50();
auto oc60 = new nspacemove_nested.OuterClass60.OuterClass60();
auto oc70 = new nspacemove_nested.OuterClass70.OuterClass70();
auto oc80 = new nspacemove_nested.Space.OuterClass80.OuterClass80();
// inner classes
auto ic1 = new nspacemove_nested.Space.InnerClass1.InnerClass1();
auto ic2 = new nspacemove_nested.Space.InnerClass2.InnerClass2();
auto ic3 = new nspacemove_nested.NewSpace3.InnerClass3.InnerClass3();
auto ic4 = new nspacemove_nested.NewSpace4.InnerClass4.InnerClass4();
auto ic5 = new nspacemove_nested.InnerClass5.InnerClass5();
auto ic6 = new nspacemove_nested.InnerClass6.InnerClass6();
auto ic7 = new nspacemove_nested.InnerClass7.InnerClass7();
auto ic10 = new nspacemove_nested.Space.InnerClass10.InnerClass10();
auto ic20 = new nspacemove_nested.Space.InnerClass20.InnerClass20();
auto ic30 = new nspacemove_nested.NewOkay30.InnerClass30.InnerClass30();
auto ic40 = new nspacemove_nested.NewOkay40.InnerClass40.InnerClass40();
auto ic50 = new nspacemove_nested.NewOkay50.InnerClass50.InnerClass50();
auto ic60 = new nspacemove_nested.InnerClass60.InnerClass60();
auto ic70 = new nspacemove_nested.InnerClass70.InnerClass70();
auto ic80 = new nspacemove_nested.Space.InnerClass80.InnerClass80();
// inner enums
oc1.take(nspacemove_nested.Space.OuterClass1.OuterClass1.InnerEnum1.ie1a, ic1);
oc2.take(nspacemove_nested.Space.OuterClass2.OuterClass2.InnerEnum2.ie2a, ic2);
oc3.take(nspacemove_nested.NewSpace3.OuterClass3.OuterClass3.InnerEnum3.ie3a, ic3);
oc4.take(nspacemove_nested.NewSpace4.OuterClass4.OuterClass4.InnerEnum4.ie4a, ic4);
oc5.take(nspacemove_nested.OuterClass5.OuterClass5.InnerEnum5.ie5a, ic5);
oc6.take(nspacemove_nested.OuterClass6.OuterClass6.InnerEnum6.ie6a, ic6);
oc7.take(nspacemove_nested.OuterClass7.OuterClass7.InnerEnum7.ie7a, ic7);
oc10.take(nspacemove_nested.Space.OuterClass10.OuterClass10.InnerEnum10.ie10a, ic10);
oc20.take(nspacemove_nested.Space.OuterClass20.OuterClass20.InnerEnum20.ie20a, ic20);
oc30.take(nspacemove_nested.NewOkay30.OuterClass30.OuterClass30.InnerEnum30.ie30a, ic30);
oc40.take(nspacemove_nested.NewOkay40.OuterClass40.OuterClass40.InnerEnum40.ie40a, ic40);
oc50.take(nspacemove_nested.NewOkay50.OuterClass50.OuterClass50.InnerEnum50.ie50a, ic50);
oc60.take(nspacemove_nested.OuterClass60.OuterClass60.InnerEnum60.ie60a, ic60);
oc70.take(nspacemove_nested.OuterClass70.OuterClass70.InnerEnum70.ie70a, ic70);
oc80.take(nspacemove_nested.Space.OuterClass80.OuterClass80.InnerEnum80.ie80a, ic80);
}

View File

@ -0,0 +1,85 @@
module nspacemove_runme;
import std.exception;
import nspacemove.nspacemove;
static import nspacemove.NoNSpacePlease;
static import nspacemove.Outer.namespce;
static import nspacemove.Euter.Extra.Inner1.Channel;
static import oi1c = nspacemove.Ooter.Extra.Inner1.Color;
static import nspacemove.Outer.Enner2.Channel;
static import nspacemove.Outer.Snner2.Color;
static import nspacemove.Outer.Inner3.Blue;
static import nspacemove.Outer.Inner4.Blue;
static import nspacemove.Outer.SomeClass;
static import nspacemove.Additional.GlobalClass;
static import nspacemove.More.GlobalEnum;
void main() {
// constructors and destructors
auto color1 = new oi1c.Color();
auto color = new oi1c.Color(color1);
// class methods
color.colorInstanceMethod(20.0);
oi1c.Color.colorStaticMethod(20.0);
auto created = oi1c.Color.create();
// class enums
auto someClass = new nspacemove.Outer.SomeClass.SomeClass();
auto channel = someClass.GetInner1ColorChannel();
enforce(channel == oi1c.Color.Channel.Transmission,
"Transmission wrong");
// class anonymous enums
int val1 = oi1c.Color.ColorEnumVal1;
int val2 = oi1c.Color.ColorEnumVal2;
enforce(val1 == 0 && val2 == 0x22, "ColorEnumVal wrong");
// instance member variables
color.instanceMemberVariable = 123;
enforce(color.instanceMemberVariable == 123,
"instance member variable failed");
// static member variables
oi1c.Color.staticMemberVariable = 789;
enforce(oi1c.Color.staticMemberVariable == 789,
"static member variable failed");
enforce(oi1c.Color.staticConstMemberVariable == 222,
"static const member variable failed");
enforce(oi1c.Color.staticConstEnumMemberVariable == oi1c.Color.Channel.Transmission,
"static const enum member variable failed");
// check globals in a namespace don't get mangled with the nspacemove option
nspacemove.nspacemove.namespaceFunction(color);
nspacemove.nspacemove.namespaceVar = 111;
enforce(nspacemove.nspacemove.namespaceVar == 111, "global var failed");
// Same class different namespaces
auto col1 = new oi1c.Color();
auto col2 = nspacemove.Outer.Snner2.Color.Color.create();
col2.colors(col1, col1, col2, col2, col2);
// global enums
auto outerChannel1 = someClass.GetInner1Channel();
enforce(outerChannel1 == nspacemove.Euter.Extra.Inner1.Channel.Channel.Transmission1,
"Transmission1 wrong");
auto outerChannel2 = someClass.GetInner2Channel();
enforce(outerChannel2 == nspacemove.Outer.Enner2.Channel.Channel.Transmission2,
"Transmission2 wrong");
takeGlobalEnum(nspacemove.More.GlobalEnum.GlobalEnum.bbb);
// global class
auto gc = new nspacemove.Additional.GlobalClass.GlobalClass();
gc.gmethod();
// turn feature off / ignoring
auto ns = new nspacemove.Outer.namespce.namespce();
auto nons = new nspacemove.NoNSpacePlease.NoNSpacePlease();
// Derived class
auto blue3 = new nspacemove.Outer.Inner3.Blue.Blue();
blue3.blueInstanceMethod();
auto blue4 = new nspacemove.Outer.Inner4.Blue.Blue();
blue4.blueInstanceMethod();
}

View File

@ -0,0 +1,16 @@
module nspacemove_stl_runme;
import std.exception;
import nspacemove_stl.nspacemove_stl;
void main() {
auto vi = new nspacemove_stl.CPlusPlus.Standard.Ints.VectorInt.VectorInt();
auto vs = new nspacemove_stl.CPlusPlus.Standard.Strings.VectorString.VectorString();
auto mii = new nspacemove_stl.CPlusPlus.Maps.MapIntInt.MapIntInt();
auto mis = new nspacemove_stl.CPlusPlus.Maps.MapIntString.MapIntString();
nspacemove_stl.nspacemove_stl.test_vector_int(vi);
nspacemove_stl.nspacemove_stl.test_vector_string(vs);
nspacemove_stl.nspacemove_stl.test_map_int(mii);
nspacemove_stl.nspacemove_stl.test_map_string(mis);
}

View File

@ -4,11 +4,7 @@
%apply (char *STRING, size_t LENGTH) { (char *dataBufferAA, int sizeAA) };
%apply (char *STRING, size_t LENGTH) { (char *dataBufferBB, int sizeBB) };
#ifdef SWIGD
%apply (const char* STRING, size_t LENGTH) { (const char* data, size_t datalen) };
#else
%apply (char* STRING, size_t LENGTH) { (const void* data, size_t datalen) };
#endif
%apply (const char *STRING, size_t LENGTH) { (const char *data, size_t datalen) };
%inline %{
#include <stdlib.h>
@ -20,57 +16,41 @@
class Callback {
public:
virtual ~Callback() {}
virtual void run(char* dataBufferAA, int sizeAA, char* dataBufferBB, int sizeBB) {
if (dataBufferAA)
memset(dataBufferAA, -1, sizeAA);
if (dataBufferBB)
memset(dataBufferBB, -1, sizeBB);
virtual int run(char* dataBufferAA, int sizeAA, char* dataBufferBB, int sizeBB) {
return 0;
}
#ifdef SWIGD
virtual void writeData(const char* data, size_t datalen) = 0;
#else
virtual void writeData(const void* data, size_t datalen) = 0;
#endif
virtual int writeData(const char* data, size_t datalen) = 0;
};
class Caller {
private:
Callback *_callback;
public:
Caller(): _callback(0) {}
~Caller() { delCallback(); }
void delCallback() { delete _callback; _callback = 0; }
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
Caller(): _callback(NULL) {}
void delCallback() { _callback = NULL; }
void setCallback(Callback *cb) { _callback = cb; }
int call() {
int sum = 0;
if (_callback) {
char* aa = (char*)malloc(BUFFER_SIZE_AA);
char aa[BUFFER_SIZE_AA];
memset(aa, 9, BUFFER_SIZE_AA);
char* bb = (char*)malloc(BUFFER_SIZE_BB);
char bb[BUFFER_SIZE_BB];
memset(bb, 13, BUFFER_SIZE_BB);
_callback->run(aa, BUFFER_SIZE_AA, bb, BUFFER_SIZE_BB);
for (int i = 0; i < BUFFER_SIZE_AA; i++)
sum += aa[i];
for (int i = 0; i < BUFFER_SIZE_BB; i++)
sum += bb[i];
free(aa);
free(bb);
return _callback->run(aa, BUFFER_SIZE_AA, bb, BUFFER_SIZE_BB);
}
return sum;
return 0;
}
void call_null() {
_callback->run(NULL, 0, NULL, 0);
if (_callback) {
_callback->run(NULL, 0, NULL, 0);
}
}
int callWriteData() {
int sum = 0;
if (_callback) {
char* aa = (char*)malloc(BUFFER_SIZE_AA);
char aa[BUFFER_SIZE_AA];
memset(aa, 9, BUFFER_SIZE_AA);
_callback->writeData(aa, BUFFER_SIZE_AA);
for (int i = 0; i < BUFFER_SIZE_AA; i++)
sum += aa[i];
return _callback->writeData(aa, BUFFER_SIZE_AA);
}
return sum;
return 0;
}
};

View File

@ -0,0 +1,166 @@
%module xxx
// Test nspace warnings (based on Examples/test-suite/nspacemove_nested.i)
%feature("flatnested"); // must have in order to see nspace warnings when using Python as nested classes are otherwise simply ignored in Python
%nspace Space::OuterClass1;
%nspacemove(Bad::Space1) Space::OuterClass1::InnerClass1;
%nspacemove(Bad::Space1) Space::OuterClass1::InnerEnum1;
%nspace Space::OuterClass2;
%nonspace Space::OuterClass2::InnerClass2;
%nonspace Space::OuterClass2::InnerEnum2;
%nspacemove(NewSpace3) Space::OuterClass3;
%nspacemove(Bad::Space3) Space::OuterClass3::InnerClass3;
%nspacemove(Bad::Space3) Space::OuterClass3::InnerEnum3;
%nspacemove(NewSpace4::NewSubSpace4) Space::OuterClass4;
%nonspace Space::OuterClass4::InnerClass4;
%nonspace Space::OuterClass4::InnerEnum4;
%nspacemove(NewSpace5) Space::OuterClass5::InnerClass5;
%nspacemove(NewSpace5) Space::OuterClass5::InnerEnum5;
%nonspace Space::OuterClass6;
%nspace Space::OuterClass6::InnerClass6;
%nspace Space::OuterClass6::InnerEnum6;
%nonspace Space::OuterClass7;
%nspacemove(NewSpace7) Space::OuterClass7::InnerClass7;
%nspacemove(NewSpace7) Space::OuterClass7::InnerEnum7;
%inline %{
namespace Space {
struct OuterClass1 {
struct InnerClass1 {
struct BottomClass1 {};
};
enum InnerEnum1 { ie1a, ie1b };
void take(InnerEnum1 e) {}
};
struct OuterClass2 {
struct InnerClass2 {
struct BottomClass2 {};
};
enum InnerEnum2 { ie2a, ie2b };
void take(InnerEnum2 e) {}
};
struct OuterClass3 {
struct InnerClass3 {
struct BottomClass3 {};
};
enum InnerEnum3 { ie3a, ie3b };
void take(InnerEnum3 e) {}
};
struct OuterClass4 {
struct InnerClass4 {
struct BottomClass4 {};
};
enum InnerEnum4 { ie4a, ie4b };
void take(InnerEnum4 e) {}
};
struct OuterClass5 {
struct InnerClass5 {
struct BottomClass5 {};
};
enum InnerEnum5 { ie5a, ie5b };
void take(InnerEnum5 e) {}
};
struct OuterClass6 {
struct InnerClass6 {
struct BottomClass6 {};
};
enum InnerEnum6 { ie6a, ie6b };
void take(InnerEnum6 e) {}
};
struct OuterClass7 {
struct InnerClass7 {
struct BottomClass7 {};
};
enum InnerEnum7 { ie7a, ie7b };
void take(InnerEnum7 e) {}
};
}
%}
// These should not warn
%nspace Space::OuterClass10;
%nspace Space::OuterClass10::InnerClass10;
%nspace Space::OuterClass10::InnerEnum10;
%nspace Space::OuterClass20;
%clearnspace Space::OuterClass20::InnerClass20;
%clearnspace Space::OuterClass20::InnerEnum20;
%nspacemove(NewOkay30) Space::OuterClass30;
%nspace Space::OuterClass30::InnerClass30;
%nspace Space::OuterClass30::InnerEnum40;
%nspacemove(NewOkay40) Space::OuterClass40;
%clearnspace Space::OuterClass40::InnerClass40;
%clearnspace Space::OuterClass40::InnerEnum40;
%nspacemove(NewOkay50) Space::OuterClass50;
%nonspace Space::OuterClass60;
%nonspace Space::OuterClass60::InnerClass60;
%nonspace Space::OuterClass60::InnerEnum60;
%nonspace Space::OuterClass70;
%inline %{
namespace Space {
struct OuterClass10 {
struct InnerClass10 {
struct BottomClass10 {};
};
enum InnerEnum10 { ie10a, ie10b };
void take(InnerEnum10 e) {}
};
struct OuterClass20 {
struct InnerClass20 {
struct BottomClass20 {};
};
enum InnerEnum20 { ie20a, ie20b };
void take(InnerEnum20 e) {}
};
struct OuterClass30 {
struct InnerClass30 {
struct BottomClass30 {};
};
enum InnerEnum30 { ie30a, ie30b };
void take(InnerEnum30 e) {}
};
struct OuterClass40 {
struct InnerClass40 {
struct BottomClass40 {};
};
enum InnerEnum40 { ie40a, ie40b };
void take(InnerEnum40 e) {}
};
struct OuterClass50 {
struct InnerClass50 {
struct BottomClass50 {};
};
enum InnerEnum50 { ie50a, ie50b };
void take(InnerEnum50 e) {}
};
struct OuterClass60 {
struct InnerClass60 {
struct BottomClass60 {};
};
enum InnerEnum60 { ie60a, ie60b };
void take(InnerEnum60 e) {}
};
struct OuterClass70 {
struct InnerClass70 {
struct BottomClass70 {};
};
enum InnerEnum70 { ie70a, ie70b };
void take(InnerEnum70 e) {}
};
}
%}

View File

@ -0,0 +1,28 @@
cpp_nspacemove.i:37: Warning 406: Ignoring nspace setting (Bad::Space1) for 'Space::OuterClass1::InnerClass1',
cpp_nspacemove.i:36: Warning 406: as it conflicts with the nspace setting (Space) for outer class 'Space::OuterClass1'.
cpp_nspacemove.i:40: Warning 406: Ignoring nspace setting (Bad::Space1) for 'Space::OuterClass1::InnerEnum1',
cpp_nspacemove.i:36: Warning 406: as it conflicts with the nspace setting (Space) for outer class 'Space::OuterClass1'.
cpp_nspacemove.i:44: Warning 406: Ignoring nspace setting (0) for 'Space::OuterClass2::InnerClass2',
cpp_nspacemove.i:43: Warning 406: as it conflicts with the nspace setting (Space) for outer class 'Space::OuterClass2'.
cpp_nspacemove.i:47: Warning 406: Ignoring nspace setting (0) for 'Space::OuterClass2::InnerEnum2',
cpp_nspacemove.i:43: Warning 406: as it conflicts with the nspace setting (Space) for outer class 'Space::OuterClass2'.
cpp_nspacemove.i:51: Warning 406: Ignoring nspace setting (Bad::Space3) for 'Space::OuterClass3::InnerClass3',
cpp_nspacemove.i:50: Warning 406: as it conflicts with the nspace setting (NewSpace3) for outer class 'Space::OuterClass3'.
cpp_nspacemove.i:54: Warning 406: Ignoring nspace setting (Bad::Space3) for 'Space::OuterClass3::InnerEnum3',
cpp_nspacemove.i:50: Warning 406: as it conflicts with the nspace setting (NewSpace3) for outer class 'Space::OuterClass3'.
cpp_nspacemove.i:58: Warning 406: Ignoring nspace setting (0) for 'Space::OuterClass4::InnerClass4',
cpp_nspacemove.i:57: Warning 406: as it conflicts with the nspace setting (NewSpace4::NewSubSpace4) for outer class 'Space::OuterClass4'.
cpp_nspacemove.i:61: Warning 406: Ignoring nspace setting (0) for 'Space::OuterClass4::InnerEnum4',
cpp_nspacemove.i:57: Warning 406: as it conflicts with the nspace setting (NewSpace4::NewSubSpace4) for outer class 'Space::OuterClass4'.
cpp_nspacemove.i:65: Warning 406: Ignoring nspace setting (NewSpace5) for 'Space::OuterClass5::InnerClass5',
cpp_nspacemove.i:64: Warning 406: as it conflicts with the nspace setting () for outer class 'Space::OuterClass5'.
cpp_nspacemove.i:68: Warning 406: Ignoring nspace setting (NewSpace5) for 'Space::OuterClass5::InnerEnum5',
cpp_nspacemove.i:64: Warning 406: as it conflicts with the nspace setting () for outer class 'Space::OuterClass5'.
cpp_nspacemove.i:72: Warning 406: Ignoring nspace setting (1) for 'Space::OuterClass6::InnerClass6',
cpp_nspacemove.i:71: Warning 406: as it conflicts with the nspace setting () for outer class 'Space::OuterClass6'.
cpp_nspacemove.i:75: Warning 406: Ignoring nspace setting (1) for 'Space::OuterClass6::InnerEnum6',
cpp_nspacemove.i:71: Warning 406: as it conflicts with the nspace setting () for outer class 'Space::OuterClass6'.
cpp_nspacemove.i:79: Warning 406: Ignoring nspace setting (NewSpace7) for 'Space::OuterClass7::InnerClass7',
cpp_nspacemove.i:78: Warning 406: as it conflicts with the nspace setting () for outer class 'Space::OuterClass7'.
cpp_nspacemove.i:82: Warning 406: Ignoring nspace setting (NewSpace7) for 'Space::OuterClass7::InnerEnum7',
cpp_nspacemove.i:78: Warning 406: as it conflicts with the nspace setting () for outer class 'Space::OuterClass7'.

View File

@ -0,0 +1,57 @@
%module xxx
// Bad names for %nspacemove
%nspacemove(2) AA::BB::Bad1;
%nspacemove(1abc) AA::BB::Bad2;
%nspacemove(abc.def) AA::BB::Bad3;
%nspacemove(0gh::ij) AA::BB::Bad4;
%nspacemove(kl::1mn) AA::BB::Bad5;
%nspacemove(kl::mn<int>) AA::BB::Bad6;
// Good names for %nspacemove
%nspacemove(_aaa::_bbb) AA::BB::Good1;
%nspacemove(_ccc::_ddd::_eee) AA::BB::Good2;
%nspacemove(_1ccc::_2ddd::_3eee) AA::BB::Good3;
namespace AA {
namespace BB {
struct Bad1 {};
struct Bad2 {};
struct Bad3 {};
struct Bad4 {};
struct Bad5 {};
struct Bad6 {};
struct Good1 {};
struct Good2 {};
struct Good3 {};
}
}
// Good names (containing whitespace) for %nspacemove
%nspacemove( Good :: Spaces ) AA::BB::Good4;
%nspacemove( Good :: Spaces ) AA::BB::Good5;
// Bad names (single colons) for %nspacemove
%nspacemove(:) AA::BB::Bad7;
%nspacemove(X: :Y) AA::BB::Bad8;
%nspacemove(X:Y) AA::BB::Bad9;
// Bad names (bad double colons) for %nspacemove
%nspacemove(X::Y::) AA::BB::Bad10;
%nspacemove(X:::Y) AA::BB::Bad11;
%nspacemove(X::::Y) AA::BB::Bad12;
namespace AA {
namespace BB {
struct Good4 {};
struct Good5 {};
struct Bad7 {};
struct Bad8 {};
struct Bad9 {};
struct Bad10 {};
struct Bad11 {};
struct Bad12 {};
}
}

View File

@ -0,0 +1,12 @@
cpp_nspacemove_bad.i:18: Error: '2' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:19: Error: '1abc' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:20: Error: 'abc.def' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:21: Error: '0gh::ij' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:22: Error: 'kl::1mn' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:23: Error: 'kl::mn<int>' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:50: Error: ':' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:51: Error: 'X: :Y' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:52: Error: 'X:Y' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:53: Error: 'X::Y::' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:54: Error: 'X:::Y' is not a valid identifier for nspace.
cpp_nspacemove_bad.i:55: Error: 'X::::Y' is not a valid identifier for nspace.

View File

@ -1,6 +1,10 @@
%module expressions
%inline %{
#if defined(_MSC_VER)
#include <iso646.h> // for alternative operator names, e.g. 'compl'
#endif
struct A
{
A() : k( 20/(5-1) ) {}
@ -9,5 +13,9 @@ struct A
// Regression test for preprocessor bug with handling a slash immediately
// followed by a single quote, fixed in 4.2.0. (#2630)
int f(int i = 64/' ') { return i; }
// Regression test for alternative operator names - this failed to parse in
// SWIG 4.2.0 and earlier.
int g(bool b = (compl 1 or not 2) xor (3 and 4) xor (3 bitand 6) xor (3 bitor 5) xor (2 + 2 not_eq 5)) { return (int)b; }
};
%}

View File

@ -5,13 +5,18 @@ import . "swigtests/char_binary"
func main() {
t := NewTest()
if t.Strlen("hile") != 4 {
print(t.Strlen("hile"))
panic("bad multi-arg typemap")
}
if t.Ustrlen("hile") != 4 {
panic("bad multi-arg typemap")
}
if t.Strlen("hil\000") != 4 {
panic("bad multi-arg typemap")
}
if t.Ustrlen("hil\000") != 4 {
panic("bad multi-arg typemap")
}
// creating a raw char*
pc := New_pchar(5)
@ -21,5 +26,30 @@ func main() {
Pchar_setitem(pc, 3, 'a')
Pchar_setitem(pc, 4, 0)
/* FIXME: pc is not a string
if t.Strlen(pc) != 4 {
panic("bad multi-arg typemap")
}
if t.Ustrlen(pc) != 4 {
panic("bad multi-arg typemap")
}
*/
/* FIXME: pc is not a string
SetVar_pchar(pc)
*/
SetVar_pchar("hola")
if GetVar_pchar() != "hola" {
panic("bad pointer case")
}
/* FIXME: pc is not a string
SetVar_namet(pc)
*/
SetVar_namet("hola")
if GetVar_namet() != "hola" {
panic("bad pointer case")
}
Delete_pchar(pc)
}

View File

@ -0,0 +1,49 @@
package main
import wrap "swigtests/director_binary_string"
type DirectorBinaryStringCallback struct{}
func (p *DirectorBinaryStringCallback) Run(dataBufferAA string, dataBufferBB string) int {
ret := 0
for i := 0; i < len(dataBufferAA); i++ {
ret += int(dataBufferAA[i]) * 2
}
for i := 0; i < len(dataBufferBB); i++ {
ret += int(dataBufferBB[i]) * 3
}
return ret
}
func (p *DirectorBinaryStringCallback) WriteData(data string) int {
ret := 0
for i := 0; i < len(data); i++ {
ret += int(data[i]) * 2
}
return ret
}
func main() {
caller := wrap.NewCaller()
callback := wrap.NewDirectorCallback(&DirectorBinaryStringCallback{})
caller.SetCallback(callback)
sum := caller.Call()
sumData := caller.CallWriteData()
caller.DelCallback()
if sum != 9*2*8 + 13*3*5 {
panic(sum)
}
if sumData != 9*2*8 {
panic(sumData)
}
// FIXME panic: accessing abstract class or protected constructor
// It does make sense as writeData() is abstract
// wrap.NewCallback().Run("", "")
callback = wrap.NewDirectorCallback(&DirectorBinaryStringCallback{})
caller.SetCallback(callback)
caller.Call_null()
}

View File

@ -3,11 +3,11 @@ package main
import . "swigtests/li_cdata_cpp"
func main() {
s := "ABC abc"
s := []byte("ABC\x00abc")
m := Malloc(256)
Memmove(m, s, len(s))
ss := Cdata(m, 7)
if string(ss) != "ABC abc" {
Memmove(m, s)
ss := Cdata(m, int64(7))
if string(ss) != "ABC\x00abc" {
panic("failed")
}
}

View File

@ -3,11 +3,11 @@ package main
import . "swigtests/li_cdata"
func main() {
s := "ABC abc"
s := []byte("ABC\x00abc")
m := Malloc(256)
Memmove(m, s, len(s))
ss := Cdata(m, 7)
if string(ss) != "ABC abc" {
Memmove(m, s)
ss := Cdata(m, int64(7))
if string(ss) != "ABC\x00abc" {
panic("failed")
}
}

View File

@ -0,0 +1,6 @@
;; The SWIG modules have "passive" Linkage, i.e., they don't generate
;; Guile modules (namespaces) but simply put all the bindings into the
;; current module. That's enough for such a simple test.
(dynamic-call "scm_init_char_binary_module" (dynamic-link "./libchar_binary"))
(load "testsuite.scm")
(load "../schemerunme/char_binary.scm")

View File

@ -0,0 +1,6 @@
;; The SWIG modules have "passive" Linkage, i.e., they don't generate
;; Guile modules (namespaces) but simply put all the bindings into the
;; current module. That's enough for such a simple test.
(dynamic-call "scm_init_li_cdata_cpp_module" (dynamic-link "./libli_cdata_cpp"))
(load "testsuite.scm")
(load "../schemerunme/li_cdata_cpp.scm")

View File

@ -0,0 +1,6 @@
;; The SWIG modules have "passive" Linkage, i.e., they don't generate
;; Guile modules (namespaces) but simply put all the bindings into the
;; current module. That's enough for such a simple test.
(dynamic-call "scm_init_li_cdata_module" (dynamic-link "./libli_cdata"))
(load "testsuite.scm")
(load "../schemerunme/li_cdata.scm")

View File

@ -55,4 +55,9 @@ void AddOne1r(double& INOUT);
inline void CharNot(char* INOUT) {
if (*INOUT) { *INOUT = '\0'; } else { *INOUT = '\xff'; }
}
inline void* NonVoidOut(int* INOUT) {
*INOUT += 42;
return NULL;
}
%}

View File

@ -87,6 +87,9 @@ java_nspacewithoutpackage.%: JAVA_PACKAGEOPT =
multiple_inheritance_nspace.%: JAVA_PACKAGE = $*Package
nspace.%: JAVA_PACKAGE = $*Package
nspace_extend.%: JAVA_PACKAGE = $*Package
nspacemove.%: JAVA_PACKAGE = $*Package
nspacemove_nested.%: JAVA_PACKAGE = $*Package
nspacemove_stl.%: JAVA_PACKAGE = $*Package
# Rules for the different types of tests
%.cpptest:

View File

@ -13,18 +13,50 @@ public class char_binary_runme {
public static void main(String argv[]) {
Test t = new Test();
byte[] hile = "hile".getBytes();
byte[] hil0 = "hil\0".getBytes();
if (t.strlen(hile) != 4)
throw new RuntimeException("bad multi-arg typemap");
if (t.strlen(hil0) != 4)
String hile = "hile";
if (t.strlen(hile) != 4)
throw new RuntimeException("bad multi-arg typemap");
if (t.ustrlen(hile) != 4)
throw new RuntimeException("bad multi-arg typemap");
String hil0 = "hil\0";
if (t.strlen(hil0) != 4)
throw new RuntimeException("bad multi-arg typemap");
if (t.ustrlen(hil0) != 4)
throw new RuntimeException("bad multi-arg typemap");
// creating a raw char*
SWIGTYPE_p_char pc = char_binary.new_pchar(5);
char_binary.pchar_setitem(pc, 0, 'h');
char_binary.pchar_setitem(pc, 1, 'o');
char_binary.pchar_setitem(pc, 2, 'l');
char_binary.pchar_setitem(pc, 3, 'a');
char_binary.pchar_setitem(pc, 4, '\0');
/* FIXME: incompatible types: SWIGTYPE_p_char cannot be converted to String
if (t.strlen(pc) != 4)
throw new RuntimeException("bad multi-arg typemap");
if (t.ustrlen(pc) != 4)
throw new RuntimeException("bad multi-arg typemap");
*/
/* FIXME: pc cannot be converted to String
char_binary.setVar_pchar(pc);
*/
char_binary.setVar_pchar("hola");
if (!char_binary.getVar_pchar().equals("hola"))
throw new RuntimeException("bad pointer case");
/* FIXME: pc cannot be converted to String
char_binary.setVar_namet(pc);
*/
char_binary.setVar_namet("hola");
if (!char_binary.getVar_namet().equals("hola"))
throw new RuntimeException("bad pointer case");
char_binary.delete_pchar(pc);
}
}

View File

@ -24,7 +24,7 @@ public class director_binary_string_runme {
throw new RuntimeException("Unexpected sum: " + sum);
if (sumData != 9*2*8)
throw new RuntimeException("Unexpected sum: " + sum);
throw new RuntimeException("Unexpected sumData: " + sumData);
new Callback().run(null, null);
callback = new DirectorBinaryStringCallback();
@ -39,23 +39,31 @@ class DirectorBinaryStringCallback extends Callback {
}
@Override
public void run(byte[] dataBufferAA, byte[] dataBufferBB)
public int run(String dataBufferAA, String dataBufferBB)
{
if (dataBufferAA != null)
for (int i = 0; i < dataBufferAA.length; i++)
dataBufferAA[i] = (byte)(dataBufferAA[i] * 2);
int ret = 0;
if (dataBufferAA != null) {
for (int i = 0; i < dataBufferAA.length(); i++)
ret += (int)dataBufferAA.charAt(i) * 2;
}
if (dataBufferBB != null)
for (int i = 0; i < dataBufferBB.length; i++)
dataBufferBB[i] = (byte)(dataBufferBB[i] * 3);
if (dataBufferBB != null) {
for (int i = 0; i < dataBufferBB.length(); i++) {
ret += (int)dataBufferBB.charAt(i) * 3;
}
}
return ret;
}
@Override
public void writeData(byte[] dataBufferAA)
public int writeData(String dataBufferAA)
{
if (dataBufferAA != null)
for (int i = 0; i < dataBufferAA.length; i++)
dataBufferAA[i] = (byte)(dataBufferAA[i] * 2);
int ret = 0;
if (dataBufferAA != null) {
for (int i = 0; i < dataBufferAA.length(); i++)
ret += (int)dataBufferAA.charAt(i) * 2;
}
return ret;
}
}

View File

@ -13,12 +13,12 @@ public class li_cdata_cpp_runme {
public static void main(String argv[]) throws Throwable
{
byte[] s = "ABC abc".getBytes();
byte[] s = "ABC\0abc".getBytes("UTF-8");
SWIGTYPE_p_void m = li_cdata_cpp.malloc(256);
li_cdata_cpp.memmove(m, s);
byte[] ss = li_cdata_cpp.cdata(m, 7);
String ss_string = new String(ss);
if (!ss_string.equals("ABC abc"))
String ss_string = new String(ss, "UTF-8");
if (!ss_string.equals("ABC\0abc"))
throw new RuntimeException("failed got: " + ss_string);
}
}

View File

@ -13,12 +13,12 @@ public class li_cdata_runme {
public static void main(String argv[]) throws Throwable
{
byte[] s = "ABC abc".getBytes();
byte[] s = "ABC\0abc".getBytes("UTF-8");
SWIGTYPE_p_void m = li_cdata.malloc(256);
li_cdata.memmove(m, s);
byte[] ss = li_cdata.cdata(m, 7);
String ss_string = new String(ss);
if (!ss_string.equals("ABC abc"))
String ss_string = new String(ss, "UTF-8");
if (!ss_string.equals("ABC\0abc"))
throw new RuntimeException("failed got: " + ss_string);
}
}

View File

@ -0,0 +1,67 @@
public class nspacemove_nested_runme {
static {
try {
System.loadLibrary("nspacemove_nested");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
// outer classes
nspacemove_nestedPackage.Space.OuterClass1 oc1 = new nspacemove_nestedPackage.Space.OuterClass1();
nspacemove_nestedPackage.Space.OuterClass2 oc2 = new nspacemove_nestedPackage.Space.OuterClass2();
nspacemove_nestedPackage.NewSpace3.OuterClass3 oc3 = new nspacemove_nestedPackage.NewSpace3.OuterClass3();
nspacemove_nestedPackage.NewSpace4.OuterClass4 oc4 = new nspacemove_nestedPackage.NewSpace4.OuterClass4();
nspacemove_nestedPackage.OuterClass5 oc5 = new nspacemove_nestedPackage.OuterClass5();
nspacemove_nestedPackage.OuterClass6 oc6 = new nspacemove_nestedPackage.OuterClass6();
nspacemove_nestedPackage.OuterClass7 oc7 = new nspacemove_nestedPackage.OuterClass7();
nspacemove_nestedPackage.Space.OuterClass10 oc10 = new nspacemove_nestedPackage.Space.OuterClass10();
nspacemove_nestedPackage.Space.OuterClass20 oc20 = new nspacemove_nestedPackage.Space.OuterClass20();
nspacemove_nestedPackage.NewOkay30.OuterClass30 oc30 = new nspacemove_nestedPackage.NewOkay30.OuterClass30();
nspacemove_nestedPackage.NewOkay40.OuterClass40 oc40 = new nspacemove_nestedPackage.NewOkay40.OuterClass40();
nspacemove_nestedPackage.NewOkay50.OuterClass50 oc50 = new nspacemove_nestedPackage.NewOkay50.OuterClass50();
nspacemove_nestedPackage.OuterClass60 oc60 = new nspacemove_nestedPackage.OuterClass60();
nspacemove_nestedPackage.OuterClass70 oc70 = new nspacemove_nestedPackage.OuterClass70();
nspacemove_nestedPackage.Space.OuterClass80 oc80 = new nspacemove_nestedPackage.Space.OuterClass80();
// inner classes
nspacemove_nestedPackage.Space.OuterClass1.InnerClass1 ic1 = new nspacemove_nestedPackage.Space.OuterClass1.InnerClass1();
nspacemove_nestedPackage.Space.OuterClass2.InnerClass2 ic2 = new nspacemove_nestedPackage.Space.OuterClass2.InnerClass2();
nspacemove_nestedPackage.NewSpace3.OuterClass3.InnerClass3 ic3 = new nspacemove_nestedPackage.NewSpace3.OuterClass3.InnerClass3();
nspacemove_nestedPackage.NewSpace4.OuterClass4.InnerClass4 ic4 = new nspacemove_nestedPackage.NewSpace4.OuterClass4.InnerClass4();
nspacemove_nestedPackage.OuterClass5.InnerClass5 ic5 = new nspacemove_nestedPackage.OuterClass5.InnerClass5();
nspacemove_nestedPackage.OuterClass6.InnerClass6 ic6 = new nspacemove_nestedPackage.OuterClass6.InnerClass6();
nspacemove_nestedPackage.OuterClass7.InnerClass7 ic7 = new nspacemove_nestedPackage.OuterClass7.InnerClass7();
nspacemove_nestedPackage.Space.OuterClass10.InnerClass10 ic10 = new nspacemove_nestedPackage.Space.OuterClass10.InnerClass10();
nspacemove_nestedPackage.Space.OuterClass20.InnerClass20 ic20 = new nspacemove_nestedPackage.Space.OuterClass20.InnerClass20();
nspacemove_nestedPackage.NewOkay30.OuterClass30.InnerClass30 ic30 = new nspacemove_nestedPackage.NewOkay30.OuterClass30.InnerClass30();
nspacemove_nestedPackage.NewOkay40.OuterClass40.InnerClass40 ic40 = new nspacemove_nestedPackage.NewOkay40.OuterClass40.InnerClass40();
nspacemove_nestedPackage.NewOkay50.OuterClass50.InnerClass50 ic50 = new nspacemove_nestedPackage.NewOkay50.OuterClass50.InnerClass50();
nspacemove_nestedPackage.OuterClass60.InnerClass60 ic60 = new nspacemove_nestedPackage.OuterClass60.InnerClass60();
nspacemove_nestedPackage.OuterClass70.InnerClass70 ic70 = new nspacemove_nestedPackage.OuterClass70.InnerClass70();
nspacemove_nestedPackage.Space.OuterClass80.InnerClass80 ic80 = new nspacemove_nestedPackage.Space.OuterClass80.InnerClass80();
// inner enums
oc1.take(nspacemove_nestedPackage.Space.OuterClass1.InnerEnum1.ie1a, ic1);
oc2.take(nspacemove_nestedPackage.Space.OuterClass2.InnerEnum2.ie2a, ic2);
oc3.take(nspacemove_nestedPackage.NewSpace3.OuterClass3.InnerEnum3.ie3a, ic3);
oc4.take(nspacemove_nestedPackage.NewSpace4.OuterClass4.InnerEnum4.ie4a, ic4);
oc5.take(nspacemove_nestedPackage.OuterClass5.InnerEnum5.ie5a, ic5);
oc6.take(nspacemove_nestedPackage.OuterClass6.InnerEnum6.ie6a, ic6);
oc7.take(nspacemove_nestedPackage.OuterClass7.InnerEnum7.ie7a, ic7);
oc10.take(nspacemove_nestedPackage.Space.OuterClass10.InnerEnum10.ie10a, ic10);
oc20.take(nspacemove_nestedPackage.Space.OuterClass20.InnerEnum20.ie20a, ic20);
oc30.take(nspacemove_nestedPackage.NewOkay30.OuterClass30.InnerEnum30.ie30a, ic30);
oc40.take(nspacemove_nestedPackage.NewOkay40.OuterClass40.InnerEnum40.ie40a, ic40);
oc50.take(nspacemove_nestedPackage.NewOkay50.OuterClass50.InnerEnum50.ie50a, ic50);
oc60.take(nspacemove_nestedPackage.OuterClass60.InnerEnum60.ie60a, ic60);
oc70.take(nspacemove_nestedPackage.OuterClass70.InnerEnum70.ie70a, ic70);
oc80.take(nspacemove_nestedPackage.Space.OuterClass80.InnerEnum80.ie80a, ic80);
}
}

View File

@ -0,0 +1,86 @@
// This tests changes the package name from nspace to nspacePackage as javac can't seem to resolve classes and packages having the same name
public class nspacemove_runme {
static {
try {
System.loadLibrary("nspacemove");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
// constructors and destructors
nspacemovePackage.Ooter.Extra.Inner1.Color color1 = new nspacemovePackage.Ooter.Extra.Inner1.Color();
nspacemovePackage.Ooter.Extra.Inner1.Color color = new nspacemovePackage.Ooter.Extra.Inner1.Color(color1);
color1.delete();
color1 = null;
// class methods
color.colorInstanceMethod(20.0);
nspacemovePackage.Ooter.Extra.Inner1.Color.colorStaticMethod(20.0);
nspacemovePackage.Ooter.Extra.Inner1.Color created = nspacemovePackage.Ooter.Extra.Inner1.Color.create();
// class enums
nspacemovePackage.Outer.SomeClass someClass = new nspacemovePackage.Outer.SomeClass();
nspacemovePackage.Ooter.Extra.Inner1.Color.Channel channel = someClass.GetInner1ColorChannel();
if (channel != nspacemovePackage.Ooter.Extra.Inner1.Color.Channel.Transmission)
throw new RuntimeException("Transmission wrong");
// class anonymous enums
int val1 = nspacemovePackage.Ooter.Extra.Inner1.Color.ColorEnumVal1;
int val2 = nspacemovePackage.Ooter.Extra.Inner1.Color.ColorEnumVal2;
if (val1 != 0 || val2 != 0x22)
throw new RuntimeException("ColorEnumVal wrong");
// instance member variables
color.setInstanceMemberVariable(123);
if (color.getInstanceMemberVariable() != 123)
throw new RuntimeException("instance member variable failed");
// static member variables
nspacemovePackage.Ooter.Extra.Inner1.Color.setStaticMemberVariable(789);
if (nspacemovePackage.Ooter.Extra.Inner1.Color.getStaticMemberVariable() != 789)
throw new RuntimeException("static member variable failed");
if (nspacemovePackage.Ooter.Extra.Inner1.Color.staticConstMemberVariable != 222)
throw new RuntimeException("static const member variable failed");
if (nspacemovePackage.Ooter.Extra.Inner1.Color.staticConstEnumMemberVariable != nspacemovePackage.Ooter.Extra.Inner1.Color.Channel.Transmission)
throw new RuntimeException("static const enum member variable failed");
// Same class different namespaces
nspacemovePackage.Ooter.Extra.Inner1.Color col1 = new nspacemovePackage.Ooter.Extra.Inner1.Color();
nspacemovePackage.Outer.Snner2.Color col2 = nspacemovePackage.Outer.Snner2.Color.create();
col2.colors(col1, col1, col2, col2, col2);
// check globals in a namespace don't get mangled with the nspacemovePackage option
nspacemovePackage.nspacemove.namespaceFunction(color);
nspacemovePackage.nspacemove.setNamespaceVar(111);
if (nspacemovePackage.nspacemove.getNamespaceVar() != 111)
throw new RuntimeException("global var failed");
// global enums
nspacemovePackage.Euter.Extra.Inner1.Channel outerChannel1 = someClass.GetInner1Channel();
if (outerChannel1 != nspacemovePackage.Euter.Extra.Inner1.Channel.Transmission1)
throw new RuntimeException("Transmission1 wrong");
nspacemovePackage.Outer.Enner2.Channel outerChannel2 = someClass.GetInner2Channel();
if (outerChannel2 != nspacemovePackage.Outer.Enner2.Channel.Transmission2)
throw new RuntimeException("Transmission2 wrong");
nspacemovePackage.nspacemove.takeGlobalEnum(nspacemovePackage.More.GlobalEnum.bbb);
// global class
nspacemovePackage.Additional.GlobalClass gc = new nspacemovePackage.Additional.GlobalClass();
gc.gmethod();
// turn feature off / ignoring
nspacemovePackage.Outer.namespce ns = new nspacemovePackage.Outer.namespce();
nspacemovePackage.NoNSpacePlease nons = new nspacemovePackage.NoNSpacePlease();
// Derived class
nspacemovePackage.Outer.Inner3.Blue blue3 = new nspacemovePackage.Outer.Inner3.Blue();
blue3.blueInstanceMethod();
nspacemovePackage.Outer.Inner4.Blue blue4 = new nspacemovePackage.Outer.Inner4.Blue();
blue4.blueInstanceMethod();
}
}

View File

@ -0,0 +1,23 @@
public class nspacemove_stl_runme {
static {
try {
System.loadLibrary("nspacemove_stl");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
nspacemove_stlPackage.CPlusPlus.Standard.Ints.VectorInt vi = new nspacemove_stlPackage.CPlusPlus.Standard.Ints.VectorInt();
nspacemove_stlPackage.CPlusPlus.Standard.Strings.VectorString vs = new nspacemove_stlPackage.CPlusPlus.Standard.Strings.VectorString();
nspacemove_stlPackage.CPlusPlus.Maps.MapIntInt mii = new nspacemove_stlPackage.CPlusPlus.Maps.MapIntInt();
nspacemove_stlPackage.CPlusPlus.Maps.MapIntString mis = new nspacemove_stlPackage.CPlusPlus.Maps.MapIntString();
nspacemove_stlPackage.nspacemove_stl.test_vector_int(vi);
nspacemove_stlPackage.nspacemove_stl.test_vector_string(vs);
nspacemove_stlPackage.nspacemove_stl.test_map_int(mii);
nspacemove_stlPackage.nspacemove_stl.test_map_string(mis);
}
}

View File

@ -42,5 +42,10 @@ public class using_member_multiple_inherit_runme {
mb.multmethod("hi");
mb.multmethod(123, 234);
mb.multmethod(123, 345, 567);
// Multiple inheritance, with no override on parent class.
Vusing2 vu = new Vusing2();
vu.usingmethod(3);
vu.usingmethod("hi");
}
}

View File

@ -2,11 +2,9 @@ var char_binary = require("char_binary");
var t = new char_binary.Test();
if (t.strlen('hile') != 4) {
print(t.strlen('hile'));
throw("bad multi-arg typemap 1");
}
if (t.ustrlen('hile') != 4) {
print(t.ustrlen('hile'));
throw("bad multi-arg typemap 1");
}
@ -37,7 +35,6 @@ if (t.ustrlen(pc) != 4) {
char_binary.var_pchar = pc;
if (char_binary.var_pchar != "hola") {
print(char_binary.var_pchar);
throw("bad pointer case (1)");
}

View File

@ -3,16 +3,16 @@ var cpp17_nested_namespaces = require("cpp17_nested_namespaces");
new cpp17_nested_namespaces.A1Struct().A1Method()
new cpp17_nested_namespaces.B1Struct().B1Method()
new cpp17_nested_namespaces.C1Struct().C1Method()
new cpp17_nested_namespaces.createA1Struct().A1Method()
new cpp17_nested_namespaces.createB1Struct().B1Method()
new cpp17_nested_namespaces.createC1Struct().C1Method()
cpp17_nested_namespaces.createA1Struct().A1Method()
cpp17_nested_namespaces.createB1Struct().B1Method()
cpp17_nested_namespaces.createC1Struct().C1Method()
new cpp17_nested_namespaces.B2Struct().B2Method()
new cpp17_nested_namespaces.C2Struct().C2Method()
new cpp17_nested_namespaces.createB2Struct().B2Method()
new cpp17_nested_namespaces.createC2Struct().C2Method()
cpp17_nested_namespaces.createB2Struct().B2Method()
cpp17_nested_namespaces.createC2Struct().C2Method()
new cpp17_nested_namespaces.B3Struct().B3Method()
new cpp17_nested_namespaces.C3Struct().C3Method()
new cpp17_nested_namespaces.createB3Struct().B3Method()
new cpp17_nested_namespaces.createC3Struct().C3Method()
cpp17_nested_namespaces.createB3Struct().B3Method()
cpp17_nested_namespaces.createC3Struct().C3Method()

View File

@ -0,0 +1,13 @@
var inout = require("inout");
if (inout.AddOne1(1) != 2) {
throw new Error;
}
if (JSON.stringify(inout.AddOne3(1, 1, 1)) != JSON.stringify([2, 2, 2])) {
throw new Error;
}
if (JSON.stringify(inout.NonVoidOut(-42)) != JSON.stringify([null, 0])) {
throw new Error;
}

View File

@ -1,6 +1,10 @@
var li_cdata_cpp = require("li_cdata_cpp");
/* FIXME:
* Use null in middle of string
* Apple JSC JSStringCreateWithUTF8CString()
* usses null terminated string without length */
s = "ABC abc";
m = li_cdata_cpp.malloc(256);
li_cdata_cpp.memmove(m, s);

View File

@ -1,6 +1,10 @@
var li_cdata = require("li_cdata");
/* FIXME:
* Use null in middle of string
* Apple JSC JSStringCreateWithUTF8CString()
* usses null terminated string without length */
s = "ABC abc";
m = li_cdata.malloc(256);
li_cdata.memmove(m, s);

View File

@ -0,0 +1,55 @@
var nspacemove_nested = require("nspacemove_nested");
// outer classes
oc1 = new nspacemove_nested.Space.OuterClass1()
oc2 = new nspacemove_nested.Space.OuterClass2()
oc3 = new nspacemove_nested.NewSpace3.OuterClass3()
oc4 = new nspacemove_nested.NewSpace4.OuterClass4()
oc5 = new nspacemove_nested.OuterClass5()
oc6 = new nspacemove_nested.OuterClass6()
oc7 = new nspacemove_nested.OuterClass7()
oc10 = new nspacemove_nested.Space.OuterClass10()
oc20 = new nspacemove_nested.Space.OuterClass20()
oc30 = new nspacemove_nested.NewOkay30.OuterClass30()
oc40 = new nspacemove_nested.NewOkay40.OuterClass40()
oc50 = new nspacemove_nested.NewOkay50.OuterClass50()
oc60 = new nspacemove_nested.OuterClass60()
oc70 = new nspacemove_nested.OuterClass70()
oc80 = new nspacemove_nested.Space.OuterClass80()
// inner classes
ic1 = new nspacemove_nested.Space.InnerClass1()
ic2 = new nspacemove_nested.Space.InnerClass2()
ic3 = new nspacemove_nested.NewSpace3.InnerClass3()
ic4 = new nspacemove_nested.NewSpace4.InnerClass4()
ic5 = new nspacemove_nested.InnerClass5()
ic6 = new nspacemove_nested.InnerClass6()
ic7 = new nspacemove_nested.InnerClass7()
ic10 = new nspacemove_nested.Space.InnerClass10()
ic20 = new nspacemove_nested.Space.InnerClass20()
ic30 = new nspacemove_nested.NewOkay30.InnerClass30()
ic40 = new nspacemove_nested.NewOkay40.InnerClass40()
ic50 = new nspacemove_nested.NewOkay50.InnerClass50()
ic60 = new nspacemove_nested.InnerClass60()
ic70 = new nspacemove_nested.InnerClass70()
ic80 = new nspacemove_nested.Space.InnerClass80()
// inner enums
oc1.take(nspacemove_nested.Space.OuterClass1.ie1a, ic1)
oc2.take(nspacemove_nested.Space.OuterClass2.ie2a, ic2)
oc3.take(nspacemove_nested.NewSpace3.OuterClass3.ie3a, ic3)
oc4.take(nspacemove_nested.NewSpace4.OuterClass4.ie4a, ic4)
oc5.take(nspacemove_nested.OuterClass5.ie5a, ic5)
oc6.take(nspacemove_nested.OuterClass6.ie6a, ic6)
oc7.take(nspacemove_nested.OuterClass7.ie7a, ic7)
oc10.take(nspacemove_nested.Space.OuterClass10.ie10a, ic10)
oc20.take(nspacemove_nested.Space.OuterClass20.ie20a, ic20)
oc30.take(nspacemove_nested.NewOkay30.OuterClass30.ie30a, ic30)
oc40.take(nspacemove_nested.NewOkay40.OuterClass40.ie40a, ic40)
oc50.take(nspacemove_nested.NewOkay50.OuterClass50.ie50a, ic50)
oc60.take(nspacemove_nested.OuterClass60.ie60a, ic60)
oc70.take(nspacemove_nested.OuterClass70.ie70a, ic70)
oc80.take(nspacemove_nested.Space.OuterClass80.ie80a, ic80)

View File

@ -0,0 +1,85 @@
var nspacemove = require("nspacemove");
var color1 = new nspacemove.Ooter.Extra.Inner1.Color();
var color = new nspacemove.Ooter.Extra.Inner1.Color(color1);
delete color1;
// class methods
color.colorInstanceMethod(20.0);
nspacemove.Ooter.Extra.Inner1.Color.colorStaticMethod(20.0);
var created = nspacemove.Ooter.Extra.Inner1.Color.create();
// class enums
var someClass = new nspacemove.Outer.SomeClass();
var channel = someClass.GetInner1ColorChannel();
if (channel != nspacemove.Ooter.Extra.Inner1.Color.Transmission) {
throw new Error("Failed.");
}
// class anonymous enums
var val1 = nspacemove.Ooter.Extra.Inner1.Color.ColorEnumVal1;
var val2 = nspacemove.Ooter.Extra.Inner1.Color.ColorEnumVal2;
if (val1 !== 0 || val2 !== 0x22) {
throw new Error("Failed.");
}
// instance member variables
color.instanceMemberVariable = 123;
if (color.instanceMemberVariable !== 123) {
throw new Error("Failed.");
}
// static member variables
nspacemove.Ooter.Extra.Inner1.Color.staticMemberVariable = 789;
if (nspacemove.Ooter.Extra.Inner1.Color.staticMemberVariable !== 789) {
throw new Error("Failed.");
}
if (nspacemove.Ooter.Extra.Inner1.Color.staticConstMemberVariable !== 222) {
throw new Error("Failed.");
}
if (nspacemove.Ooter.Extra.Inner1.Color.staticConstEnumMemberVariable !== nspacemove.Ooter.Extra.Inner1.Color.Transmission) {
throw new Error("Failed.");
}
// Same class different namespaces
var col1 = new nspacemove.Ooter.Extra.Inner1.Color();
var col2 = nspacemove.Outer.Snner2.Color.create();
col2.colors(col1, col1, col2, col2, col2);
nspacemove.Outer.Inner1.namespaceFunction(color);
nspacemove.Outer.Inner1.namespaceVar = 111;
if (nspacemove.Outer.Inner1.namespaceVar !== 111) {
throw new Error("Failed.");
}
// global enums
var outerChannel1 = someClass.GetInner1Channel();
// TODO, broken:
if (outerChannel1 != nspacemove.Outer.Inner1.Transmission1) {
throw new Error("Failed.");
}
var outerChannel2 = someClass.GetInner2Channel();
// TODO, broken:
if (outerChannel2 !== nspacemove.Outer.Inner2.Transmission2) {
throw new Error("Failed.");
}
// TODO, broken
nspacemove.takeGlobalEnum(nspacemove.bbb);
// global class
var gc = new nspacemove.Additional.GlobalClass();
gc.gmethod();
// turn feature off / ignoring
var ns = new nspacemove.Outer.namespce();
var nons = new nspacemove.NoNSpacePlease();
// Derived class
var blue3 = new nspacemove.Outer.Inner3.Blue();
blue3.blueInstanceMethod();
var blue4 = new nspacemove.Outer.Inner4.Blue();
blue4.blueInstanceMethod();

View File

@ -0,0 +1,11 @@
var nspacemove_stl = require("nspacemove_stl");
vi = new nspacemove_stl.CPlusPlus.Standard.Ints.VectorInt()
vs = new nspacemove_stl.CPlusPlus.Standard.Strings.VectorString()
mii = new nspacemove_stl.CPlusPlus.Maps.MapIntInt()
mis = new nspacemove_stl.CPlusPlus.Maps.MapIntString()
nspacemove_stl.test_vector_int(vi)
nspacemove_stl.test_vector_string(vs)
nspacemove_stl.test_map_int(mii)
nspacemove_stl.test_map_string(mis)

View File

@ -31,7 +31,7 @@
SWIG_Object identity(SWIG_Object x) {
#ifdef SWIGPYTHON
Py_XINCREF(x);
Py_IncRef(x);
#endif
return x;
}

View File

@ -0,0 +1,46 @@
require("import") -- the import fn
import("char_binary") -- import lib
v = char_binary
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
t = v.Test()
assert(t:strlen("hile") == 4, "bad multi-arg typemap");
assert(t:ustrlen("hile") == 4, "bad multi-arg typemap");
assert(t:strlen("hil\0") == 4, "bad multi-arg typemap");
assert(t:ustrlen("hil\0") == 4, "bad multi-arg typemap");
-- creating a raw char*
pc = v.new_pchar(5);
v.pchar_setitem(pc, 0, 'h');
v.pchar_setitem(pc, 1, 'o');
v.pchar_setitem(pc, 2, 'l');
v.pchar_setitem(pc, 3, 'a');
v.pchar_setitem(pc, 4, 0);
-- FIXME: strlen except 'char const *' but pc is 'char *'
if false then
assert(t:strlen(pc) == 4, "bad multi-arg typemap");
assert(t:ustrlen(pc) == 4, "bad multi-arg typemap");
end
-- FIXME: expected 'pchar' got 'char *'
if false then
v.var_pchar = pc;
else
v.var_pchar = "hola";
end
assert(v.var_pchar == "hola", "bad pointer case");
-- FIXME: expected 'pchar' got 'char *'
if false then
v.var_namet = pc;
else
v.var_namet = "hola";
end
assert(v.var_namet == "hola", "bad pointer case");
v.delete_pchar(pc);

View File

@ -0,0 +1,16 @@
require("import") -- the import fn
import("li_cdata_cpp") -- import lib
v = li_cdata_cpp
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
s = "ABC\0abc";
m = v.malloc(256);
v.memmove(m, s);
ss = v.cdata(m, 7);
if ss ~= "ABC\0abc" then
error("failed")
end

View File

@ -0,0 +1,16 @@
require("import") -- the import fn
import("li_cdata") -- import lib
v = li_cdata
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
s = "ABC\0abc";
m = v.malloc(256);
v.memmove(m, s);
ss = v.cdata(m, 7);
if ss ~= "ABC\0abc" then
error("failed")
end

View File

@ -0,0 +1,61 @@
require("import") -- the import fn
import("nspacemove_nested") -- import lib
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
-- outer classes
oc1 = nspacemove_nested.Space.OuterClass1()
oc2 = nspacemove_nested.Space.OuterClass2()
oc3 = nspacemove_nested.NewSpace3.OuterClass3()
oc4 = nspacemove_nested.NewSpace4.OuterClass4()
oc5 = nspacemove_nested.OuterClass5()
oc6 = nspacemove_nested.OuterClass6()
oc7 = nspacemove_nested.OuterClass7()
oc10 = nspacemove_nested.Space.OuterClass10()
oc20 = nspacemove_nested.Space.OuterClass20()
oc30 = nspacemove_nested.NewOkay30.OuterClass30()
oc40 = nspacemove_nested.NewOkay40.OuterClass40()
oc50 = nspacemove_nested.NewOkay50.OuterClass50()
oc60 = nspacemove_nested.OuterClass60()
oc70 = nspacemove_nested.OuterClass70()
oc80 = nspacemove_nested.Space.OuterClass80()
-- inner classes
ic1 = nspacemove_nested.Space.InnerClass1()
ic2 = nspacemove_nested.Space.InnerClass2()
ic3 = nspacemove_nested.NewSpace3.InnerClass3()
ic4 = nspacemove_nested.NewSpace4.InnerClass4()
ic5 = nspacemove_nested.InnerClass5()
ic6 = nspacemove_nested.InnerClass6()
ic7 = nspacemove_nested.InnerClass7()
ic10 = nspacemove_nested.Space.InnerClass10()
ic20 = nspacemove_nested.Space.InnerClass20()
ic30 = nspacemove_nested.NewOkay30.InnerClass30()
ic40 = nspacemove_nested.NewOkay40.InnerClass40()
ic50 = nspacemove_nested.NewOkay50.InnerClass50()
ic60 = nspacemove_nested.InnerClass60()
ic70 = nspacemove_nested.InnerClass70()
ic80 = nspacemove_nested.Space.InnerClass80()
-- inner enums
oc1:take(nspacemove_nested.Space.OuterClass1.ie1a, ic1)
oc2:take(nspacemove_nested.Space.OuterClass2.ie2a, ic2)
oc3:take(nspacemove_nested.NewSpace3.OuterClass3.ie3a, ic3)
oc4:take(nspacemove_nested.NewSpace4.OuterClass4.ie4a, ic4)
oc5:take(nspacemove_nested.OuterClass5.ie5a, ic5)
oc6:take(nspacemove_nested.OuterClass6.ie6a, ic6)
oc7:take(nspacemove_nested.OuterClass7.ie7a, ic7)
oc10:take(nspacemove_nested.Space.OuterClass10.ie10a, ic10)
oc20:take(nspacemove_nested.Space.OuterClass20.ie20a, ic20)
oc30:take(nspacemove_nested.NewOkay30.OuterClass30.ie30a, ic30)
oc40:take(nspacemove_nested.NewOkay40.OuterClass40.ie40a, ic40)
oc50:take(nspacemove_nested.NewOkay50.OuterClass50.ie50a, ic50)
oc60:take(nspacemove_nested.OuterClass60.ie60a, ic60)
oc70:take(nspacemove_nested.OuterClass70.ie70a, ic70)
oc80:take(nspacemove_nested.Space.OuterClass80.ie80a, ic80)

View File

@ -0,0 +1,80 @@
require("import") -- the import fn
import("nspacemove") -- import lib
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
ns = nspacemove
-- Inheritance
blue1 = ns.Outer.Inner3.Blue()
-- blue1:blueInstanceMethod()
blue1:colorInstanceMethod(60.0)
blue1.instanceMemberVariable = 4
assert( blue1.instanceMemberVariable == 4 )
-- Constructors
color1 = ns.Ooter.Extra.Inner1.Color()
color2 = ns.Ooter.Extra.Inner1.Color.create()
color = ns.Ooter.Extra.Inner1.Color(color1)
color3 = ns.Outer.Snner2.Color.create()
color4 = ns.Outer.Snner2.Color.create()
color5 = ns.Outer.Snner2.Color.create()
mwp2 = ns.Outer.MyWorldPart2()
gc = ns.Additional.GlobalClass()
nnsp = ns.NoNSpacePlease()
-- Class methods
color:colorInstanceMethod(20.0)
ns.Ooter.Extra.Inner1.Color.colorStaticMethod(30.0)
color3:colorInstanceMethod(40.0)
ns.Outer.Snner2.Color.colorStaticMethod(50.0)
color3:colors(color1, color2, color3, color4, color5)
gc:gmethod()
-- Class variables
color.instanceMemberVariable = 5
color1.instanceMemberVariable = 7
assert( color.instanceMemberVariable == 5 )
assert( color1.instanceMemberVariable == 7 )
assert(ns.Ooter.Extra.Inner1.Color.staticMemberVariable == 0 )
assert(ns.Outer.Snner2.Color.staticMemberVariable == 0 )
ns.Ooter.Extra.Inner1.Color.staticMemberVariable = 9
ns.Outer.Snner2.Color.staticMemberVariable = 11
assert(ns.Ooter.Extra.Inner1.Color.staticMemberVariable == 9)
assert(ns.Outer.Snner2.Color.staticMemberVariable == 11)
-- Class constants
assert( ns.Ooter.Extra.Inner1.Color.Specular == 0x20 )
assert( ns.Outer.Snner2.Color.Specular == 0x40 )
assert( ns.Ooter.Extra.Inner1.Color.staticConstMemberVariable == 222 )
assert( ns.Outer.Snner2.Color.staticConstMemberVariable == 333 )
assert( ns.Ooter.Extra.Inner1.Color.staticConstEnumMemberVariable ~= ns.Outer.Snner2.Color.staticConstEnumMemberVariable )
-- Aggregation
sc = ns.Outer.SomeClass()
assert( sc:GetInner1ColorChannel() ~= sc:GetInner2Channel() )
assert( sc:GetInner1Channel() ~= sc:GetInner2Channel() )
-- Backward compatibility
assert(ns.Euter.Extra.Inner1.Diffuse ~= nil)
-- Enums within class within namespace shouldn't have backward compatible name. Same for static methods
assert(ns.Ooter.Extra.Inner1.Color_Diffuse == nil)
assert(ns.Ooter.Extra.Inner1.Color_colorStaticMethod == nil)
-- Enums and static methods of class marked as %nonspace should have backward compatible name
assert(ns.NoNSpacePlease_noNspaceStaticFunc() == 10)
assert(ns.Outer.Enner2.NoNSpacePlease_NoNspace == nil)
-- ReallyNoNSpaceEnum is wrapped into %nonspace and thus handled correctly.
-- NoNSpaceEnum is not (although both of them are in %nonspace-wrapped class) and thus
-- handled rather unexpectedly
assert(ns.NoNSpacePlease_ReallyNoNspace1 == 1)
assert(ns.NoNSpacePlease.ReallyNoNspace2 == 10)
ns.takeGlobalEnum(ns.More.bbb)

View File

@ -0,0 +1,18 @@
require("import") -- the import fn
import("nspacemove_stl") -- import lib
-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
vi = nspacemove_stl.CPlusPlus.Standard.Ints.VectorInt()
vs = nspacemove_stl.CPlusPlus.Standard.Strings.VectorString()
mii = nspacemove_stl.CPlusPlus.Maps.MapIntInt()
mis = nspacemove_stl.CPlusPlus.Maps.MapIntString()
nspacemove_stl.test_vector_int(vi)
nspacemove_stl.test_vector_string(vs)
nspacemove_stl.test_map_int(mii)
nspacemove_stl.test_map_string(mis)

View File

@ -87,7 +87,7 @@ namespace test {
%typemap(in) string_class * {
PyObject *bytes = NULL;
$1 = new string_class(SWIG_PyUnicode_AsUTF8AndSize($input, NULL, &bytes));
Py_XDECREF(bytes);
Py_DecRef(bytes);
}
%typemap(freearg) string_class * {
delete $1;

View File

@ -11,6 +11,7 @@ SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
%nspace;
%nonspace Outer::Inner2::NoNSpacePlease;
%nonspace Outer::Inner2::NoNSpacePlease::ReallyNoNSpaceEnum;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Outer::Inner2::NoNSpacePlease;
%copyctor;
%ignore Outer::Inner2::Color::Color();
@ -52,8 +53,8 @@ namespace Outer {
Color() : instanceMemberVariable(0) {}
static Color* create() { return new Color(); }
enum Channel { Diffuse, Specular = 0x40, Transmission };
enum { ColorEnumVal1, ColorEnumVal2 = 0x33, ColorEnumVal3 };
enum Channel { Diffuse, Specular = 0x40, Transmission, Channel4 };
enum { ColorEnumVal1, ColorEnumVal2 = 0x33, ColorEnumVal3, ColorEnumVal4 };
int instanceMemberVariable;
static int staticMemberVariable;
@ -106,6 +107,9 @@ struct GlobalClass {
void gmethod() {}
};
enum GlobalEnum { aaa, bbb, ccc };
void takeGlobalEnum(GlobalEnum) {}
void test_classes(Outer::SomeClass c, Outer::Inner2::Color cc) {}
%}

View File

@ -0,0 +1,15 @@
%module nspacemove
// Testing %nspacemove which moves symbols into a different target language 'namespace'
// move structs
%nspacemove(Ooter::Extra::Inner1) Outer::Inner1::Color;
%nspacemove(Outer::Snner2) Outer::Inner2::Color;
%nspacemove(Additional) ::GlobalClass;
// move enum
%nspacemove(Euter :: Extra :: Inner1) Outer::Inner1::Channel;
%nspacemove(Outer:: Enner2) Outer::Inner2::Channel;
%nspacemove(More) ::GlobalEnum;
%include "nspace.i"

View File

@ -0,0 +1,205 @@
%module nspacemove_nested
// Tests nested classes for badly configured %nspace, %nonspace, %nspacemove combinations
// Based off Examples/test-suite/errors/swig_nspacemove.i
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT)
#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
%feature ("flatnested");
#endif
// These will warn, hence suppressed in this testcase
// Note that these could also be suppressed at the outer class level, eg:
// %warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass1;
// Or even at namespace level:
// %warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass1::InnerClass1;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass2::InnerClass2;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass3::InnerClass3;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass4::InnerClass4;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass5::InnerClass5;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass6::InnerClass6;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass7::InnerClass7;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass1::InnerEnum1;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass2::InnerEnum2;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass3::InnerEnum3;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass4::InnerEnum4;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass5::InnerEnum5;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass6::InnerEnum6;
%warnfilter(SWIGWARN_TYPE_NSPACE_SETTING) Space::OuterClass7::InnerEnum7;
%nspace Space::OuterClass1;
%nspacemove(BadSpace1) Space::OuterClass1::InnerClass1;
%nspacemove(BadSpace1) Space::OuterClass1::InnerEnum1;
%nspace Space::OuterClass2;
%nonspace Space::OuterClass2::InnerClass2;
%nonspace Space::OuterClass2::InnerEnum2;
%nspacemove(NewSpace3) Space::OuterClass3;
%nspacemove(BadSpace3) Space::OuterClass3::InnerClass3;
%nspacemove(BadSpace3) Space::OuterClass3::InnerEnum3;
%nspacemove(NewSpace4) Space::OuterClass4;
%nonspace Space::OuterClass4::InnerClass4;
%nonspace Space::OuterClass4::InnerEnum4;
%nspacemove(NewSpace5) Space::OuterClass5::InnerClass5;
%nspacemove(NewSpace5) Space::OuterClass5::InnerEnum5;
%nonspace Space::OuterClass6;
%nspace Space::OuterClass6::InnerClass6;
%nspace Space::OuterClass6::InnerEnum6;
%nonspace Space::OuterClass7;
%nspacemove(NewSpace7) Space::OuterClass7::InnerClass7;
%nspacemove(NewSpace7) Space::OuterClass7::InnerEnum7;
%inline %{
namespace Space {
struct OuterClass1 {
struct InnerClass1 {
struct BottomClass1 {};
};
enum InnerEnum1 { ie1a, ie1b };
void take(InnerEnum1 e, InnerClass1 c) {}
};
struct OuterClass2 {
struct InnerClass2 {
struct BottomClass2 {};
};
enum InnerEnum2 { ie2a, ie2b };
void take(InnerEnum2 e, InnerClass2 c) {}
};
struct OuterClass3 {
struct InnerClass3 {
struct BottomClass3 {};
};
enum InnerEnum3 { ie3a, ie3b };
void take(InnerEnum3 e, InnerClass3 c) {}
};
struct OuterClass4 {
struct InnerClass4 {
struct BottomClass4 {};
};
enum InnerEnum4 { ie4a, ie4b };
void take(InnerEnum4 e, InnerClass4 c) {}
};
struct OuterClass5 {
struct InnerClass5 {
struct BottomClass5 {};
};
enum InnerEnum5 { ie5a, ie5b };
void take(InnerEnum5 e, InnerClass5 c) {}
};
struct OuterClass6 {
struct InnerClass6 {
struct BottomClass6 {};
};
enum InnerEnum6 { ie6a, ie6b };
void take(InnerEnum6 e, InnerClass6 c) {}
};
struct OuterClass7 {
struct InnerClass7 {
struct BottomClass7 {};
};
enum InnerEnum7 { ie7a, ie7b };
void take(InnerEnum7 e, InnerClass7 c) {}
};
}
%}
// These should not warn
%nspace Space::OuterClass10;
%nspace Space::OuterClass10::InnerClass10;
%nspace Space::OuterClass10::InnerEnum10;
%nspace Space::OuterClass20;
%clearnspace Space::OuterClass20::InnerClass20;
%clearnspace Space::OuterClass20::InnerEnum20;
%nspacemove(NewOkay30) Space::OuterClass30;
%nspace Space::OuterClass30::InnerClass30;
%nspace Space::OuterClass30::InnerEnum40;
%nspacemove(NewOkay40) Space::OuterClass40;
%clearnspace Space::OuterClass40::InnerClass40;
%clearnspace Space::OuterClass40::InnerEnum40;
%nspacemove(NewOkay50) Space::OuterClass50;
%nonspace Space::OuterClass60;
%nonspace Space::OuterClass60::InnerClass60;
%nonspace Space::OuterClass60::InnerEnum60;
%nonspace Space::OuterClass70;
%nspace Space::OuterClass80;
%inline %{
namespace Space {
struct OuterClass10 {
struct InnerClass10 {
struct BottomClass10 {};
};
enum InnerEnum10 { ie10a, ie10b };
void take(InnerEnum10 e, InnerClass10 c) {}
};
struct OuterClass20 {
struct InnerClass20 {
struct BottomClass20 {};
};
enum InnerEnum20 { ie20a, ie20b };
void take(InnerEnum20 e, InnerClass20 c) {}
};
struct OuterClass30 {
struct InnerClass30 {
struct BottomClass30 {};
};
enum InnerEnum30 { ie30a, ie30b };
void take(InnerEnum30 e, InnerClass30 c) {}
};
struct OuterClass40 {
struct InnerClass40 {
struct BottomClass40 {};
};
enum InnerEnum40 { ie40a, ie40b };
void take(InnerEnum40 e, InnerClass40 c) {}
};
struct OuterClass50 {
struct InnerClass50 {
struct BottomClass50 {};
};
enum InnerEnum50 { ie50a, ie50b };
void take(InnerEnum50 e, InnerClass50 c) {}
};
struct OuterClass60 {
struct InnerClass60 {
struct BottomClass60 {};
};
enum InnerEnum60 { ie60a, ie60b };
void take(InnerEnum60 e, InnerClass60 c) {}
};
struct OuterClass70 {
struct InnerClass70 {
struct BottomClass70 {};
};
enum InnerEnum70 { ie70a, ie70b };
void take(InnerEnum70 e, InnerClass70 c) {}
};
struct OuterClass80 {
struct InnerClass80 {
struct BottomClass80 {};
};
enum InnerEnum80 { ie80a, ie80b };
void take(InnerEnum80 e, InnerClass80 c) {}
};
}
%}
#endif

View File

@ -0,0 +1,31 @@
%module nspacemove_stl
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT)
#if defined(SWIGJAVA)
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
#endif
// %nspacemove needed before %include std_vector.i, std_map.i etc so that this nspace targetting the template is attached to the template node
%nspacemove(CPlusPlus::Maps) std::map;
%include <stl.i>
// %nspacemove needed at least before instantiation of the templates
%nspacemove(CPlusPlus::Standard::Ints) std::vector<int>;
%nspacemove(CPlusPlus::Standard::Strings) std::vector<std::string>;
%template(VectorInt) std::vector<int>;
%template(VectorString) std::vector<std::string>;
%template(MapIntInt) std::map<int, int>;
%template(MapIntString) std::map<int, std::string>;
%inline %{
void test_vector_int(std::vector<int> a) {}
void test_vector_string(std::vector<std::string> a) {}
void test_map_int(std::map<int, int> a) {}
void test_map_string(std::map<int, std::string> a) {}
%}
#endif

View File

@ -0,0 +1,45 @@
director_binary_string
function self=DirectorBinaryStringCallback()
global director_binary_string;
self=subclass(director_binary_string.Callback());
self.run=@DirectorBinaryStringCallback_run;
self.writeData=@DirectorBinaryStringCallback_writeData;
end
function ret=DirectorBinaryStringCallback_run(self, dataBufferAA, dataBufferBB)
ret = 0;
for i = 1:length(dataBufferAA)
ret = ret + double(dataBufferAA(i)) * 2;
end
for i = 1:length(dataBufferBB)
ret = ret + double(dataBufferBB(i)) * 3;
end
end
function ret=DirectorBinaryStringCallback_writeData(self, dataBufferAA)
ret = 0;
for i = 1:length(dataBufferAA)
ret = ret + double(dataBufferAA(i)) * 2;
end
end
caller = director_binary_string.Caller();
callback = DirectorBinaryStringCallback();
caller.setCallback(callback);
sum = caller.call();
sumData = caller.callWriteData();
caller.delCallback();
if (sum != 9*2*8 + 13*3*5)
error(sum);
end
if (sumData != 9*2*8)
error(sumData);
end
% FIXME how do we create null string?
% director_binary_string.Callback().run(null, null);
director_binary_string.Callback().run('', '');
callback = DirectorBinaryStringCallback();
caller.setCallback(callback);
caller.call_null();
caller.delCallback();

View File

@ -0,0 +1,10 @@
li_cdata_cpp
s = "ABC\000abc";
m = li_cdata_cpp.malloc(256);
li_cdata_cpp.memmove(m, s);
ss = li_cdata_cpp.cdata(m, 7);
if (ss != "ABC\000abc")
disp(ss);
error("failed");
endif

View File

@ -0,0 +1,10 @@
li_cdata
s = "ABC\000abc";
m = li_cdata.malloc(256);
li_cdata.memmove(m, s);
ss = li_cdata.cdata(m, 7);
if (ss != "ABC\000abc")
disp(ss);
error("failed");
endif

View File

@ -0,0 +1,50 @@
use strict;
use warnings;
use Test::More tests => 4;
BEGIN { use_ok 'director_binary_string' }
require_ok 'director_binary_string';
{
package DirectorBinaryStringCallback;
use base 'director_binary_string::Callback';
sub run {
my $ret = 0;
my ($self, $dataBufferAA, $dataBufferBB) = @_;
if(defined $dataBufferAA) {
$ret += ord($_) * 2 for(split('', $dataBufferAA));
}
if(defined $dataBufferBB) {
$ret += ord($_) * 3 for(split('', $dataBufferBB));
}
return $ret;
}
sub writeData {
my $ret = 0;
my ($self, $dataBufferAA) = @_;
if(defined $dataBufferAA) {
$ret += ord($_) * 2 for(split('', $dataBufferAA));
}
return $ret;
}
}
{
print "Start\n";
my $caller = director_binary_string::Caller->new();
my $callback = DirectorBinaryStringCallback->new();
$caller->setCallback($callback);
my $sum = $caller->call();
my $sumData = $caller->callWriteData();
$caller->delCallback();
is($sum, 9*2*8 + 13*3*5, 'Unexpected sum: ' . $sum);
is($sumData, 9*2*8, 'Unexpected sumData: ' . $sumData);
# FIXME accessing abstract class or protected constructor
# It does make sense as writeData() is abstract
# director_binary_string::Callback->new()->run(undef, undef);
$callback = DirectorBinaryStringCallback->new();
$caller->setCallback($callback);
$caller->call_null();
$caller->delCallback();
}

View File

@ -0,0 +1,11 @@
use strict;
use warnings;
use Test::More tests => 3;
BEGIN { use_ok('li_cdata_cpp') }
require_ok('li_cdata_cpp');
my $s = "ABC\x00abc";
my $m = li_cdata_cpp::malloc(256);
li_cdata_cpp::memmove($m, $s);
my $ss = li_cdata_cpp::cdata($m, 7);
is($ss, "ABC\x00abc", "failed");

View File

@ -0,0 +1,11 @@
use strict;
use warnings;
use Test::More tests => 3;
BEGIN { use_ok('li_cdata') }
require_ok('li_cdata');
my $s = "ABC\x00abc";
my $m = li_cdata::malloc(256);
li_cdata::memmove($m, $s);
my $ss = li_cdata::cdata($m, 7);
is($ss, "ABC\x00abc", "failed");

View File

@ -26,14 +26,24 @@ pchar_setitem($pc, 4, 0);
if (0) {
check::equal($t->strlen($pc), 4, "bad multi-arg typemap");
check::equal($t->ustrlen($pc), 4, "bad multi-arg typemap");
var_pchar_set($pc);
check::equal(var_pchar_get(), "hola", "bad pointer case");
var_namet_set($pc);
check::equal(var_namet_get(), "hola", "bad pointer case");
}
// FIXME: Cannot convert pc to string
if (0) {
var_pchar_set($pc);
} else {
var_pchar_set("hola");
}
check::equal(var_pchar_get(), "hola", "bad pointer case");
// FIXME: Cannot convert pc to string
if (0) {
var_namet_set($pc);
} else {
var_namet_set("hola");
}
check::equal(var_namet_get(), "hola", "bad pointer case");
delete_pchar($pc);
check::done();

Some files were not shown because too many files have changed in this diff Show More