Merge branch 'master' into C

This commit is contained in:
Olly Betts 2024-09-11 16:26:07 +12:00
commit eff3d2225e
117 changed files with 1950 additions and 729 deletions

View File

@ -153,6 +153,10 @@ jobs:
- SWIGLANG: python
VER: '3.12'
CSTD: gnu99
- SWIGLANG: python
VER: '3.13'
CSTD: gnu99
continue-on-error: true # Python 3.13 is still in beta
- SWIGLANG: python
PY2: 2
SWIG_FEATURES: -builtin
@ -501,6 +505,18 @@ jobs:
# dependencies.
unset SWIGJOBS
;;
scilab)
case $VER in
""|6.*|2023.*|2024.0.*)
# Some older versions of scilab sporadically fail with:
# terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
# #2942 says "this issue was fixed in Scilab 2024.1.0"
# and that it was probably introduced in 6.x (we've
# seen it with 6.1.0.0, but haven't with 5.x).
unset SWIGJOBS
;;
esac
;;
esac
# Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic.

View File

@ -55,10 +55,14 @@ jobs:
- SWIGLANG: java
COMPILER: gcc
VER: 11
# Next two are using old VC++ as the new visual c++ not handling containers of enums
# See https://github.com/swig/swig/issues/3008
- SWIGLANG: python
VER: '3.7'
os: 'windows-2019'
- SWIGLANG: python
VER: '3.12'
os: 'windows-2019'
# TODO require fixing of probing in configure.ac
#- SWIGLANG: python
# INSTALL: 'true'

View File

@ -7,6 +7,105 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.3.0 (in progress)
===========================
2024-09-07: wsfulton
#2875 Fix swig-4.1.0 regression using the %interface family of macros
for multiple inheritance and common bases.
2024-09-06: olly
[Python] Stop documenting to define SWIG_FILE_WITH_INIT - this does
not actually do anything (and apparently never has!)
2024-09-05: wsfulton
#2845 Fix duplicate friend wrappers for friend declarations in nested
classes.
2024-09-03: olly
#3010 Improve handling of zero bytes in input files. This is
certainly a corner case, but GCC and clang both accept zero bytes
at least in comments, and SWIG's current handling is to ignore
the zero byte and all following characters up to and including the
next newline, so for example if a // comment contains a zero byte
SWIG would quietly ignore the next line.
2024-08-30: olly
#2996 Fix generic string literal handling to handle embedded zero
bytes. This allows such strings to work for C# (with %csconst), D
(with %dmanifestconst), Go and Java (with %javaconst). For other
target languages SWIG-generated wrappers still truncate such string
literals at a zero byte (which is probably the best we can do for
target languages where the native string can't contain zero bytes).
2024-08-23: wsfulton
[Java] #2991 Document solutions for mismatch in C++ access specifiers
and Java access modifiers in an inheritance hierarchy.
2024-08-19: wsfulton
[Python] #2993 Add missing std::filesystem namespace to std_filesystem.i.
2024-08-17: olly
#904 #1907 #2579 Fix string literal and character literal wrapping bugs.
2024-08-15: olly
Fix parsing of octal string escapes. We now stop when the next
character is digit 8 or 9, and stop after 3 octal digits even if
the next character is an octal digit.
2024-08-15: olly
SWIG now gives an error for digits 8 and 9 in octal constants -
previously these were quietly accepted resulting in a bogus value.
C++11 binary constants are now treated similarly - only digits 0
and 1 were allowed before, but trying to use other digits now gives
a clearer error.
2024-08-12: olly
#657 Allow unmatched ' and " in #error and #warning.
2024-08-09: wsfulton
[Java] Add the constantsmodifiers pragma so that the visibility for the
Java constants interface can be changed from public to default.
2024-08-02: vadz
[Python] #2966 Fix overloaded Doxygen comments. Sometimes the Doxygen
comments were not combined into one Pydoc comment.
2024-08-01: olly
Fix wrapping of string constants containing bytes 0-8, 11, 12 or
14-31 followed by a digit '0' to '7'. We were emitting these bytes
as a one or two character octal escape sequence which when
interpreted would include the following character.
2024-07-27: olly
#2087 Fix parsing of `noexcept` on a function pointer type used
as the type of a function parameter. We currently generate
invalid C++ code if we try to wrap the function parameter, but
at least the user can `%ignore` the parameter or the whole
function, whereas the parse error was hard to work around.
2024-07-26: olly
Support parsing `noexcept(X)` in expressions, including deducing
its type (which is always `bool`).
2024-07-21: wsfulton
[Python] Add missing slot for init in struct _specialization_cache
needed for python-3.13 builtin wrappers.
2024-07-21: shadchin
[Python] #2968 Add missing tp_versions_used slot needed for python-3.13.
2024-07-19: olly
-Wallkw now includes keywords for Javascript.
2024-07-19: vadz
[Javascript] #2940 Names of object properties can be keywords in
Javascript so don't auto-rename them to have a leading underscore.
2024-07-18: olly
#1917 Stop removing `f` and `F` suffixes from float literals.
This was resulting in incorrect generated C# and Java code. For
some cases such as `#define CONSTANT 1.0f` this was a regression
introduced in 4.2.0 when we started more correctly wrapping these
as `float` rather than `double`.
2024-07-15: vadz
#2941 Suppress warning WARN_PARSE_USING_UNDEF for ignored using declarations.

View File

@ -43,6 +43,7 @@
<ul>
<li><a name="i7.1" href="#7.1">7.1 Debugging DOH Types The Hard Way</a>
<li><a name="i7.2" href="#7.2">7.2 Debugging DOH memory allocation problems</a>
<li><a name="i7.3" href="#7.3">7.3 Further debugging information</a>
</ul>
</ul>
@ -1226,10 +1227,21 @@ Fatal internal error: Attempt to delete a non-DOH object.
<p>
This can be memory intensive as previously used memory in the pool is not re-used so is
only recommended for diagnosing memory corruption problems.
The valgrind tool is commonly used for debugging memory problems and <tt>DOH_DEBUG_MEMORY_POOLS</tt>
should also be defined when using valgrind.
</p>
<a name="7.3" href="#i7.3">
<h3>7.3 Further debugging information</h3>
</a>
<p>
There is also useful practical information about debugging SWIG in the <i>Extending SWIG to support new languages</i> chapter in the main documentation manual.
</p>
<hr>
Copyright (C) 1999-2022 SWIG Development Team.
Copyright (C) 1999-2024 SWIG Development Team.
</body>
</html>

View File

@ -94,7 +94,7 @@
<li><a href="Windows.html#Windows_swig_exe">Building swig.exe on Windows</a>
<ul>
<li><a href="Windows.html#Windows_cmake">Building swig.exe using CMake</a>
<li><a href="Windows.html#Windows_msys2">Building swig.exe using MSYS2</a>
<li><a href="Windows.html#Windows_msys2">Building swig.exe using MSYS2 and MinGW-w64</a>
<li><a href="Windows.html#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</a>
<li><a href="Windows.html#Windows_cygwin">Building swig.exe using Cygwin</a>
<ul>
@ -1054,6 +1054,10 @@
<ul>
<li><a href="Java.html#Java_module_class_pragmas">The Java module class pragmas</a>
</ul>
<li><a href="Java.html#Java_constants_interface">The Java constants interface</a>
<ul>
<li><a href="Java.html#Java_constants_interface_pragmas">The Java constants interface pragmas</a>
</ul>
<li><a href="Java.html#Java_proxy_classes">Java proxy classes</a>
<ul>
<li><a href="Java.html#Java_memory_management">Memory management</a>
@ -1083,8 +1087,9 @@
<ul>
<li><a href="Java.html#Java_customizing_director_exceptions">Customizing director exceptions</a>
</ul>
<li><a href="Java.html#Java_protected_virtual_methods">Accessing virtual protected methods</a>
<li><a href="Java.html#Java_allprotected">Accessing non-virtual protected members</a>
</ul>
<li><a href="Java.html#Java_allprotected">Accessing protected members</a>
<li><a href="Java.html#Java_common_customization">Common customization features</a>
<ul>
<li><a href="Java.html#Java_helper_functions">C/C++ helper functions</a>

View File

@ -3507,7 +3507,9 @@ make ret_by_value.ctest RUNTOOL="valgrind --leak-check=full"
<p>
This will probably make more sense if you look at the output of the above as it will show the exact commands being executed.
SWIG can be analyzed for bad memory accesses using:
SWIG can be analyzed for bad memory by first rebuilding swig with just the <tt>-g</tt> option.
Also define DOH_DEBUG_MEMORY_POOLS, see <a href="#Extending_further_info"></a> section.
SWIG can then be invoked via valgrind using:
</p>
<div class="shell"><pre>

View File

@ -288,10 +288,10 @@ build a Tcl module (under Linux) as follows :
</p>
<div class="shell"><pre>
unix &gt; <b>swig -tcl example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o example.so</b>
unix &gt; <b>tclsh</b>
$ <b>swig -tcl example.i</b>
$ <b>gcc -c -fPIC example.c example_wrap.c -I/usr/include/tcl8.7</b>
$ <b>gcc -shared example.o example_wrap.o -o example.so</b>
$ <b>tclsh</b>
% <b>load ./example.so</b>
% <b>fact 4</b>
24
@ -342,17 +342,16 @@ unix &gt;
<p>
Finally, let's build a module for Python (shown for Irix).
Finally, let's build a module for Python (shown for Linux).
</p>
<div class="shell"><pre>
unix &gt; <b>swig -python example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o _example.so</b>
unix &gt; <b>python</b>
Python 2.0 (#6, Feb 21 2001, 13:29:45)
[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Type "copyright", "credits" or "license" for more information.
$ <b>swig -python example.i</b>
$ <b>gcc -c -fPIC example.c example_wrap.c -I/usr/include/python3.12</b>
$ <b>gcc -shared example.o example_wrap.o -o _example.so</b>
$ <b>python3</b>
Python 3.12.4 (main, Jun 12 2024, 19:06:53) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; <b>import example</b>
&gt;&gt;&gt; <b>example.fact(4)</b>
24

View File

@ -68,6 +68,10 @@
<ul>
<li><a href="#Java_module_class_pragmas">The Java module class pragmas</a>
</ul>
<li><a href="#Java_constants_interface">The Java constants interface</a>
<ul>
<li><a href="#Java_constants_interface_pragmas">The Java constants interface pragmas</a>
</ul>
<li><a href="#Java_proxy_classes">Java proxy classes</a>
<ul>
<li><a href="#Java_memory_management">Memory management</a>
@ -97,8 +101,9 @@
<ul>
<li><a href="#Java_customizing_director_exceptions">Customizing director exceptions</a>
</ul>
<li><a href="#Java_protected_virtual_methods">Accessing virtual protected methods</a>
<li><a href="#Java_allprotected">Accessing non-virtual protected members</a>
</ul>
<li><a href="#Java_allprotected">Accessing protected members</a>
<li><a href="#Java_common_customization">Common customization features</a>
<ul>
<li><a href="#Java_helper_functions">C/C++ helper functions</a>
@ -501,8 +506,8 @@ compiler. For example:
<div class="code"><pre>
% swig -c++ -java example.i
% g++ -c -fpic example.cxx
% g++ -c -fpic example_wrap.cxx -I/usr/java/j2sdk1.4.1/include -I/usr/java/j2sdk1.4.1/include/linux
% g++ -c -fPIC example.cxx
% g++ -c -fPIC example_wrap.cxx -I/usr/java/j2sdk1.4.1/include -I/usr/java/j2sdk1.4.1/include/linux
% g++ -shared example.o example_wrap.o -o libexample.so
</pre></div>
@ -1627,6 +1632,11 @@ Note that Java does not support multiple inheritance so any multiple inheritance
A warning is given when multiple inheritance is detected and only the first base class is used.
</p>
<p>
Private and protected methods are not wrapped as they are inaccessible outside of the class.
Protected methods can be made accessible though via the directors feature, see the <a href="#Java_protected_virtual_methods">Accessing virtual protected methods</a> in the directors section.
</p>
<H3><a name="Java_pointers_refs_arrays">27.3.10 Pointers, references, arrays and pass by value</a></H3>
@ -2399,8 +2409,70 @@ The pragma code appears in the generated module class like this:
See <a href="#Java_imclass_pragmas">The intermediary JNI class pragmas</a> section for further details on using pragmas.
</p>
<H3><a name="Java_constants_interface">27.4.3 The Java constants interface</a></H3>
<H3><a name="Java_proxy_classes">27.4.3 Java proxy classes</a></H3>
<p>
C/C++ constants are generated as final static members in a constants interface as mentioned in the <a href="#Java_constants">Constants</a> section, such as the example in this section:
</p>
<div class="code"><pre>
public interface exampleConstants {
public final static int EXPRESSION = (0x100+5);
public final static long BIG = exampleJNI.BIG_get();
public final static java.math.BigInteger LARGE = exampleJNI.LARGE_get();
}
</pre></div>
<p>
C/C++ enums can also be generated into the same constants interface as described in the <a href="#Java_enumerations">Enumerations</a> section.
</p>
<H4><a name="Java_constants_interface_pragmas">27.4.3.1 The Java constants interface pragmas</a></H4>
<p>
Scope for tailoring the generated interface is limited to one pragma, in the same manner as the intermediary JNI class pragmas and module class pragmas. The pragma details are:
</p>
<table BORDER summary="Java constants interface pragmas">
<tr VALIGN=TOP>
<td><b>Pragma</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td>constantsmodifiers </td> <td>Class modifiers and class type for the constants interface, defaults to <tt>public interface</tt></td>
</tr>
</table>
<p>
The pragma code appears in the generated constants interface like this:
</p>
<div class="code">
<pre>
[ constantsmodifiers pragma ] constantsname {
... SWIG generated final static variables ...
}
</pre>
</div>
<p>
where <tt>constantsname</tt> is a name created by concatenating the module name and <tt>Constants</tt>, for example, <tt>exampleConstants</tt> for a module named <tt>example</tt>.
</p>
<p>
The only real use for this pragma is to change the visibility from public to default with:
</p>
<div class="code">
<pre>
%pragma(java) constantsmodifiers="interface"
</pre>
</div>
<H3><a name="Java_proxy_classes">27.4.4 Java proxy classes</a></H3>
<p>
@ -2476,7 +2548,7 @@ int y = f.spam(5, new Foo());
</pre>
</div>
<H4><a name="Java_memory_management">27.4.3.1 Memory management</a></H4>
<H4><a name="Java_memory_management">27.4.4.1 Memory management</a></H4>
<p>
@ -2638,7 +2710,7 @@ and
</p>
<H4><a name="Java_inheritance_mirroring">27.4.3.2 Inheritance</a></H4>
<H4><a name="Java_inheritance_mirroring">27.4.4.2 Inheritance</a></H4>
<p>
@ -2754,7 +2826,7 @@ However, true cross language polymorphism can be achieved using the <a href="#Ja
</p>
<H4><a name="Java_proxy_classes_gc">27.4.3.3 Proxy classes and garbage collection</a></H4>
<H4><a name="Java_proxy_classes_gc">27.4.4.3 Proxy classes and garbage collection</a></H4>
<p>
@ -2837,7 +2909,7 @@ The section on <a href="#Java_typemaps">Java typemaps</a> details how to specify
See the <a href="http://www.devx.com/Java/Article/30192">How to Handle Java Finalization's Memory-Retention Issues</a> article for alternative approaches to managing memory by avoiding finalizers altogether.
</p>
<H4><a name="Java_pgcpp">27.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling</a></H4>
<H4><a name="Java_pgcpp">27.4.4.4 The premature garbage collection prevention parameter for proxy class marshalling</a></H4>
<p>
@ -2959,7 +3031,7 @@ For example:
<b>Compatibility note:</b> The generation of this additional parameter did not occur in versions prior to SWIG-1.3.30.
</p>
<H4><a name="Java_multithread_libraries">27.4.3.5 Single threaded applications and thread safety</a></H4>
<H4><a name="Java_multithread_libraries">27.4.4.5 Single threaded applications and thread safety</a></H4>
<p>
@ -3047,7 +3119,7 @@ for (int i=0; i&lt;100000; i++) {
</pre></div>
<H3><a name="Java_type_wrapper_classes">27.4.4 Type wrapper classes</a></H3>
<H3><a name="Java_type_wrapper_classes">27.4.5 Type wrapper classes</a></H3>
<p>
@ -3134,7 +3206,7 @@ public static void spam(SWIGTYPE_p_int x, SWIGTYPE_p_int y, int z) { ... }
</div>
<H3><a name="Java_enum_classes">27.4.5 Enum classes</a></H3>
<H3><a name="Java_enum_classes">27.4.6 Enum classes</a></H3>
<p>
@ -3143,7 +3215,7 @@ The <a href="#Java_enumerations">Enumerations</a> section discussed these but om
The following sub-sections detail the various types of enum classes that can be generated.
</p>
<H4><a name="Java_typesafe_enums_classes">27.4.5.1 Typesafe enum classes</a></H4>
<H4><a name="Java_typesafe_enums_classes">27.4.6.1 Typesafe enum classes</a></H4>
<p>
@ -3227,7 +3299,7 @@ The <tt>swigValue</tt> method is used for marshalling in the other direction.
The <tt>toString</tt> method is overridden so that the enum name is available.
</p>
<H4><a name="Java_proper_enums_classes">27.4.5.2 Proper Java enum classes</a></H4>
<H4><a name="Java_proper_enums_classes">27.4.6.2 Proper Java enum classes</a></H4>
<p>
@ -3305,7 +3377,7 @@ These needn't be generated if the enum being wrapped does not have any initializ
<a href="#Java_simpler_enum_classes">Simpler Java enums for enums without initializers</a> section describes how typemaps can be used to achieve this.
</p>
<H4><a name="Java_typeunsafe_enums_classes">27.4.5.3 Type unsafe enum classes</a></H4>
<H4><a name="Java_typeunsafe_enums_classes">27.4.6.3 Type unsafe enum classes</a></H4>
<p>
@ -3336,7 +3408,7 @@ public final class Beverage {
</pre>
</div>
<H3><a name="Java_interfaces">27.4.6 Interfaces</a></H3>
<H3><a name="Java_interfaces">27.4.7 Interfaces</a></H3>
<p>
@ -4472,14 +4544,97 @@ Exception in thread "main" java.lang.IndexOutOfBoundsException: Index is negativ
</pre>
</div>
<H2><a name="Java_allprotected">27.6 Accessing protected members</a></H2>
<H3><a name="Java_protected_virtual_methods">27.5.8 Accessing virtual protected methods</a></H3>
<p>
When using directors, the protected virtual methods are also wrapped.
By default, without enabling the director feature, protected methods are not wrapped and so cannot be accessed from Java.
When using directors, the protected virtual methods are wrapped.
These methods are wrapped with a protected Java proxy method, so the only way that Java code can access these is from within a Java class derived from the director class.
</p>
<p>
Unfortunately the rules for classes in an inheritance chain when changing the access specifiers in C++ are different to Java access modifiers.
They are similar, but, unlike in C+++, one cannot assign weaker access modifiers in Java.
Consider the following inheritance chain and using directors to turn on wrapping protected methods:
</p>
<div class="code">
<pre>
%feature("director") BaseClass;
%feature("director") DerivedClass;
%inline %{
class BaseClass {
public:
virtual ~BaseClass();
virtual void baseMethod1();
virtual void baseMethod2();
protected:
virtual void baseMethod3();
virtual void baseMethod4();
};
class DerivedClass : public BaseClass {
public:
virtual ~DerivedClass();
virtual void baseMethod1();
protected:
virtual void baseMethod2();
virtual void baseMethod3();
public:
virtual void baseMethod4();
};
%}
</pre>
</div>
<p>
SWIG will generate Java access modifiers that are a one-to-one mapping of the C++ access specifiers.
So if a method is <tt>public</tt> in C++ it will also be <tt>public</tt> in Java, and similarly <tt>protected</tt> in C++ becomes <tt>protected</tt> in Java.
This is fine for all of the methods in the above example, except for the <tt>DerivedClass.baseMethod2</tt>.
The Java compiler issues an error:
</p>
<div class="shell">
<pre>
DerivedClass.java:69: error: baseMethod2() in DerivedClass cannot override baseMethod2() in BaseClass
protected void baseMethod2() {
^
attempting to assign weaker access privileges; was public
</pre>
</div>
<p>
This requires fixing with one of two solutions:
</p>
<ol>
<p>
<li>Change the access modifier to public for the derived class by adding the following before SWIG parses the <tt>DerivedClass</tt>:</li>
</p>
<div class="code">
<pre>
%feature("java:methodmodifiers") DerivedClass::baseMethod2 "public"
</pre>
</div>
<p>
<li>Simply ignore the method in the derived class altogether as it cannot be used as a <tt>protected</tt> method in Java as the C++ design intended:</li>
</p>
<div class="code">
<pre>
%ignore DerivedClass::baseMethod2;
</pre>
</div>
</ol>
<H3><a name="Java_allprotected">27.5.9 Accessing non-virtual protected members</a></H3>
<p>
Members which are protected and non-virtual can also be accessed when using the 'allprotected' mode.
The allprotected mode requires directors and is turned on by setting the <tt>allprotected</tt> option in addition to the <tt>directors</tt> option in the %module directive, like this:
@ -4568,7 +4723,7 @@ class MyProtectedBase extends ProtectedBase
<H2><a name="Java_common_customization">27.7 Common customization features</a></H2>
<H2><a name="Java_common_customization">27.6 Common customization features</a></H2>
<p>
@ -4580,7 +4735,7 @@ be awkward. This section describes some common SWIG features that are used
to improve the interface to existing C/C++ code.
</p>
<H3><a name="Java_helper_functions">27.7.1 C/C++ helper functions</a></H3>
<H3><a name="Java_helper_functions">27.6.1 C/C++ helper functions</a></H3>
<p>
@ -4646,7 +4801,7 @@ hard to implement. It is possible to improve on this using Java code, typemaps,
customization features as covered in later sections, but sometimes helper functions are a quick and easy solution to difficult cases.
</p>
<H3><a name="Java_class_extension">27.7.2 Class extension with %extend</a></H3>
<H3><a name="Java_class_extension">27.6.2 Class extension with %extend</a></H3>
<p>
@ -4709,7 +4864,7 @@ Vector(2, 3, 4)
in any way---the extensions only show up in the Java interface.
</p>
<H3><a name="Java_proxycode">27.7.3 Class extension with %proxycode</a></H3>
<H3><a name="Java_proxycode">27.6.3 Class extension with %proxycode</a></H3>
<p>
@ -4846,7 +5001,7 @@ public class ValueUnsignedInt {
</pre>
</div>
<H3><a name="Java_exception_handling">27.7.4 Exception handling with %exception and %javaexception</a></H3>
<H3><a name="Java_exception_handling">27.6.4 Exception handling with %exception and %javaexception</a></H3>
<p>
@ -5005,7 +5160,7 @@ to raise exceptions. See the <a href="Library.html#Library">SWIG Library</a> ch
The typemap example <a href="#Java_exception_typemap">Handling C++ exception specifications as Java exceptions</a> provides further exception handling capabilities.
</p>
<H3><a name="Java_method_access">27.7.5 Method access with %javamethodmodifiers</a></H3>
<H3><a name="Java_method_access">27.6.5 Method access with %javamethodmodifiers</a></H3>
<p>
@ -5031,7 +5186,7 @@ protected static void protect_me() {
</pre>
</div>
<H3><a name="Java_begin">27.7.6 Java begin</a></H3>
<H3><a name="Java_begin">27.6.6 Java begin</a></H3>
<p>
@ -5050,7 +5205,7 @@ a common comment into all generated .java files. For example, copyright text for
</div>
<H2><a name="Java_tips_techniques">27.8 Tips and techniques</a></H2>
<H2><a name="Java_tips_techniques">27.7 Tips and techniques</a></H2>
<p>
@ -5060,7 +5215,7 @@ strings and arrays. This chapter discusses the common techniques for
solving these problems.
</p>
<H3><a name="Java_input_output_parameters">27.8.1 Input and output parameters using primitive pointers and references</a></H3>
<H3><a name="Java_input_output_parameters">27.7.1 Input and output parameters using primitive pointers and references</a></H3>
<p>
@ -5234,7 +5389,7 @@ void foo(Bar *OUTPUT);
will not have the intended effect since <tt>typemaps.i</tt> does not define an OUTPUT rule for <tt>Bar</tt>.
</p>
<H3><a name="Java_simple_pointers">27.8.2 Simple pointers</a></H3>
<H3><a name="Java_simple_pointers">27.7.2 Simple pointers</a></H3>
<p>
@ -5300,7 +5455,7 @@ System.out.println("3 + 4 = " + result);
See the <a href="Library.html#Library">SWIG Library</a> chapter for further details.
</p>
<H3><a name="Java_c_arrays">27.8.3 Wrapping C arrays with Java arrays</a></H3>
<H3><a name="Java_c_arrays">27.7.3 Wrapping C arrays with Java arrays</a></H3>
<p>
@ -5367,7 +5522,7 @@ Please be aware that the typemaps in this library are not efficient as all the e
There is an alternative approach using the SWIG array library and this is covered in the next section.
</p>
<H3><a name="Java_unbounded_c_arrays">27.8.4 Unbounded C Arrays</a></H3>
<H3><a name="Java_unbounded_c_arrays">27.7.4 Unbounded C Arrays</a></H3>
<p>
@ -5512,7 +5667,7 @@ well suited for applications in which you need to create buffers,
package binary data, etc.
</p>
<H3><a name="Java_string_length">27.8.5 Passing a string with length</a></H3>
<H3><a name="Java_string_length">27.7.5 Passing a string with length</a></H3>
<p>
@ -5565,7 +5720,7 @@ The typemap uses Java <tt>String::getBytes()</tt> to convert the string to the d
</pre></div>
<H3><a name="Java_heap_allocations">27.8.6 Overriding new and delete to allocate from Java heap</a></H3>
<H3><a name="Java_heap_allocations">27.7.6 Overriding new and delete to allocate from Java heap</a></H3>
<p>
@ -5682,7 +5837,7 @@ model and use these functions in place of malloc and free in your own
code.
</p>
<H2><a name="Java_typemaps">27.9 Java typemaps</a></H2>
<H2><a name="Java_typemaps">27.8 Java typemaps</a></H2>
<p>
@ -5703,7 +5858,7 @@ Before proceeding, it should be stressed that typemaps are not a required
part of using SWIG---the default wrapping behavior is enough in most cases.
Typemaps are only used if you want to change some aspect of the generated code.
<H3><a name="Java_default_primitive_type_mappings">27.9.1 Default primitive type mappings</a></H3>
<H3><a name="Java_default_primitive_type_mappings">27.8.1 Default primitive type mappings</a></H3>
<p>
@ -5917,7 +6072,7 @@ However, the mappings allow the full range of values for each C type from Java.
</p>
<H3><a name="Java_default_non_primitive_typemaps">27.9.2 Default typemaps for non-primitive types</a></H3>
<H3><a name="Java_default_non_primitive_typemaps">27.8.2 Default typemaps for non-primitive types</a></H3>
<p>
@ -5932,7 +6087,7 @@ So in summary, the C/C++ pointer to non-primitive types is cast into the 64 bit
The Java type is either the proxy class or type wrapper class.
</p>
<H3><a name="Java_jvm64">27.9.3 Sixty four bit JVMs</a></H3>
<H3><a name="Java_jvm64">27.8.3 Sixty four bit JVMs</a></H3>
<p>
@ -5945,7 +6100,7 @@ Unfortunately it won't of course hold true for JNI code.
</p>
<H3><a name="Java_what_is_typemap">27.9.4 What is a typemap?</a></H3>
<H3><a name="Java_what_is_typemap">27.8.4 What is a typemap?</a></H3>
<p>
@ -6068,7 +6223,7 @@ int c = example.count('e', "Hello World");
</pre>
</div>
<H3><a name="Java_typemaps_c_to_java_types">27.9.5 Typemaps for mapping C/C++ types to Java types</a></H3>
<H3><a name="Java_typemaps_c_to_java_types">27.8.5 Typemaps for mapping C/C++ types to Java types</a></H3>
<p>
@ -6348,7 +6503,7 @@ These are listed below:
</table>
<H3><a name="Java_typemap_attributes">27.9.6 Java typemap attributes</a></H3>
<H3><a name="Java_typemap_attributes">27.8.6 Java typemap attributes</a></H3>
<p>
@ -6394,7 +6549,7 @@ The "javain" typemap has the optional 'pre', 'post' and 'pgcppname' attributes.
Note that when the 'pre' or 'post' attributes are specified and the associated type is used in a constructor, a constructor helper function is generated. This is necessary as the Java proxy constructor wrapper makes a call to a support constructor using a <i>this</i> call. In Java the <i>this</i> call must be the first statement in the constructor body. The constructor body thus calls the helper function and the helper function instead makes the JNI call, ensuring the 'pre' code is called before the JNI call is made. There is a <a href="#Java_date_marshalling">Date marshalling</a> example showing 'pre', 'post' and 'pgcppname' attributes in action.
</p>
<H3><a name="Java_special_variables">27.9.7 Java special variables</a></H3>
<H3><a name="Java_special_variables">27.8.7 Java special variables</a></H3>
<p>
@ -6582,7 +6737,7 @@ in that it is not fully qualified with the package name when using the
<a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a>.
</p>
<H3><a name="Java_typemaps_for_c_and_cpp">27.9.8 Typemaps for both C and C++ compilation</a></H3>
<H3><a name="Java_typemaps_for_c_and_cpp">27.8.8 Typemaps for both C and C++ compilation</a></H3>
<p>
@ -6619,7 +6774,7 @@ If you do not intend your code to be targeting both C and C++ then your typemaps
</p>
<H3><a name="Java_code_typemaps">27.9.9 Java code typemaps</a></H3>
<H3><a name="Java_code_typemaps">27.8.9 Java code typemaps</a></H3>
<p>
@ -6926,7 +7081,7 @@ to make the method and constructor public:
</pre>
</div>
<H3><a name="Java_directors_typemaps">27.9.10 Director specific typemaps</a></H3>
<H3><a name="Java_directors_typemaps">27.8.10 Director specific typemaps</a></H3>
<p>
@ -7203,7 +7358,7 @@ The basic strategy here is to provide a default package typemap for the majority
</div>
<H2><a name="Java_typemap_examples">27.10 Typemap Examples</a></H2>
<H2><a name="Java_typemap_examples">27.9 Typemap Examples</a></H2>
<p>
@ -7213,7 +7368,7 @@ the SWIG library.
</p>
<H3><a name="Java_simpler_enum_classes">27.10.1 Simpler Java enums for enums without initializers</a></H3>
<H3><a name="Java_simpler_enum_classes">27.9.1 Simpler Java enums for enums without initializers</a></H3>
<p>
@ -7292,7 +7447,7 @@ This would be done by using the original versions of these typemaps in "enums.sw
</p>
<H3><a name="Java_exception_typemap">27.10.2 Handling C++ exception specifications as Java exceptions</a></H3>
<H3><a name="Java_exception_typemap">27.9.2 Handling C++ exception specifications as Java exceptions</a></H3>
<p>
@ -7417,7 +7572,7 @@ We could alternatively have used <tt>%rename</tt> to rename <tt>what()</tt> into
</p>
<H3><a name="Java_nan_exception_typemap">27.10.3 NaN Exception - exception handling for a particular type</a></H3>
<H3><a name="Java_nan_exception_typemap">27.9.3 NaN Exception - exception handling for a particular type</a></H3>
<p>
@ -7572,7 +7727,7 @@ If we were a martyr to the JNI cause, we could replace the succinct code within
If we had, we would have put it in the "in" typemap which, like all JNI and Java typemaps, also supports the 'throws' attribute.
</p>
<H3><a name="Java_converting_java_string_arrays">27.10.4 Converting Java String arrays to char ** </a></H3>
<H3><a name="Java_converting_java_string_arrays">27.9.4 Converting Java String arrays to char ** </a></H3>
<p>
@ -7716,7 +7871,7 @@ Lastly the "jni", "jtype" and "jstype" typemaps are also required to specify
what Java types to use.
</p>
<H3><a name="Java_expanding_java_object">27.10.5 Expanding a Java object to multiple arguments</a></H3>
<H3><a name="Java_expanding_java_object">27.9.5 Expanding a Java object to multiple arguments</a></H3>
<p>
@ -7798,7 +7953,7 @@ example.foo(new String[]{"red", "green", "blue", "white"});
</div>
<H3><a name="Java_using_typemaps_return_arguments">27.10.6 Using typemaps to return arguments</a></H3>
<H3><a name="Java_using_typemaps_return_arguments">27.9.6 Using typemaps to return arguments</a></H3>
<p>
@ -7916,7 +8071,7 @@ $ java runme
1 12.0 340.0
</pre></div>
<H3><a name="Java_adding_downcasts">27.10.7 Adding Java downcasts to polymorphic return types</a></H3>
<H3><a name="Java_adding_downcasts">27.9.7 Adding Java downcasts to polymorphic return types</a></H3>
<p>
@ -8122,7 +8277,7 @@ SWIG usually generates code which constructs the proxy classes using Java code a
Note that the JNI code above uses a number of string lookups to call a constructor, whereas this would not occur using byte compiled Java code.
</p>
<H3><a name="Java_adding_equals_method">27.10.8 Adding an equals method to the Java classes</a></H3>
<H3><a name="Java_adding_equals_method">27.9.8 Adding an equals method to the Java classes</a></H3>
<p>
@ -8166,7 +8321,7 @@ System.out.println("foo1? " + foo1.equals(foo2));
</div>
<H3><a name="Java_void_pointers">27.10.9 Void pointers and a common Java base class</a></H3>
<H3><a name="Java_void_pointers">27.9.9 Void pointers and a common Java base class</a></H3>
<p>
@ -8225,7 +8380,7 @@ This example contains some useful functionality which you may want in your code.
<li> It also has a function which effectively implements a cast from the type of the proxy/type wrapper class to a void pointer. This is necessary for passing a proxy class or a type wrapper class to a function that takes a void pointer.
</ul>
<H3><a name="Java_struct_pointer_pointer">27.10.10 Struct pointer to pointer</a></H3>
<H3><a name="Java_struct_pointer_pointer">27.9.10 Struct pointer to pointer</a></H3>
<p>
@ -8405,7 +8560,7 @@ The C functional interface has been completely morphed into an object-oriented i
the Butler class would behave much like any pure Java class and feel more natural to Java users.
</p>
<H3><a name="Java_memory_management_member_variables">27.10.11 Memory management when returning references to member variables</a></H3>
<H3><a name="Java_memory_management_member_variables">27.9.11 Memory management when returning references to member variables</a></H3>
<p>
@ -8528,7 +8683,7 @@ public class Bike {
Note the <tt>addReference</tt> call.
</p>
<H3><a name="Java_memory_management_objects">27.10.12 Memory management for objects passed to the C++ layer</a></H3>
<H3><a name="Java_memory_management_objects">27.9.12 Memory management for objects passed to the C++ layer</a></H3>
<p>
@ -8656,7 +8811,7 @@ as mentioned earlier, <tt>setElement</tt> is actually:
</pre>
</div>
<H3><a name="Java_date_marshalling">27.10.13 Date marshalling using the javain typemap and associated attributes</a></H3>
<H3><a name="Java_date_marshalling">27.9.13 Date marshalling using the javain typemap and associated attributes</a></H3>
<p>
@ -8833,7 +8988,7 @@ A few things to note:
<H2><a name="Java_directors_faq">27.11 Living with Java Directors</a></H2>
<H2><a name="Java_directors_faq">27.10 Living with Java Directors</a></H2>
<p>
@ -9012,10 +9167,10 @@ public abstract class UserVisibleFoo extends Foo {
</li>
</ol>
<H2><a name="Java_odds_ends">27.12 Odds and ends</a></H2>
<H2><a name="Java_odds_ends">27.11 Odds and ends</a></H2>
<H3><a name="Java_javadoc_comments">27.12.1 JavaDoc comments</a></H3>
<H3><a name="Java_javadoc_comments">27.11.1 JavaDoc comments</a></H3>
<p>
@ -9076,7 +9231,7 @@ public class Barmy {
<H3><a name="Java_functional_interface">27.12.2 Functional interface without proxy classes</a></H3>
<H3><a name="Java_functional_interface">27.11.2 Functional interface without proxy classes</a></H3>
<p>
@ -9137,7 +9292,7 @@ All destructors have to be called manually for example the <tt>delete_Foo(foo)</
</p>
<H3><a name="Java_using_own_jni_functions">27.12.3 Using your own JNI functions</a></H3>
<H3><a name="Java_using_own_jni_functions">27.11.3 Using your own JNI functions</a></H3>
<p>
@ -9192,7 +9347,7 @@ This directive is only really useful if you want to mix your own hand crafted JN
</p>
<H3><a name="Java_performance">27.12.4 Performance concerns and hints</a></H3>
<H3><a name="Java_performance">27.11.4 Performance concerns and hints</a></H3>
<p>
@ -9213,7 +9368,7 @@ However, you will have to be careful about memory management and make sure that
This method normally calls the C++ destructor or <tt>free()</tt> for C code.
</p>
<H3><a name="Java_debugging">27.12.5 Debugging</a></H3>
<H3><a name="Java_debugging">27.11.5 Debugging</a></H3>
<p>
@ -9235,7 +9390,7 @@ The -verbose:jni and -verbose:gc are also useful options for monitoring code beh
</p>
<H2><a name="Java_examples">27.13 Java Examples</a></H2>
<H2><a name="Java_examples">27.12 Java Examples</a></H2>
<p>

View File

@ -58,11 +58,16 @@
<p>Javascript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development.
Javascript has gone beyond being a browser-based scripting language and with <a href="https://nodejs.org">node.js</a>, it is also used as a backend development language.</p>
Javascript has gone beyond being a browser-based scripting language and can be used as a backend development language with <a href="https://nodejs.org">node.js</a>.</p>
<p>Native Javascript extensions can be used for applications that embed a web-browser view or that embed a Javascript engine (such as <em>node.js</em>). Extending a general purpose web-browser is not possible as this would be a severe security issue.</p>
<p>SWIG Javascript currently supports <strong>JavascriptCore</strong>, the Javascript engine used by <code>Safari/Webkit</code>, and <a href="https://v8.dev/"><strong>v8</strong></a>, which is used by <code>Chromium</code> and <code>node.js</code>.</p>
<p>SWIG/Javascript currently supports:</p>
<ul>
<li><strong>Node.js</strong> 12 or later. SWIG can optionally generate Node-API code, which needs Node.js 12.17 or later.</li>
<li><strong>JavascriptCore</strong> 4.0 or later. JavascriptCore is used by Safari/Webkit</li>
<li><a href="https://v8.dev/"><strong>v8</strong></a> 5.0 or later. v8 is used by Chromium</li>
</ul>
<p><a href="https://webkit.org/">WebKit</a> is a modern browser implementation available as open-source which can be embedded into an application.
With <a href="https://github.com/rogerwang/node-webkit">node-webkit</a> there is a platform which uses Google's <code>Chromium</code> as Web-Browser widget and <code>node.js</code> for javascript extensions.
<a href="https://github.com/nwjs/nw.js">NW.jst</a> provides an app runtime which uses Google's Chromium as Web-Browser widget and node.js for javascript extensions.
</p>
<H2><a name="Javascript_preliminaries">28.2 Preliminaries</a></H2>
@ -91,14 +96,6 @@ $ swig -javascript -jsc example.i</pre>
<pre>
$ swig -c++ -javascript -jsc example.i</pre>
</div>
<p>The V8 code that SWIG generates requires at least V8 5.0. Keep in mind
that this is the V8 version, not Node.js. To give some perspective, Node.js v6.0
uses V8 5.0, v12.0 - 7.4, v14.0 - 8.1...</p>
<p>The Node-API code that SWIG generates requires Node-API version 6.
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

@ -138,9 +138,9 @@ and there may be some variation between platforms - these commands should at
least work for Linux though):
</p>
<div class="code"><pre>
gcc `php-config --includes` -fpic -c example_wrap.c example.c
gcc -shared example_wrap.o example.o -o example.so
<div class="shell"><pre>
$ gcc `php-config --includes` -fPIC -c example_wrap.c example.c
$ gcc -shared example_wrap.o example.o -o example.so
</pre></div>
<H3><a name="Php_nn1_3">32.1.2 Using PHP Extensions</a></H3>

View File

@ -158,9 +158,9 @@
<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), 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.
with all recent Python versions (Python 2.7 and Python &gt;= 3.5). Python 3.3
and 3.4 may still work but we are no longer regularly testing with them.
SWIG 4.0.x supported Python 3.2. SWIG 3.0.x supported older Python 2.x and 3.x.
</p>
<p>
@ -213,7 +213,6 @@ Suppose that you defined a SWIG module such as the following:
%module example
%{
#define SWIG_FILE_WITH_INIT
#include "example.h"
%}
@ -222,9 +221,7 @@ int fact(int n);
</div>
<p>
The <tt>#define SWIG_FILE_WITH_INIT</tt> line inserts a macro that specifies that the
resulting C file should be built as a Python extension, inserting the module
<tt>init</tt> code. This <tt>.i</tt> file wraps the following simple C file:
This <tt>.i</tt> file wraps the following simple C file:
</p>
<div class="code">

View File

@ -1780,6 +1780,10 @@ const int foo; /* Read only variable */
char * const version="1.0"; /* Read only variable */
</pre></div>
<p>
SWIG will also create read-only variables for non-assignable types, more details in the <a href="SWIGPlus.html#SWIGPlus_member_data">Member data</a> section in the C++ chapter.
</p>
<H3><a name="SWIG_rename_ignore">5.4.7 Renaming and ignoring declarations</a></H3>

View File

@ -1043,8 +1043,34 @@ void Foo_items_set(Foo *self, List *value) {
</div>
<p>
More information about this can be found in the SWIG Basics chapter,
<a href="SWIG.html#SWIG_structure_data_members">Structure data members</a> section.
More information about this can be found in the SWIG Basics chapter in the
<a href="SWIG.html#SWIG_structure_data_members">Structure data members</a> and
<a href="SWIG.html#SWIG_readonly_variables">Creating read-only variables</a> sections.
</p>
<p>
Additionally, any C++ type that is not assignable is also wrapped as a read-only member.
Consider the class below which is non-assignable due to the private assignment operator:
</p>
<div class="code">
<pre>
class NonAssignable {
private:
NonAssignable &amp; operator=(const NonAssignable &amp;);
public:
NonAssignable();
};
struct ImmutableVars {
NonAssignable non_assignable;
};
</pre>
</div>
<p>
The <tt>non_assignable</tt> member variable is immutable by default as SWIG detects that <tt>NonAssignable</tt> is not assignable.
SWIG must of course see the full type information in order to get this correct, otherwise you may have to use <tt>%immutable</tt> to make the variable read-only.
</p>
<p>

View File

@ -370,11 +370,11 @@ for a few common platforms is shown below:</p>
<div class="shell"><pre>
# Build a shared library for Solaris
gcc -fpic -c example.c example_wrap.c -I/usr/local/include
gcc -fPIC -c example.c example_wrap.c -I/usr/local/include
ld -G example.o example_wrap.o -o example.so
# Build a shared library for Linux
gcc -fpic -c example.c example_wrap.c -I/usr/local/include
gcc -fPIC -c example.c example_wrap.c -I/usr/local/include
gcc -shared example.o example_wrap.o -o example.so
</pre></div>

View File

@ -415,7 +415,8 @@ example.i(4) : Syntax error in input(1).
<li>327. Extern template ignored.
<li>328. Value assigned to <em>name</em> not used due to limited parsing implementation.
<li>329. Using declaration '<em>name</em>' for inheriting constructors uses base '<em>name</em>' which is not an immediate base of '<em>name</em>'.
<li>330. Template forward class instantiation '<em>templ</em>' with name '<em>name</em>' is ineffective.
<li>330. Template forward class '<em>name</em>' cannot be used to instantiate a full template class with name '<em>name</em>'.
<li>331. Unsupported template nested class '<em>name</em>' cannot be used to instantiate a full template class with name '<em>name</em>'.
<li>340. Lambda expressions and closures are not fully supported yet.
<li>344. Unable to deduce decltype for '<em>expr</em>'.
<li>345. Unable to deduce auto return type for '<em>name</em>' (ignored).

View File

@ -69,8 +69,7 @@ SWIG = $(SWIG_LIB_SET) $(SWIGTOOL) $(SWIGEXE)
LIBM = @LIBM@
LIBC = @LIBC@
LIBCRYPT = @LIBCRYPT@
SYSLIBS = $(LIBM) $(LIBC) $(LIBCRYPT)
SYSLIBS = $(LIBM) $(LIBC)
LIBPREFIX =
# RUNTOOL is for use with runtime tools, eg set it to valgrind

View File

@ -72,10 +72,10 @@ rather than <tt>gccgo</tt>.
named <tt>example.a</tt>; e.g., <tt>gopack grc example.a example.6
example_gc.6</tt>.
<li>Compile the <tt><a href="example_wrap.c">example_wrap.c</a></tt>
file using your standard C compiler with the <tt>-fpic</tt> option;
e.g., <tt>gcc -c -O -fpic example_wrap.c</tt>.
file using your standard C compiler with the <tt>-fPIC</tt> option;
e.g., <tt>gcc -c -O -fPIC example_wrap.c</tt>.
<li>Also compile the actual code, not generated by SWIG; e.g., <tt>gcc
-c -O -fpic example.c</tt>.
-c -O -fPIC example.c</tt>.
<li>Put the gcc compiled object files into a shared library;
e.g., <tt>gcc -shared -o example.so example_wrap.o example.o</tt>.
<li>Compile the program which demonstrates how to use the library;

View File

@ -42,7 +42,7 @@ the steps look like this (Linux):
<blockquote>
<pre>
% swig -perl5 interface.i
% gcc -fpic -c -Dbool=char -I/usr/lib/perl5/5.00503/i386-linux/CORE interface_wrap.c
% gcc -fPIC -c -Dbool=char -I/usr/lib/perl5/5.00503/i386-linux/CORE interface_wrap.c
% gcc -shared interface_wrap.o $(OBJS) -o interface.so
% perl
use interface;

View File

@ -44,7 +44,7 @@ the steps look like this (Linux):
<blockquote>
<pre>
% swig -python interface.i
% gcc -fpic -c interface_wrap.c -I/usr/local/include/python1.5
% gcc -fPIC -c interface_wrap.c -I/usr/local/include/python1.5
% gcc -shared interface_wrap.o $(OBJS) -o interfacemodule.so
% python
Python 1.5.2 (#3, Oct 9 1999, 22:09:34) [GCC 2.95.1 19990816 (release)] on linux2

View File

@ -45,7 +45,7 @@ the steps look like this (Linux):
<blockquote>
<pre>
% swig -ruby interface.i
% gcc -fpic -c interface_wrap.c -I/usr/local/lib/ruby/1.4/i686-linux
% gcc -fPIC -c interface_wrap.c -I/usr/local/lib/ruby/1.4/i686-linux
% gcc -shared interface_wrap.o $(OBJS) -o interface.so
% ruby
require 'interface'

View File

@ -44,7 +44,7 @@ the steps look like this (Linux):
<blockquote>
<pre>
unix % swig -tcl interface.i
unix % gcc -fpic -c interface_wrap.c -I/usr/local/include
unix % gcc -fPIC -c interface_wrap.c -I/usr/local/include
unix % gcc -shared interface_wrap.o $(OBJS) -o interface.so
unix % tclsh8.3
% load ./interface.so

View File

@ -21,6 +21,7 @@
#define SPECIALCHARAE1 'Æ' // AE (latin1 encoded)
#define SPECIALCHARAE2 '\306' // AE (latin1 encoded)
#define SPECIALCHARAE3 '\xC6' // AE (latin1 encoded)
#define SPECIALCHARPAREN (';')
#if defined(SWIGJAVA)
%javaconst(1);
@ -42,9 +43,11 @@
#define X_SPECIALCHARAE1 'Æ' // AE (latin1 encoded)
#define X_SPECIALCHARAE2 '\306' // AE (latin1 encoded)
#define X_SPECIALCHARAE3 '\xC6' // AE (latin1 encoded)
#define X_SPECIALCHARPAREN (';')
%inline
{
const int ia = (int)'a';
const int ib = 'b';
const int iparen = (';');
}

View File

@ -269,6 +269,7 @@ CPP_TEST_CASES += \
features \
fragments \
friends \
friends_nested \
friends_operator_overloading \
friends_template \
funcptr_cpp \
@ -586,6 +587,7 @@ CPP_TEST_CASES += \
using_directive_and_declaration \
using_directive_and_declaration_forward \
using_extend \
using_extend_flatten \
using_inherit \
using_member \
using_member_multiple_inherit \
@ -715,7 +717,7 @@ ifneq ($(SKIP_DOXYGEN_TEST_CASES),1)
python_HAS_DOXYGEN := 1
java_HAS_DOXYGEN := 1
$(eval HAS_DOXYGEN := $($(LANGUAGE)_HAS_DOXYGEN))
HAS_DOXYGEN := $($(LANGUAGE)_HAS_DOXYGEN)
endif
ifdef HAS_DOXYGEN
@ -730,6 +732,7 @@ DOXYGEN_TEST_CASES += \
doxygen_ignore \
doxygen_misc_constructs \
doxygen_nested_class \
doxygen_overloads \
doxygen_parsing \
doxygen_parsing_enums \
doxygen_translate \

View File

@ -64,3 +64,6 @@ public:
std::is_trivially_destructible<T>::value>
test_alignof_too;
};
%constant int WSTRING_LIT_LEN1 = (sizeof(L"1234")/sizeof(wchar_t) - 1);
%constant int WSTRING_LIT_LEN2 = (sizeof(L"12" L"34")/sizeof(wchar_t) - 1);

View File

@ -77,3 +77,14 @@ const int s9a = sizeof(-s8a);
// const int s9b = sizeof -s8a; /* not currently supported */
%}
/* Regression test for #1917, fixed in 4.3.0. */
#ifdef SWIGCSHARP
%csconst(1) float_suffix_test;
#endif
#ifdef SWIGJAVA
%javaconst(1) float_suffix_test;
#endif
%constant const float float_suffix_test = 4.0f;
%constant const float float_suffix_test2 = 4.0f;
#define float_suffix_test3 4.0f

View File

@ -1,5 +1,7 @@
%module cpp11_auto_variable
%ignore func();
%inline %{
static auto t = true;
@ -26,6 +28,9 @@ static constexpr auto Foo2 = Foo;
static auto Bar3 = f ? zero : t;
static constexpr auto Foo3 = f ? f : one;
int func() { return 1; }
static constexpr auto NOEXCEPT_FUNC = noexcept(func);
%}
// SWIG currently can't deduce the type for examples below.
@ -44,6 +49,13 @@ static constexpr auto Bad4 = &one;
%}
%inline %{
// Concatenation of a literal with an encoding prefix and one without
// was added in C++11.
static auto wstring_lit_len1 = sizeof(L"123" "456") / sizeof(wchar_t) - 1;
static auto wstring_lit_len2 = sizeof("123" L"456") / sizeof(wchar_t) - 1;
%}
%inline %{
// FIXME: Not currently handled by SWIG's parser:

View File

@ -41,9 +41,12 @@
%ignore hidden_global_char;
%ignore hidden_global_func;
%inline %{
#define DECLARE(VAR, VAL) decltype(VAL) VAR = VAL
static const char hidden_global_char = '\0';
void hidden_global_func() { }
class B {
public:
int i;
@ -83,6 +86,9 @@
// Test alternative operator names work in this context.
decltype(((compl 42) and (not 1)) or (2 xor 4)) should_be_bool2;
// Feature test for noexcept as an operator.
decltype(noexcept(hidden_global_func)) should_be_bool3;
decltype(E1) should_be_enum;
auto get_number_sum(decltype(i+j) a) -> decltype(i+j) {

View File

@ -62,3 +62,12 @@ struct NoExceptDefaultDelete {
%}
// Regression tests for #2087 (noexcept on a function pointer parameter type).
//
// FIXME: We've only fixed `noexcept` on parameter types which are function
// pointers to parse - the generated code has `noexcept` in the wrong place
// and won't compile so for now we only check SWIG can parse this.
%ignore f2087a;
%ignore f2087b;
void f2087a(int (*g)() noexcept) { (void)g; }
void f2087b(int const (*g)() noexcept) { (void)g; }

View File

@ -58,7 +58,8 @@ std::string pathPtrToStr(const std::filesystem::path * p) {
return p->string();
}
std::filesystem::path roundTrip(const std::filesystem::path& p) {
namespace stdfs = std::filesystem;
std::filesystem::path roundTrip(const stdfs::path& p) {
return p;
}
%}

View File

@ -39,6 +39,9 @@ public class runme {
assert( typeof(char) == preproc_constants.CONST_CHAR.GetType() );
assert( typeof(string) == preproc_constants.CONST_STRING1.GetType() );
assert( typeof(string) == preproc_constants.CONST_STRING2.GetType() );
assert( typeof(string) == preproc_constants.CONST_STRING3.GetType() );
assert( typeof(string) == preproc_constants.CONST_STRING4.GetType() );
assert( preproc_constants.CONST_STRING4 == "zer\0zer\0" );
assert( typeof(int) == preproc_constants.INT_AND_BOOL.GetType() );
assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() );

View File

@ -0,0 +1,13 @@
using System;
using string_constantsNamespace;
public class runme {
static void Main() {
assert( string_constants.QQ1 == "\x000800! \x00018b00!" );
assert( string_constants.QQ2 == "\x000800! \x00018b00!" );
}
static void assert(bool assertion) {
if (!assertion)
throw new ApplicationException("test failed");
}
}

View File

@ -0,0 +1,95 @@
%module doxygen_overloads
%inline %{
void overloadWithNoDoc(int) { }
void overloadWithNoDoc(double) { }
/// Doc for first overload.
void overloadWithFirstDoc(int) { }
void overloadWithFirstDoc(double) { }
void overloadWithSecondDoc(int) { }
/// Doc for second overload.
void overloadWithSecondDoc(double) { }
/// Doc for both overloads, first.
void overloadWithBothDocs(int) { }
/// Doc for both overloads, second.
void overloadWithBothDocs(double) { }
/// Doc for some overloads, first.
void overloadWithSomeDocs(int) { }
void overloadWithSomeDocs(double) { }
/// Doc for some overloads, third.
void overloadWithSomeDocs(char) { }
/// Doc for some other overloads, first.
void overloadWithSomeOtherDocs(int) { }
/// Doc for some other overloads, second.
void overloadWithSomeOtherDocs(double) { }
void overloadWithSomeOtherDocs(char) { }
// Also test different kinds of member functions.
struct S {
/// Doc for first static overload.
static void staticOverloadWithFirstDoc(int) { }
static void staticOverloadWithFirstDoc(double) { }
/// Doc for first member overload.
void memberOverloadWithFirstDoc(int) { }
void memberOverloadWithFirstDoc(double) { }
};
// Class ctors are handled differently from the other functions, so check them too.
struct ClassWithNoDoc {
ClassWithNoDoc(int) { }
ClassWithNoDoc(double) { }
};
struct ClassWithFirstDoc {
/// Doc for first ctor.
ClassWithFirstDoc(int) { }
ClassWithFirstDoc(double) { }
};
struct ClassWithSecondDoc {
ClassWithSecondDoc(int) { }
/// Doc for second ctor.
ClassWithSecondDoc(double) { }
};
struct ClassWithBothDocs {
/// Doc for both ctors, first.
ClassWithBothDocs(int) { }
/// Doc for both ctors, second.
ClassWithBothDocs(double) { }
};
struct ClassWithSomeDocs {
/// Doc for some ctors, first.
ClassWithSomeDocs(int) { }
ClassWithSomeDocs(double) { }
/// Doc for some ctors, third.
ClassWithSomeDocs(char) { }
};
struct ClassWithSomeOtherDocs {
/// Doc for some other ctors, first.
ClassWithSomeOtherDocs(int) { }
/// Doc for some other ctors, second.
ClassWithSomeOtherDocs(double) { }
ClassWithSomeOtherDocs(char) { }
};
#ifdef SWIGPYTHON_BUILTIN
bool is_python_builtin() { return true; }
#else
bool is_python_builtin() { return false; }
#endif
%}

View File

@ -2,6 +2,8 @@
enum stuff {
FOO = 'x',
BAR = 3.14159
BAR = 3.14159,
BADBIN = 0b121,
BADOCTAL = 018118055
};

View File

@ -1 +1,4 @@
c_enum_badvalue.i:6: Error: Type error. Expecting an integral type
c_enum_badvalue.i:5: Error: Type error. Expecting an integral type
c_enum_badvalue.i:6: Error: Invalid digit '2' in binary constant
c_enum_badvalue.i:7: Error: Invalid digit '8' in octal constant
c_enum_badvalue.i:7: Error: Invalid digit '8' in octal constant

View File

@ -0,0 +1,15 @@
%module xxx
namespace ns {
class OuterClass {
public:
template <class T> struct Inner1 {
};
Inner1<int> useInner1(const Inner1<int>& inner) { return inner; }
#ifdef SWIG
%template(T_OuterClassInner1Double) Inner1<double>;
#endif
int iii;
};
}

View File

@ -0,0 +1,2 @@
cpp_nested_class_template.i:7: Warning 325: Nested struct not currently supported (Inner1 ignored)
cpp_nested_class_template.i:11: Warning 331: Unsupported template nested class 'ns::OuterClass::Inner1< double >' cannot be used to instantiate a full template class with name 'T_OuterClassInner1Double'.

View File

@ -1,4 +1,4 @@
cpp_template_forward.i:6: Warning 330: Template forward class instantiation 'Space::ForwardDeclaredTemplate< double >' with name 'ForwardDeclaredTemplate_double' is ineffective.
cpp_template_forward.i:9: Warning 330: Template forward class instantiation 'Space::ForwardDeclaredSpecialized< int >' with name 'ForwardDeclaredTemplate_int' is ineffective.
cpp_template_forward.i:10: Warning 330: Template forward class instantiation 'Space::ForwardDeclaredSpecialized< double >' with name 'ForwardDeclaredTemplate_double' is ineffective.
cpp_template_forward.i:16: Warning 330: Template forward class instantiation 'Space::ForwardDeclaredMisplacedPrimary< double >' with name 'ForwardDeclaredTemplate_double' is ineffective.
cpp_template_forward.i:6: Warning 330: Template forward class 'Space::ForwardDeclaredTemplate< double >' cannot be used to instantiate a full template class with name 'ForwardDeclaredTemplate_double'.
cpp_template_forward.i:9: Warning 330: Template forward class 'Space::ForwardDeclaredSpecialized< int >' cannot be used to instantiate a full template class with name 'ForwardDeclaredTemplate_int'.
cpp_template_forward.i:10: Warning 330: Template forward class 'Space::ForwardDeclaredSpecialized< double >' cannot be used to instantiate a full template class with name 'ForwardDeclaredTemplate_double'.
cpp_template_forward.i:16: Warning 330: Template forward class 'Space::ForwardDeclaredMisplacedPrimary< double >' cannot be used to instantiate a full template class with name 'ForwardDeclaredTemplate_double'.

View File

@ -50,3 +50,10 @@ comment */
%constant int ggg=;
// Bad binary and octal constants
%constant int badbin = 0b121;
%constant int badoct = 018118055;
// Bad octal escape sequences.
%constant char * badbinstring = "\400";
%constant char badbinchar = '\777';

View File

@ -6,3 +6,8 @@ pp_constant.i:37: Warning 305: Bad constant value (ignored).
pp_constant.i:44: Warning 305: Bad constant value (ignored).
pp_constant.i:48: Warning 305: Bad constant value (ignored).
pp_constant.i:51: Warning 305: Bad constant value (ignored).
pp_constant.i:54: Error: Invalid digit '2' in binary constant
pp_constant.i:55: Error: Invalid digit '8' in octal constant
pp_constant.i:55: Error: Invalid digit '8' in octal constant
pp_constant.i:58: Error: octal escape sequence out of range
pp_constant.i:59: Error: octal escape sequence out of range

View File

@ -7,3 +7,7 @@
#error Another error
#warning Another warning
/* Regression tests for #657 */
#error Test it's OK to use an apostrophe
#warning An unmatched " should be OK too

View File

@ -2,3 +2,5 @@ pp_error_directive.i:3: Warning 204: CPP #warning, "Print this warning".
pp_error_directive.i:5: Error: CPP #error "This is an error". Use the -cpperraswarn option to continue swig processing.
pp_error_directive.i:7: Error: CPP #error "Another error". Use the -cpperraswarn option to continue swig processing.
pp_error_directive.i:9: Warning 204: CPP #warning, "Another warning".
pp_error_directive.i:12: Error: CPP #error "Test it's OK to use an apostrophe". Use the -cpperraswarn option to continue swig processing.
pp_error_directive.i:13: Warning 204: CPP #warning, "An unmatched " should be OK too".

View File

@ -77,3 +77,9 @@
#if MY_VERSION_AT_LEAST(1,2,3)
#warning This should not warn
#endif
/* Test errors for bad digits in binary and octal constants. */
#if 0b01210
#endif
#if 018118055
#endif

View File

@ -35,3 +35,6 @@ pp_expressions_bad.i:73: Warning 202: Could not evaluate expression '(4 <=> 2) <
pp_expressions_bad.i:73: Warning 202: Syntax error
pp_expressions_bad.i:77: Warning 202: Could not evaluate expression 'MY_VERSION_AT_LEAST(1,2,3)'
pp_expressions_bad.i:77: Warning 202: Use of undefined function-like macro
pp_expressions_bad.i:82: Error: Invalid digit '2' in binary constant
pp_expressions_bad.i:84: Error: Invalid digit '8' in octal constant
pp_expressions_bad.i:84: Error: Invalid digit '8' in octal constant

Binary file not shown.

View File

@ -0,0 +1,5 @@
pp_zerobyte.i:6: Error: CPP #error "case 1a". Use the -cpperraswarn option to continue swig processing.
pp_zerobyte.i:7: Error: CPP #error "case 1b". Use the -cpperraswarn option to continue swig processing.
pp_zerobyte.i:9: Error: CPP #error "case 2a". Use the -cpperraswarn option to continue swig processing.
pp_zerobyte.i:10: Error: CPP #error "case 2b". Use the -cpperraswarn option to continue swig processing.
pp_zerobyte.i:14: Error: CPP #error "case 3". Use the -cpperraswarn option to continue swig processing.

View File

@ -16,6 +16,10 @@ struct A
// 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; }
int g(int 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 b; }
};
const unsigned char LASTCHAR1 = "hello world"[sizeof"hello world" - 2];
const unsigned char LASTCHAR2 = "bye"[sizeof("bye") - 2];
%}

View File

@ -0,0 +1,232 @@
%module friends_nested
// Issue #2845 - handling friends in nested classes
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) CPP17::AA::BB::more_acc_cond::squeezed_in;
%rename(operatorshift) operator<<;
%rename(operatorshift) *::operator<<;
%feature("flatnested") spot::acc_cond::mark_t;
%inline %{
#include <iostream>
std::ostream& std_cout_reference() {
return std::cout;
}
// Stops cout from outputting anything
void std_cout_badbit() {
std_cout_reference().setstate(std::ios_base::badbit);
}
namespace spot
{
class option_map
{
public:
friend std::ostream& operator<<(std::ostream& os, const option_map& m); // 1
};
class acc_cond
{
public:
struct mark_t
{
mark_t operator<<(unsigned i) const; // 2
friend std::ostream& operator<<(std::ostream& os, mark_t m); // 3
};
};
std::ostream& operator<<(std::ostream& os, const acc_cond& acc); // 4
}
void test_from_cplusplus() {
spot::option_map om;
{
using namespace spot;
operator<<(std::cout, om);
}
spot::acc_cond::mark_t m;
m.operator<<(999);
{
using namespace spot;
operator<<(std::cout, m);
}
spot::acc_cond a;
operator<<(std::cout, a);
}
%}
%{
namespace spot {
std::ostream& operator<<(std::ostream& os, const option_map& m) { os << "operator<< 1" << std::endl; return os; } // 1
acc_cond::mark_t acc_cond::mark_t::operator<<(unsigned i) const { std::ostream& os = std_cout_reference(); os << "operator<< 2" << std::endl; return spot::acc_cond::mark_t(); } // 2
std::ostream& operator<<(std::ostream& os, acc_cond::mark_t m) { os << "operator<< 3" << std::endl; return os; } // 3
std::ostream& operator<<(std::ostream& os, const acc_cond& acc) { os << "operator<< 4" << std::endl; return os; } // 4
}
%}
%{
// Compiler using traditional (non-C++17 nested) namespaces
namespace CPP17 {
namespace AA {
namespace BB {
class more_acc_cond {
public:
struct squeezed_in {
struct more_mark_t
{
more_mark_t operator<<(unsigned i) const; // 6
friend std::ostream& operator<<(std::ostream& os, const more_mark_t& m); // 5
};
};
};
}
}
}
%}
// SWIG testing C++17 nested namespaces
namespace CPP17::AA::BB {
class more_acc_cond {
public:
struct squeezed_in {
struct more_mark_t
{
more_mark_t operator<<(unsigned i) const; // 6
friend std::ostream& operator<<(std::ostream& os, const more_mark_t& m); // 5
};
};
};
}
%{
namespace CPP17 {
namespace AA {
namespace BB {
more_acc_cond::squeezed_in::more_mark_t more_acc_cond::squeezed_in::more_mark_t::operator<<(unsigned i) const { std::ostream& os = std_cout_reference(); os << "operator<< 6" << std::endl; return more_acc_cond::squeezed_in::more_mark_t(); }
std::ostream& operator<<(std::ostream& os, const more_acc_cond::squeezed_in::more_mark_t& m) { os << "operator<< 5" << std::endl; return os; } // 5
}
}
}
%}
%inline %{
#if defined(SWIG)
#define STATIC_FOR_ANONYMOUS
#else
// For gcc in C++98 mode (at least) to avoid:
// error: unnamed type with no linkage used to declare variable <unnamed class> instance with linkage
#define STATIC_FOR_ANONYMOUS static
#endif
struct BaseForAnon {
virtual ~BaseForAnon() {}
};
// Unnamed nested classes are ignored but were causing code that did not compile
STATIC_FOR_ANONYMOUS class /*unnamed*/ : public BaseForAnon {
int member_var;
public:
friend int myfriend();
// nested unnamed class
class /*unnamed*/ {
int inner_member_var;
public:
// below caused SWIG crash
friend int innerfriend();
} anon_inner;
} instance;
// friend members ignored too as the entire unnamed class is ignored!
int myfriend() {
return instance.member_var;
}
int innerfriend() {
return instance.anon_inner.inner_member_var;
}
%}
///////////////////////////////////////////////////////////////
// Test nested templates and classes
///////////////////////////////////////////////////////////////
// %feature("flatnested"); // This ought to work for languages that don't support nested structs, but InnerInnerStruct is multiply defined at the time of writing
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
%inline %{
namespace OuterSpace {
namespace InnerSpace {
struct OuterClass {
template<typename T> struct InnerTemplate {
InnerTemplate(T i) : val(i) {}
void InstanceMethod(T i) {}
static void StaticMethod(T i) {}
friend T friendly(InnerTemplate/*<T>*/ t) {return t.val; }
T thung(InnerTemplate/*<T>*/ t) {return t.val; }
struct InnerInnerStruct {
InnerInnerStruct(T p) : priv(p) {}
friend T friendly_inner_qualified(const InnerTemplate<T>::InnerInnerStruct& i) { return i.priv; }
// friend T friendly_inner(const InnerInnerStruct& i) { return i.priv; } // TODO: without template parameters
void dosomething(const InnerInnerStruct& x) {}
void useinner(const InnerTemplate& x) {}
private:
T priv;
};
void use_inner_inner(InnerInnerStruct iis) {}
template<typename X> struct InnerInnerTemplate {
InnerInnerTemplate(T t, X x) : t_private(t), x_private(x) {}
friend X friendly_inner_x(const InnerTemplate<T>::InnerInnerTemplate<X>& i) { return i.x_private; }
friend T friendly_inner_t(const InnerTemplate<T>::InnerInnerTemplate<X>& i) { return i.t_private; }
void doanything(const InnerInnerTemplate& x) {}
void useT(const T& ttt) {}
void useX(const X& xxx) {}
struct VeryInner {
VeryInner(const T& t, const X& x) {}
friend X very_inner(const InnerTemplate<T>::InnerInnerTemplate<X>::VeryInner& vi) { return 0; }
};
private:
T t_private;
X x_private;
};
private:
T val;
};
#if defined(SWIG)
// Template instantation within the class
%template(InnerDouble) InnerTemplate<double>;
%template(InnerShort) InnerTemplate<short>;
#endif
};
}
}
%}
%extend OuterSpace::InnerSpace::OuterClass {
// Template instantation after the class is fully defined and added to the symbol tables
%template(InnerInt) InnerTemplate<int>;
}
%extend OuterSpace::InnerSpace::OuterClass::InnerTemplate<double> {
%template(InnerInnerBool) InnerInnerTemplate<bool>;
}
%extend OuterSpace::InnerSpace::OuterClass::InnerTemplate<int> {
%template(InnerInnerChar) InnerInnerTemplate<char>;
}
%extend OuterSpace::InnerSpace::OuterClass::InnerTemplate<short> {
%template(InnerInnerString) InnerInnerTemplate<char *>;
}
#endif

View File

@ -33,4 +33,3 @@ void *typedef_call1(AddByValueTypedef *& precallback, AddByValueTypedef * postca
void *typedef_call2(AddByPointerTypedef *& precallback, AddByPointerTypedef * postcallback) { return 0; }
void *typedef_call3(AddByReferenceTypedef *& precallback, AddByReferenceTypedef * postcallback) { return 0; }
%}

View File

@ -0,0 +1,9 @@
package main
import "swigtests/preproc_constants"
func main() {
if preproc_constants.CONST_STRING4 != "zer\x00zer\x00" {
panic(0)
}
}

View File

@ -0,0 +1,65 @@
import friends_nested.*;
public class friends_nested_runme {
static {
try {
System.loadLibrary("friends_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[]) {
option_map om = new option_map();
mark_t m = new mark_t();
acc_cond ac = new acc_cond();
more_acc_cond.squeezed_in.more_mark_t mm = new more_acc_cond.squeezed_in.more_mark_t();
SWIGTYPE_p_std__ostream cout = friends_nested.std_cout_reference();
friends_nested.std_cout_badbit(); // uncomment this to see std::cout
friends_nested.operatorshift(cout, om);
m.operatorshift(0);
friends_nested.operatorshift(cout, m);
friends_nested.operatorshift(cout, ac);
friends_nested.operatorshift(cout, mm);
// Test nested templates and classes
OuterClass oc = new OuterClass();
OuterClass.InnerDouble inner_double = new OuterClass.InnerDouble(1.1);
OuterClass.InnerInt inner_int = new OuterClass.InnerInt(2);
OuterClass.InnerShort inner_short = new OuterClass.InnerShort((short)3);
friends_nested.friendly(inner_double);
friends_nested.friendly(inner_int);
friends_nested.friendly(inner_short);
OuterClass.InnerDouble.InnerInnerStruct iis_double = new OuterClass.InnerDouble.InnerInnerStruct(11.1);
OuterClass.InnerInt.InnerInnerStruct iis_int = new OuterClass.InnerInt.InnerInnerStruct(22);
OuterClass.InnerShort.InnerInnerStruct iis_short = new OuterClass.InnerShort.InnerInnerStruct((short)33);
friends_nested.friendly_inner_qualified(iis_double);
friends_nested.friendly_inner_qualified(iis_int);
friends_nested.friendly_inner_qualified(iis_short);
OuterClass.InnerDouble.InnerInnerBool iit_bool = new OuterClass.InnerDouble.InnerInnerBool(111.1, true);
OuterClass.InnerInt.InnerInnerChar iit_char = new OuterClass.InnerInt.InnerInnerChar(222, 'x');
OuterClass.InnerShort.InnerInnerString iit_string = new OuterClass.InnerShort.InnerInnerString((short)333, "hi");
friends_nested.friendly_inner_x(iit_bool);
friends_nested.friendly_inner_x(iit_char);
friends_nested.friendly_inner_x(iit_string);
OuterClass.InnerDouble.InnerInnerBool.VeryInner vi_iit_bool = new OuterClass.InnerDouble.InnerInnerBool.VeryInner(111.1, true);
OuterClass.InnerInt.InnerInnerChar.VeryInner vi_iit_char = new OuterClass.InnerInt.InnerInnerChar.VeryInner(222, 'x');
OuterClass.InnerShort.InnerInnerString.VeryInner vi_iit_string = new OuterClass.InnerShort.InnerInnerString.VeryInner((short)333, "hi");
friends_nested.very_inner(vi_iit_bool);
friends_nested.very_inner(vi_iit_char);
friends_nested.very_inner(vi_iit_string);
}
}

View File

@ -1,5 +1,6 @@
import java_constants.*;
import java.lang.reflect.*;
public class java_constants_runme {
static {
@ -25,5 +26,13 @@ public class java_constants_runme {
default:
break;
}
// Check the altered constants interface access modifier
Class[] cls = java_constants.class.getInterfaces();
Class constantsInterface = cls[0];
int modifiers = constantsInterface.getModifiers();
boolean isDefaultAccessModifier = !(Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers) || Modifier.isPrivate(modifiers));
if (!isDefaultAccessModifier)
throw new RuntimeException("java_constantsConstants interface access modifiers not default access");
}
}

View File

@ -68,6 +68,13 @@ public class multiple_inheritance_interfaces_runme {
checkBaseAndInterfaces(V.class, false, "S", new String[] {});
checkBaseAndInterfaces(W.class, false, "T", new String[] {});
checkBaseAndInterfaces(IV1SwigInterface.class, true, "", new String[] {"IA"});
checkBaseAndInterfaces(IV2SwigInterface.class, true, "", new String[] {"IA"});
checkBaseAndInterfaces(IV1.class, false, "", new String[] {"IV1SwigInterface", "IA"});
checkBaseAndInterfaces(IV2.class, false, "", new String[] {"IV2SwigInterface", "IA"});
checkBaseAndInterfaces(V3.class, false, "", new String[] {"V3SwigInterface", "IV1SwigInterface", "IA", "IV2SwigInterface"});
checkBaseAndInterfaces(V3SwigInterface.class, true, "", new String[] {"IV1SwigInterface", "IV2SwigInterface"});
// overloaded methods check
D d = new D();
d.ia();

View File

@ -0,0 +1,19 @@
import preproc_constants.*;
public class preproc_constants_runme {
static {
try {
System.loadLibrary("preproc_constants");
} 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[])
{
if (preproc_constants.CONST_STRING4 != "zer\0zer\0")
throw new RuntimeException("Failed");
}
}

View File

@ -0,0 +1,24 @@
import string_constants.*;
public class string_constants_runme {
static {
try {
System.loadLibrary("string_constants");
} 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[])
{
if (!string_constants.ES1.equals(""))
throw new RuntimeException("fail");
if (!string_constants.ES2.equals(""))
throw new RuntimeException("fail");
if (!string_constants.ZS1.equals("\000"))
throw new RuntimeException("fail");
if (!string_constants.ZS2.equals("\000"))
throw new RuntimeException("fail");
}
}

View File

@ -0,0 +1,21 @@
import using_extend_flatten.*;
public class using_extend_flatten_runme {
static {
try {
System.loadLibrary("using_extend_flatten");
} 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[]) {
ExtendDerived ed = new ExtendDerived();
ed.one();
ed.two();
ed.three();
}
}

View File

@ -3,6 +3,7 @@
%module java_constants
%pragma(java) constantsmodifiers="interface" // change to default access
%constant short DIPSTICK=100;

View File

@ -1,3 +1,5 @@
var keyword_rename_c = require("keyword_rename_c");
keyword_rename_c._instanceof(1);
keyword_rename_c._finally(1);
keyword_rename_c._yield(0);
keyword_rename_c.yield = 0;

View File

@ -1,3 +1,12 @@
var keyword_rename = require("keyword_rename")
keyword_rename._instanceof(1)
keyword_rename._finally(1)
keyword_rename._yield(0)
var s = keyword_rename.make_S_with_yield(17);
if (s.yield != 17)
throw new Error;
if (s._yield == 17)
throw new Error;

View File

@ -40,6 +40,19 @@ KW(nil,local)
/* Javascript keywords */
KW(instanceof, finally)
KW(finally, instanceof)
KW(yield, with)
/* Keywords used as member variables shouldn't be renamed in Javascript. */
struct S {
int yield;
};
struct S make_S_with_yield(int yield) {
struct S s;
s.yield = yield;
return s;
}
%}

View File

@ -174,3 +174,16 @@ public:
}
%}
#if defined(SWIGJAVA)
%javaconst(1);
#elif SWIGCSHARP
%csconst(1);
#elif SWIGD
%dmanifestconst;
#endif
%inline %{
const std::string aString = "something";
%}
%constant std::string MY_STRING = "";
%constant std::string MY_STRING_2 = "OK";

View File

@ -49,6 +49,17 @@ struct V : S {};
struct W : T {};
%}
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
%interface(IV1)
%interface(IV2)
%interface(V3)
#endif
%inline %{
struct IV1 : virtual IA {};
struct IV2 : virtual IA {};
struct V3 : IV1, IV2 {};
%}
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
%interface_impl(Undesirables);
#endif

View File

@ -13,12 +13,24 @@ global CONST_DOUBLE3
global CONST_BOOL1
global CONST_CHAR
global CONST_STRING1
global CONST_STRING4
assert(CONST_INT1, 10)
assert(CONST_DOUBLE3, 12.3)
assert(CONST_BOOL1, true)
assert(CONST_CHAR, 'x')
assert(CONST_STRING1, "const string")
if (false)
# Currently SWIG/Octave truncates at a zero byte in a string constant.
# strings support embedded zero bytes so this ought to work, but is an
# uncommon case.
assert(CONST_STRING4, "zer\0zer\0")
else
# Test the current behaviour for now to ensure this testcase gets updated
# when this gets fixed, and also to check we don't mangle the value in some
# other way.
assert(CONST_STRING4, "zer")
endif
endfunction
test_global

View File

@ -15,4 +15,7 @@ check::equal(YY, yy());
check::equal(constant_expr::XX, constant_expr::xx());
check::equal(constant_expr::YY, constant_expr::yy());
check::equal(WSTRING_LIT_LEN1, 4);
check::equal(WSTRING_LIT_LEN2, 4);
check::done();

View File

@ -5,7 +5,7 @@ require "tests.php";
// No new functions
check::functions(array());
check::classes(array('cpp11_auto_variable'));
check::globals(array('f', 't', 'zero', 'one', 'la', 'da', 'fa', 'lc', 'dc', 'fc', 'pi_approx', 'Bar', 'Bar2', 'Bar3', 'Foo', 'Foo2', 'Foo3'));
check::globals(array('f', 't', 'zero', 'one', 'la', 'da', 'fa', 'lc', 'dc', 'fc', 'pi_approx', 'wstring_lit_len1', 'wstring_lit_len2', 'Bar', 'Bar2', 'Bar3', 'Foo', 'Foo2', 'Foo3', 'NOEXCEPT_FUNC'));
check::equal(f_get(), false);
check::equal(gettype(f_get()), "boolean");
@ -38,3 +38,6 @@ check::equal(dc_get(), 1.0);
// PHP doesn't have a native "long double" type, so SWIG/PHP doesn't have
// typemaps for it and so it should get wrapped as an opaque type.
check::str_contains(lc_get(), "SWIGPointer(");
check::equal(wstring_lit_len1_get(), 6);
check::equal(wstring_lit_len2_get(), 6);

View File

@ -34,6 +34,21 @@ check::equal(gettype(preproc_constants::CONST_BOOL2), "boolean", "preproc_consta
check::equal(gettype(preproc_constants::CONST_CHAR), "string", "preproc_constants.CONST_CHAR has unexpected type");
check::equal(gettype(preproc_constants::CONST_STRING1), "string", "preproc_constants.CONST_STRING1 has unexpected type");
check::equal(gettype(preproc_constants::CONST_STRING2), "string", "preproc_constants.CONST_STRING2 has unexpected type");
check::equal(gettype(preproc_constants::CONST_STRING3), "string", "preproc_constants.CONST_STRING3 has unexpected type");
check::equal(gettype(preproc_constants::CONST_STRING4), "string", "preproc_constants.CONST_STRING4 has unexpected type");
if (false) {
// Currently SWIG/PHP truncates at a zero byte in a string constant. PHP
// strings support embedded zero bytes so this ought to work, but is an
// uncommon case.
check::equal(preproc_constants::CONST_STRING4, "zer\0zer\0");
check::equal(CONST_STRING4, "zer\0zer\0");
} else {
// Test the current behaviour for now to ensure this testcase gets updated
// when this gets fixed, and also to check we don't mangle the value in some
// other way.
check::equal(preproc_constants::CONST_STRING4, "zer");
check::equal(CONST_STRING4, "zer");
}
check::equal(gettype(preproc_constants::INT_AND_BOOL), "integer", "preproc_constants.INT_AND_BOOL has unexpected type");
check::equal(gettype(preproc_constants::INT_AND_CHAR), "integer", "preproc_constants.INT_AND_CHAR has unexpected type");

View File

@ -0,0 +1,18 @@
<?php
require "tests.php";
// No new functions
check::functions(array());
// New classes
check::classes(array('string_constants', 'things'));
// New vars
check::globals(array('AA3', 'EE3', 'ES3', 'QQ3', 'SS3', 'XX3', 'ZS3'));
check::equal(string_constants::QQ1, "\01000! \0018b00!");
check::equal(string_constants::QQ2, "\01000! \0018b00!");
check::equal(QQ3_get(), "\01000! \0018b00!");
$t = new things();
check::equal($t->defarguments7(), "\01000! \0018b00!");
check::done();

View File

@ -1,5 +1,15 @@
%module preproc_constants
#ifdef SWIGCSHARP
%csconst(1) CONST_STRING4;
#endif
#ifdef SWIGD
%dmanifestconst CONST_STRING4;
#endif
#ifdef SWIGJAVA
%javaconst(1) CONST_STRING4;
#endif
%{
#if defined(__clang__)
//Suppress: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
@ -48,6 +58,9 @@
#define CONST_STRING1 "const string"
#define CONST_STRING2 "const" " string"
#define CONST_STRING3 "log-revprops"
// Ideally we shouldn't truncate at a zero byte in target languages where the
// native string type allows strings to contain a zero byte.
#define CONST_STRING4 "zer\0" "zer\0"
// Expressions - runtime tests check the type for any necessary type promotions of the expressions

View File

@ -0,0 +1,83 @@
import doxygen_overloads
import inspect
import comment_verifier
if inspect.getdoc(doxygen_overloads.overloadWithNoDoc) is not None:
raise Exception("No docstring expected for overloadWithNoDoc.")
comment_verifier.check(inspect.getdoc(doxygen_overloads.overloadWithFirstDoc),
"Doc for first overload.")
comment_verifier.check(inspect.getdoc(doxygen_overloads.overloadWithSecondDoc),
"Doc for second overload.")
comment_verifier.check(inspect.getdoc(doxygen_overloads.overloadWithBothDocs),
r"""*Overload 1:*
Doc for both overloads, first.
|
*Overload 2:*
Doc for both overloads, second.""")
comment_verifier.check(inspect.getdoc(doxygen_overloads.overloadWithSomeDocs),
r"""*Overload 1:*
Doc for some overloads, first.
|
*Overload 2:*
Doc for some overloads, third.""")
comment_verifier.check(inspect.getdoc(doxygen_overloads.overloadWithSomeOtherDocs),
r"""*Overload 1:*
Doc for some other overloads, first.
|
*Overload 2:*
Doc for some other overloads, second.""")
comment_verifier.check(inspect.getdoc(doxygen_overloads.S.staticOverloadWithFirstDoc),
"Doc for first static overload.")
comment_verifier.check(inspect.getdoc(doxygen_overloads.S.memberOverloadWithFirstDoc),
"Doc for first member overload.")
# As mentioned in doxygen_parsing_runme.py, docstrings for __init__ can't be specified when using "-builtin", so skip these checks in this case.
if not doxygen_overloads.is_python_builtin():
# Do not check for ClassWithNoDoc ctor docstring, as Python provides a standard one
# ('Initialize self. See help(type(self)) for accurate signature.') if none is explicitly specified.
comment_verifier.check(inspect.getdoc(doxygen_overloads.ClassWithFirstDoc.__init__),
"Doc for first ctor.")
comment_verifier.check(inspect.getdoc(doxygen_overloads.ClassWithSecondDoc.__init__),
"Doc for second ctor.")
comment_verifier.check(inspect.getdoc(doxygen_overloads.ClassWithBothDocs.__init__),
r"""*Overload 1:*
Doc for both ctors, first.
|
*Overload 2:*
Doc for both ctors, second.""")
comment_verifier.check(inspect.getdoc(doxygen_overloads.ClassWithSomeDocs.__init__),
r"""*Overload 1:*
Doc for some ctors, first.
|
*Overload 2:*
Doc for some ctors, third.""")
comment_verifier.check(inspect.getdoc(doxygen_overloads.ClassWithSomeOtherDocs.__init__),
r"""*Overload 1:*
Doc for some other ctors, first.
|
*Overload 2:*
Doc for some other ctors, second.""")

View File

@ -7,6 +7,5 @@ cacheMetaData(1)
v <- enumToInteger('kValue', '_MyEnum')
print(v)
# temporarily removed until fixed (in progress, see Github patch #500)
#unittest(v,4)
unittest(v,4)
q(save="no")

View File

@ -18,6 +18,8 @@
#define XX1 "\x57\x58\x59"
#define ZS1 "\0"
#define ES1 ""
#define QQ1 "\b00! \18\14200!"
#define PR1 ("paren")
%}
%constant SS2="ÆÎOU\n";
%constant AA2="A\rB\nC";
@ -25,6 +27,8 @@
%constant XX2="\x57\x58\x59";
%constant ZS2="\0";
%constant ES2="";
%constant QQ2="\b00! \18\14200!";
%constant PR2=("paren");
%inline %{
static const char *SS3 = "ÆÎOU\n";
@ -33,6 +37,8 @@ static const char *EE3 = "\124\125\126";
static const char *XX3 = "\x57\x58\x59";
static const char *ZS3 = "\0";
static const char *ES3 = "";
static const char *QQ3 = "\b00! \18\14200!";
static const char *PR3 = ("paren");
struct things {
const char * defarguments1(const char *SS4 = "ÆÎOU\n") { return SS4; }
const char * defarguments2(const char *AA4 = "A\rB\nC") { return AA4; }
@ -40,5 +46,7 @@ struct things {
const char * defarguments4(const char *XX4 = "\x57\x58\x59") { return XX4; }
const char * defarguments5(const char *ZS4 = "\0") { return ZS4; }
const char * defarguments6(const char *ES4 = "") { return ES4; }
const char * defarguments7(const char *QQ4 = "\b00! \18\14200!") { return QQ4; }
const char * defarguments8(const char *PR4 = ("paren")) { return PR4; }
};
%}

View File

@ -4,6 +4,8 @@
#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
#pragma SWIG nowarn=SWIGWARN_PARSE_NAMED_NESTED_CLASS
%warnfilter(SWIGWARN_PARSE_TEMPLATE_NESTED) ns::OuterClass::Inner1;
%warnfilter(SWIGWARN_PARSE_TEMPLATE_NESTED) ns::OuterClass::Inner2;
#endif
namespace ns {

View File

@ -0,0 +1,35 @@
%module using_extend_flatten
// Issue #1581 - how to flatten all the methods in a base class into a derived class.
// Just ExtendDerived is exposed including the methods from the base class, exposed via a using declaration.
%extend ExtendDerived {
using ExtendBase::one;
}
%ignore ExtendBase;
%inline %{
class ExtendBase
{
public:
void one();
virtual void two();
virtual void three();
virtual ~ExtendBase() {}
};
class ExtendDerived : public ExtendBase
{
public:
void two();
void three();
};
%}
%{
void ExtendBase::one() {}
void ExtendBase::two() {}
void ExtendBase::three() {}
void ExtendDerived::two() {}
void ExtendDerived::three() {}
%}

View File

@ -20,6 +20,7 @@
%include <d/dkw.swg>
%include <go/gokw.swg>
%include <java/javakw.swg>
%include <javascript/javascriptkw.swg>
%include <lua/luakw.swg>
%include <ocaml/ocamlkw.swg>
%include <perl5/perlkw.swg>

View File

@ -1398,6 +1398,7 @@ SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE)
%pragma(java) jniclassclassmodifiers="public class"
%pragma(java) moduleclassmodifiers="public class"
%pragma(java) constantsmodifiers="public interface"
/* 64-bit architecture specific typemaps */
#if defined(SWIGWORDSIZE64)

View File

@ -1,8 +1,8 @@
#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_
#define JAVASCRIPT_JAVASCRIPTKW_SWG_
/* Warnings for Java keywords */
#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s") `x`
/* Warnings for Javascript keywords: note that we allow the use of keywords for members, as they're used as property names in JS and properties don't conflict with keywords. */
#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",%$not %$ismember,rename="_%s") `x`
/* Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords */
/* This the union of all currently reserved keywords in ECMAScript 4 to 6 in both sloppy and strict mode */

View File

@ -12,7 +12,7 @@
%include <javascripthelpers.swg>
%include <javascriptkw.swg>
%include <javascript/javascriptkw.swg>
%include <javascriptcode.swg>

View File

@ -10,7 +10,7 @@
%include <javascriptruntime.swg>
%include <javascriptkw.swg>
%include <javascript/javascriptkw.swg>
%include <javascriptcode.swg>

View File

@ -12,7 +12,7 @@
%include <javascripthelpers.swg>
%include <javascriptkw.swg>
%include <javascript/javascriptkw.swg>
%include <javascriptcode.swg>

View File

@ -273,6 +273,9 @@ SwigPyStaticVar_Type(void) {
#if PY_VERSION_HEX >= 0x030c0000
0, /* tp_watched */
#endif
#if PY_VERSION_HEX >= 0x030d00a4
0, /* tp_versions_used */
#endif
#ifdef COUNT_ALLOCS
0, /* tp_allocs */
0, /* tp_frees */
@ -364,6 +367,9 @@ SwigPyObjectType(void) {
#if PY_VERSION_HEX >= 0x030c0000
0, /* tp_watched */
#endif
#if PY_VERSION_HEX >= 0x030d00a4
0, /* tp_versions_used */
#endif
#ifdef COUNT_ALLOCS
0, /* tp_allocs */
0, /* tp_frees */

View File

@ -392,6 +392,9 @@ swig_varlink_type(void) {
#if PY_VERSION_HEX >= 0x030C0000
0, /* tp_watched */
#endif
#if PY_VERSION_HEX >= 0x030d00a4
0, /* tp_versions_used */
#endif
#ifdef COUNT_ALLOCS
0, /* tp_allocs */
0, /* tp_frees */
@ -1025,6 +1028,9 @@ SwigPyObject_TypeOnce(void) {
#if PY_VERSION_HEX >= 0x030C0000
0, /* tp_watched */
#endif
#if PY_VERSION_HEX >= 0x030d00a4
0, /* tp_versions_used */
#endif
#ifdef COUNT_ALLOCS
0, /* tp_allocs */
0, /* tp_frees */
@ -1244,6 +1250,9 @@ SwigPyPacked_TypeOnce(void) {
#if PY_VERSION_HEX >= 0x030C0000
0, /* tp_watched */
#endif
#if PY_VERSION_HEX >= 0x030d00a4
0, /* tp_versions_used */
#endif
#ifdef COUNT_ALLOCS
0, /* tp_allocs */
0, /* tp_frees */

View File

@ -8,6 +8,12 @@
#include <filesystem>
%}
namespace std {
namespace filesystem {
class path;
}
}
%fragment("SWIG_std_filesystem", "header") {
SWIGINTERN PyObject *SWIG_std_filesystem_importPathClass() {
PyObject *module = PyImport_ImportModule("pathlib");

View File

@ -333,7 +333,6 @@ SWIG_R_ConvertPtrAndOwn(SEXP obj, void **ptr, swig_type_info *ty, int flags, int
if (ptr) *ptr = vptr;
} else {
swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
int newmemory = 0;
if (ptr) {
int newmemory = 0;
*ptr = SWIG_TypeCast(tc, vptr, &newmemory);

View File

@ -43,7 +43,7 @@ extern "C" {
extern void scanner_set_main_input_file(String *file);
extern String *scanner_get_main_input_file(void);
extern void Swig_cparse_follow_locators(int);
extern void start_inline(char *, int);
extern void scanner_start_inline(String *, int);
extern String *scanner_ccode;
extern int yylex(void);
@ -80,6 +80,4 @@ extern "C" {
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
}
#define COMPOUND_EXPR_VAL(dtype) \
((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
#endif

View File

@ -141,14 +141,14 @@ void scanner_file(DOHFile * f) {
}
/* ----------------------------------------------------------------------------
* start_inline(char *text, int line)
* scanner_start_inline(String *text, int line)
*
* Take a chunk of text and recursively feed it back into the scanner. Used
* by the %inline directive.
* ------------------------------------------------------------------------- */
void start_inline(char *text, int line) {
String *stext = NewString(text);
void scanner_start_inline(String *text, int line) {
String *stext = Copy(text);
Seek(stext,0,SEEK_SET);
Setfile(stext,cparse_file);
@ -377,11 +377,11 @@ static int yylook(void) {
return TYPE_RAW;
case SWIG_TOKEN_STRING:
yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
yylval.str = NewString(Scanner_text(scan));
return STRING;
case SWIG_TOKEN_WSTRING:
yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
yylval.str = NewString(Scanner_text(scan));
return WSTRING;
case SWIG_TOKEN_CHAR:

View File

@ -427,11 +427,23 @@ static void add_symbols(Node *n) {
if (inclass) {
String *name = Getattr(n, "name");
if (isfriend) {
/* For friends, set the scope to the same as the class that the friend is defined/declared in, that is, pop scope once */
/* Friends methods in a class are declared in the namespace enclosing the class (outer most class if a nested class) */
String *prefix = name ? Swig_scopename_prefix(name) : 0;
Node *outer = currentOuterClass;
Symtab *namespace_symtab;
old_prefix = Namespaceprefix;
old_scope = Swig_symbol_popscope();
old_scope = Swig_symbol_current();
assert(outer);
while (Getattr(outer, "nested:outer")) {
outer = Getattr(outer, "nested:outer");
}
namespace_symtab = Getattr(outer, "sym:symtab");
if (!namespace_symtab)
namespace_symtab = Getattr(outer, "unofficial:symtab");
Swig_symbol_setscope(namespace_symtab);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
if (!prefix) {
/* To check - this should probably apply to operators too */
if (name && !is_operator(name) && Namespaceprefix) {
@ -441,13 +453,11 @@ static void add_symbols(Node *n) {
}
} else {
/* Qualified friend declarations should not be possible as they are ignored in the parse tree */
/* TODO: uncomment out for swig-4.3.0
assert(0);
*/
}
} else if (Equal(nodeType(n), "using")) {
String *uname = Getattr(n, "uname");
Node *cls = current_class ? current_class : currentOuterClass; /* Current class seems to vary depending on whether it is a template class or a plain class */
Node *cls = currentOuterClass;
String *nprefix = 0;
String *nlast = 0;
Swig_scopename_split(uname, &nprefix, &nlast);
@ -695,12 +705,9 @@ static void add_symbols(Node *n) {
/* add symbols a parse tree node copy */
static void add_symbols_copy(Node *n) {
String *name;
int emode = 0;
while (n) {
char *cnodeType = Char(nodeType(n));
if (strcmp(cnodeType,"access") == 0) {
if (Equal(nodeType(n), "access")) {
String *kind = Getattr(n,"kind");
if (Strcmp(kind,"public") == 0) {
cplus_mode = CPLUS_PUBLIC;
@ -716,7 +723,7 @@ static void add_symbols_copy(Node *n) {
add_oldname = Getattr(n,"sym:name");
if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) {
int old_inclass = -1;
Node *old_current_class = 0;
Node *oldCurrentOuterClass = 0;
if (add_oldname) {
DohIncref(add_oldname);
/* Disable this, it prevents %rename to work with templates */
@ -738,30 +745,33 @@ static void add_symbols_copy(Node *n) {
Swig_symbol_cadd(Getattr(n,"partialargs"),n);
}
add_only_one = 0;
name = Getattr(n,"name");
if (Getattr(n,"requires_symtab")) {
Swig_symbol_newscope();
Swig_symbol_setscopename(name);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
}
if (strcmp(cnodeType,"class") == 0) {
if (Equal(nodeType(n), "class")) {
/* add_symbols() above sets "sym:symtab", so "unofficial:symtab" is not required */
old_inclass = inclass;
oldCurrentOuterClass = currentOuterClass;
inclass = 1;
old_current_class = current_class;
current_class = n;
currentOuterClass = n;
if (Strcmp(Getattr(n,"kind"),"class") == 0) {
cplus_mode = CPLUS_PRIVATE;
} else {
cplus_mode = CPLUS_PUBLIC;
}
}
if (strcmp(cnodeType,"extend") == 0) {
if (Equal(nodeType(n), "extend")) {
emode = cplus_mode;
cplus_mode = CPLUS_PUBLIC;
}
if (Getattr(n, "requires_symtab")) {
Swig_symbol_newscope();
Swig_symbol_setscopename(Getattr(n, "name"));
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
}
add_symbols_copy(firstChild(n));
if (strcmp(cnodeType,"extend") == 0) {
if (Equal(nodeType(n), "extend")) {
cplus_mode = emode;
}
if (Getattr(n,"requires_symtab")) {
@ -774,17 +784,17 @@ static void add_symbols_copy(Node *n) {
Delete(add_oldname);
add_oldname = 0;
}
if (strcmp(cnodeType,"class") == 0) {
if (Equal(nodeType(n), "class")) {
inclass = old_inclass;
current_class = old_current_class;
currentOuterClass = oldCurrentOuterClass;
}
} else {
if (strcmp(cnodeType,"extend") == 0) {
if (Equal(nodeType(n), "extend")) {
emode = cplus_mode;
cplus_mode = CPLUS_PUBLIC;
}
add_symbols_copy(firstChild(n));
if (strcmp(cnodeType,"extend") == 0) {
if (Equal(nodeType(n), "extend")) {
cplus_mode = emode;
}
}
@ -1242,6 +1252,7 @@ static Node *nested_forward_declaration(const String *storage, const String *kin
Setattr(n, "name", sname);
Setattr(n, "storage", storage);
Setattr(n, "sym:weak", "1");
SetFlag(n, "nested:forward");
add_symbols(n);
nn = n;
}
@ -1608,8 +1619,54 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
const char *id;
List *bases;
struct Define {
// The value of the expression as C/C++ code.
String *val;
String *rawval;
// If type is a string or char type, this is the actual value of that
// string or char type as a String. This is useful in cases where we
// want to emit the string in the target language - we could just try
// emitting the C/C++ code for the literal, but that won't always be
// a valid string literal in most target languages.
//
// SWIG's scanner reads the string or character literal in the source code
// and interprets quoting and escape sequences. Concatenation of adjacent
// string literals is currently handled here in the parser (though
// technically it should happen before parsing).
//
// stringval holds the actual value of the string (from the scanner,
// taking into account concatenation of adjacent string literals).
// Then val is created by escaping stringval using SWIG's %(escape)s
// Printf specification, and adding the appropriate quotes (and
// an L-prefix for wide literals). So val is also a C/C++ source
// representation of the string, but may not be the same representation
// as in the source code (it should be equivalent though).
//
// Some examples:
//
// C/C++ source stringval val Notes
// ------------- ----------- --------- -------
// "bar" bar "bar"
// "b\x61r" bar "bar"
// "b\141r" bar "bar"
// "b" "ar" bar "bar"
// u8"bar" bar "bar" C++11
// R"bar" bar "bar" C++11
// "\228\22" "8" "\"8\""
// "\\\"\'" \"' "\\\"\'"
// R"(\"')" \"' "\\\"\'" C++11
// L"bar" bar L"bar"
// L"b" L"ar" bar L"bar"
// L"b" "ar" bar L"bar" C++11
// "b" L"ar" bar L"bar" C++11
// 'x' x 'x'
// '\"' " '\"'
// '\42' " '\"'
// '\042' " '\"'
// '\x22' " '\"'
//
// Zero bytes are allowed in stringval (DOH's String can hold a string
// with embedded zero bytes), but handling may currently be buggy in
// places.
String *stringval;
int type;
/* The type code for the argument when the top level operator is unary.
* This is useful because our grammar parses cases such as (7)*6 as a
@ -1663,7 +1720,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%token <id> ID
%token <str> HBLOCK
%token <id> POUND
%token <id> STRING WSTRING
%token <str> STRING WSTRING
%token <loc> INCLUDE IMPORT INSERT
%token <str> CHARCONST WCHARCONST
%token <dtype> NUM_INT NUM_DOUBLE NUM_FLOAT NUM_LONGDOUBLE NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
@ -2053,7 +2110,7 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI {
Setattr($$, "name", $identifier);
Setattr($$, "type", type);
Setattr($$, "value", $definetype.val);
if ($definetype.rawval) Setattr($$, "rawval", $definetype.rawval);
if ($definetype.stringval) Setattr($$, "stringval", $definetype.stringval);
Setattr($$, "storage", "%constant");
SetFlag($$, "feature:immutable");
add_symbols($$);
@ -2073,7 +2130,7 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI {
Setattr($$, "name", $declarator.id);
Setattr($$, "type", $type);
Setattr($$, "value", $def_args.val);
if ($def_args.rawval) Setattr($$, "rawval", $def_args.rawval);
if ($def_args.stringval) Setattr($$, "stringval", $def_args.stringval);
Setattr($$, "storage", "%constant");
SetFlag($$, "feature:immutable");
add_symbols($$);
@ -2092,7 +2149,7 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI {
Setattr($$, "name", $direct_declarator.id);
Setattr($$, "type", $type);
Setattr($$, "value", $def_args.val);
if ($def_args.rawval) Setattr($$, "rawval", $def_args.rawval);
if ($def_args.stringval) Setattr($$, "stringval", $def_args.stringval);
Setattr($$, "storage", "%constant");
SetFlag($$, "feature:immutable");
add_symbols($$);
@ -2270,7 +2327,7 @@ inline_directive : INLINE HBLOCK {
Setline($HBLOCK,cparse_start_line);
Setfile($HBLOCK,cparse_file);
cpps = Preprocessor_parse($HBLOCK);
start_inline(Char(cpps), cparse_start_line);
scanner_start_inline(cpps, cparse_start_line);
Delete($HBLOCK);
Delete(cpps);
}
@ -2294,7 +2351,7 @@ inline_directive : INLINE HBLOCK {
Setattr($$,"code", code);
Delete(code);
cpps=Copy(scanner_ccode);
start_inline(Char(cpps), start_line);
scanner_start_inline(cpps, start_line);
Delete(cpps);
}
}
@ -2960,10 +3017,13 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
}
add_symbols_copy(templnode);
if (Equal(nodeType(templnode), "classforward")) {
if (Equal(nodeType(templnode), "classforward") && !(GetFlag(templnode, "feature:ignore") || GetFlag(templnode, "hidden"))) {
SWIG_WARN_NODE_BEGIN(templnode);
/* A full template class definition is required in order to wrap a template class as a proxy class so this %template is ineffective. */
Swig_warning(WARN_PARSE_TEMPLATE_FORWARD, cparse_file, cparse_line, "Template forward class instantiation '%s' with name '%s' is ineffective.\n", Swig_name_decl(templnode), Getattr(templnode, "sym:name"));
if (GetFlag(templnode, "nested:forward"))
Swig_warning(WARN_PARSE_TEMPLATE_NESTED, cparse_file, cparse_line, "Unsupported template nested class '%s' cannot be used to instantiate a full template class with name '%s'.\n", Swig_name_decl(templnode), Getattr(templnode, "sym:name"));
else
Swig_warning(WARN_PARSE_TEMPLATE_FORWARD, cparse_file, cparse_line, "Template forward class '%s' cannot be used to instantiate a full template class with name '%s'.\n", Swig_name_decl(templnode), Getattr(templnode, "sym:name"));
SWIG_WARN_NODE_END(templnode);
}
@ -3182,6 +3242,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
Setattr($$,"decl",decl);
Setattr($$,"parms",$declarator.parms);
Setattr($$,"value",$initializer.val);
if ($initializer.stringval) Setattr($$, "stringval", $initializer.stringval);
Setattr($$,"throws",$cpp_const.throws);
Setattr($$,"throw",$cpp_const.throwf);
Setattr($$,"noexcept",$cpp_const.nexcept);
@ -3412,6 +3473,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
Setattr($$, "name", $idcolon);
Setattr($$, "decl", NewStringEmpty());
Setattr($$, "value", $definetype.val);
if ($definetype.stringval) Setattr($$, "stringval", $definetype.stringval);
Setattr($$, "valuetype", type);
}
;
@ -3430,6 +3492,7 @@ c_decl_tail : SEMI {
Setattr($$,"decl",$declarator.type);
Setattr($$,"parms",$declarator.parms);
Setattr($$,"value",$initializer.val);
if ($initializer.stringval) Setattr($$, "stringval", $initializer.stringval);
Setattr($$,"throws",$cpp_const.throws);
Setattr($$,"throw",$cpp_const.throwf);
Setattr($$,"noexcept",$cpp_const.nexcept);
@ -3797,8 +3860,8 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
}
Setattr($$,"allows_typedef","1");
/* preserve the current scope */
Setattr($$,"prev_symtab",Swig_symbol_current());
/* Temporary unofficial symtab for use until add_symbols() adds "sym:symtab" */
Setattr($$, "unofficial:symtab", Swig_symbol_current());
/* If the class name is qualified. We need to create or lookup namespace/scope entries */
scope = resolve_create_node_scope($idcolon, 1, &errored_flag);
@ -3896,8 +3959,8 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
}
if (!currentOuterClass)
inclass = 0;
cscope = Getattr($$, "prev_symtab");
Delattr($$, "prev_symtab");
cscope = Getattr($$, "unofficial:symtab");
Delattr($$, "unofficial:symtab");
/* Check for pure-abstract class */
Setattr($$,"abstracts", pure_abstracts($cpp_members));
@ -4042,6 +4105,10 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
Setattr($$,"storage",$storage_class);
Setattr($$,"unnamed",unnamed);
Setattr($$,"allows_typedef","1");
/* Temporary unofficial symtab for use until add_symbols() adds "sym:symtab" */
Setattr($$, "unofficial:symtab", Swig_symbol_current());
if (currentOuterClass) {
SetFlag($$, "nested");
Setattr($$, "nested:outer", currentOuterClass);
@ -4071,6 +4138,7 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
List *bases = 0;
String *name = 0;
Node *n;
Symtab *cscope;
Classprefix = 0;
(void)$node;
$$ = currentOuterClass;
@ -4079,6 +4147,10 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
inclass = 0;
else
restore_access_mode($$);
cscope = Getattr($$, "unofficial:symtab");
Delattr($$, "unofficial:symtab");
unnamed = Getattr($$,"unnamed");
/* Check for pure-abstract class */
Setattr($$,"abstracts", pure_abstracts($cpp_members));
@ -4086,9 +4158,6 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
String *name = n ? Copy(Getattr(n, "name")) : 0;
$$ = nested_forward_declaration($storage_class, $cpptype, 0, name, n);
Swig_symbol_popscope();
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
} else if (n) {
appendSibling($$,n);
/* If a proper typedef name was given, we'll use it to set the scope name */
@ -4158,9 +4227,9 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
add_symbols($$);
add_symbols(n);
Delattr($$, "class_rename");
}else if (cparse_cplusplus)
} else if (cparse_cplusplus)
$$ = 0; /* ignore unnamed structs for C++ */
Delete(unnamed);
Delete(unnamed);
} else { /* unnamed struct w/o declarator*/
Swig_symbol_popscope();
Delete(Namespaceprefix);
@ -4169,6 +4238,9 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L
Delete($$);
$$ = $cpp_members; /* pass member list to outer class/namespace (instead of self)*/
}
Swig_symbol_setscope(cscope);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
Classprefix = currentOuterClass ? Getattr(currentOuterClass, "Classprefix") : 0;
}
;
@ -4454,7 +4526,8 @@ templateparameter : templcpptype def_args {
$$ = NewParmWithoutFileLineInfo($templcpptype, 0);
Setfile($$, cparse_file);
Setline($$, cparse_line);
Setattr($$, "value", $def_args.rawval ? $def_args.rawval : $def_args.val);
Setattr($$, "value", $def_args.val);
if ($def_args.stringval) Setattr($$, "stringval", $def_args.stringval);
}
| TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon def_args {
$$ = NewParmWithoutFileLineInfo(NewStringf("template< %s > %s %s", ParmList_str_defaultargs($template_parms), $cpptype, $idcolon), $idcolon);
@ -5255,6 +5328,7 @@ valparm : parm {
Setfile($$,cparse_file);
Setline($$,cparse_line);
Setattr($$,"value",$valexpr.val);
if ($valexpr.stringval) Setattr($$, "stringval", $valexpr.stringval);
}
;
@ -5282,7 +5356,7 @@ def_args : EQUAL definetype {
| EQUAL LBRACE {
if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$.val = NewString(scanner_ccode);
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_UNKNOWN;
$$.unary_arg_type = 0;
$$.bitfield = 0;
@ -5293,7 +5367,7 @@ def_args : EQUAL definetype {
}
| COLON expr {
$$.val = 0;
$$.rawval = 0;
$$.stringval = 0;
$$.type = 0;
$$.bitfield = $expr.val;
$$.throws = 0;
@ -5303,7 +5377,7 @@ def_args : EQUAL definetype {
}
| %empty {
$$.val = 0;
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_UNKNOWN;
$$.unary_arg_type = 0;
$$.bitfield = 0;
@ -5316,26 +5390,28 @@ def_args : EQUAL definetype {
parameter_declarator : declarator def_args {
$$ = $declarator;
$$.defarg = $def_args.rawval ? $def_args.rawval : $def_args.val;
$$.defarg = $def_args.val;
}
| abstract_declarator def_args {
$$ = $abstract_declarator;
$$.defarg = $def_args.rawval ? $def_args.rawval : $def_args.val;
$$.defarg = $def_args.val;
}
| def_args {
$$.type = 0;
$$.id = 0;
$$.defarg = $def_args.rawval ? $def_args.rawval : $def_args.val;
$$.defarg = $def_args.val;
}
/* Member function pointers with qualifiers. eg.
int f(short (Funcs::*parm)(bool) const); */
| direct_declarator LPAREN parms RPAREN cv_ref_qualifier {
| direct_declarator LPAREN parms RPAREN qualifiers_exception_specification {
SwigType *t;
$$ = $direct_declarator;
t = NewStringEmpty();
SwigType_add_function(t,$parms);
if ($cv_ref_qualifier.qualifier)
SwigType_push(t, $cv_ref_qualifier.qualifier);
if ($qualifiers_exception_specification.qualifier)
SwigType_push(t, $qualifiers_exception_specification.qualifier);
if ($qualifiers_exception_specification.nexcept)
SwigType_add_qualifier(t, "noexcept");
if (!$$.have_parms) {
$$.parms = $parms;
$$.have_parms = 1;
@ -6367,11 +6443,6 @@ type_specifier : TYPE_INT {
definetype : expr {
$$ = $expr;
if ($$.type == T_STRING) {
$$.rawval = NewStringf("\"%(escape)s\"",$$.val);
} else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) {
$$.rawval = NewStringf("%s", $$.val);
}
$$.qualifier = 0;
$$.refqualifier = 0;
$$.bitfield = 0;
@ -6390,7 +6461,7 @@ default_delete : deleted_definition
/* For C++ deleted definition '= delete' */
deleted_definition : DELETE_KW {
$$.val = NewString("delete");
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_STRING;
$$.unary_arg_type = 0;
$$.qualifier = 0;
@ -6406,7 +6477,7 @@ deleted_definition : DELETE_KW {
/* For C++ explicitly defaulted functions '= default' */
explicit_default : DEFAULT {
$$.val = NewString("default");
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_STRING;
$$.unary_arg_type = 0;
$$.qualifier = 0;
@ -6520,6 +6591,9 @@ edecl : identifier {
Setattr($$,"type",type);
SetFlag($$,"feature:immutable");
Setattr($$,"enumvalue", $etype.val);
if ($etype.stringval) {
Setattr($$, "enumstringval", $etype.stringval);
}
Setattr($$,"value",$identifier);
Delete(type);
}
@ -6609,10 +6683,40 @@ exprmem : ID[lhs] ARROW ID[rhs] {
exprsimple : exprnum
| exprmem
| string {
$$.val = $string;
$$.type = T_STRING;
$$.unary_arg_type = 0;
}
$$.stringval = $string;
$$.val = NewStringf("\"%(escape)s\"", $string);
$$.type = T_STRING;
$$.unary_arg_type = 0;
}
| wstring {
$$.stringval = $wstring;
$$.val = NewStringf("L\"%(escape)s\"", $wstring);
$$.type = T_WSTRING;
$$.unary_arg_type = 0;
}
| CHARCONST {
$$.stringval = $CHARCONST;
$$.val = NewStringf("'%(escape)s'", $CHARCONST);
$$.type = T_CHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| WCHARCONST {
$$.stringval = $WCHARCONST;
$$.val = NewStringf("L'%(escape)s'", $WCHARCONST);
$$.type = T_WCHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
/* In sizeof(X) X can be a type or expression. We don't actually
* need to parse X as the type of sizeof is always size_t (which
* SWIG handles as T_ULONG), so we just skip to the closing ')' and
@ -6633,6 +6737,14 @@ exprsimple : exprnum
$$.type = T_ULONG;
$$.unary_arg_type = 0;
}
/* noexcept(X) always has type bool. */
| NOEXCEPT LPAREN {
if (skip_balanced('(', ')') < 0) Exit(EXIT_FAILURE);
$$.val = NewStringf("noexcept%s", scanner_ccode);
Clear(scanner_ccode);
$$.type = T_BOOL;
$$.unary_arg_type = 0;
}
| SIZEOF ELLIPSIS LPAREN identifier RPAREN {
$$.val = NewStringf("sizeof...(%s)", $identifier);
$$.type = T_ULONG;
@ -6648,43 +6760,6 @@ exprsimple : exprnum
$$.type = T_ULONG;
$$.unary_arg_type = 0;
}
| wstring {
$$.val = $wstring;
$$.rawval = NewStringf("L\"%s\"", $$.val);
$$.type = T_WSTRING;
$$.unary_arg_type = 0;
}
| CHARCONST {
$$.val = NewString($CHARCONST);
if (Len($$.val)) {
$$.rawval = NewStringf("'%(escape)s'", $$.val);
} else {
$$.rawval = NewString("'\\0'");
}
$$.type = T_CHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| WCHARCONST {
$$.val = NewString($WCHARCONST);
if (Len($$.val)) {
$$.rawval = NewStringf("L\'%s\'", $$.val);
} else {
$$.rawval = NewString("L'\\0'");
}
$$.type = T_WCHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
;
valexpr : exprsimple
@ -6693,8 +6768,8 @@ valexpr : exprsimple
/* grouping */
| LPAREN expr RPAREN %prec CAST {
$$.val = NewStringf("(%s)",$expr.val);
if ($expr.rawval) {
$$.rawval = NewStringf("(%s)",$expr.rawval);
if ($expr.stringval) {
$$.stringval = Copy($expr.stringval);
}
$$.type = $expr.type;
}
@ -6783,7 +6858,7 @@ valexpr : exprsimple
| AND expr {
$$ = $expr;
$$.val = NewStringf("&%s", $expr.val);
$$.rawval = 0;
$$.stringval = 0;
/* Record the type code for expr so we can properly handle
* cases such as (6)&7 which get parsed using this rule then
* the rule for a C-style cast.
@ -6803,7 +6878,7 @@ valexpr : exprsimple
| STAR expr {
$$ = $expr;
$$.val = NewStringf("*%s", $expr.val);
$$.rawval = 0;
$$.stringval = 0;
/* Record the type code for expr so we can properly handle
* cases such as (6)*7 which get parsed using this rule then
* the rule for a C-style cast.
@ -6835,59 +6910,59 @@ exprnum : NUM_INT
;
exprcompound : expr[lhs] PLUS expr[rhs] {
$$.val = NewStringf("%s+%s", COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s+%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] MINUS expr[rhs] {
$$.val = NewStringf("%s-%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s-%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] STAR expr[rhs] {
$$.val = NewStringf("%s*%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s*%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] SLASH expr[rhs] {
$$.val = NewStringf("%s/%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s/%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] MODULO expr[rhs] {
$$.val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s%%%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] AND expr[rhs] {
$$.val = NewStringf("%s&%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s&%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] OR expr[rhs] {
$$.val = NewStringf("%s|%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s|%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] XOR expr[rhs] {
$$.val = NewStringf("%s^%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s^%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] LSHIFT expr[rhs] {
$$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s << %s", $lhs.val, $rhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] RSHIFT expr[rhs] {
$$.val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s >> %s", $lhs.val, $rhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] LAND expr[rhs] {
$$.val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s&&%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LOR expr[rhs] {
$$.val = NewStringf("%s||%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s||%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] EQUALTO expr[rhs] {
$$.val = NewStringf("%s==%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s==%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] NOTEQUALTO expr[rhs] {
$$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s!=%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Trying to parse `>` in the general case results in conflicts
@ -6895,7 +6970,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* parentheses and we can handle that case.
*/
| LPAREN expr[lhs] GREATERTHAN expr[rhs] RPAREN {
$$.val = NewStringf("(%s > %s)", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("(%s > %s)", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
@ -6905,15 +6980,15 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* covers all user-reported cases.
*/
| LPAREN exprsimple[lhs] LESSTHAN expr[rhs] RPAREN {
$$.val = NewStringf("(%s < %s)", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("(%s < %s)", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] GREATERTHANOREQUALTO expr[rhs] {
$$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s >= %s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LESSTHANOREQUALTO expr[rhs] {
$$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s <= %s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
@ -6929,59 +7004,59 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
//
// = += -= *= /= %= ^= &= |= <<= >>= , .* ->*.
| expr[lhs] PLUS ELLIPSIS {
$$.val = NewStringf("%s+...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s+...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] MINUS ELLIPSIS {
$$.val = NewStringf("%s-...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s-...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] STAR ELLIPSIS {
$$.val = NewStringf("%s*...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s*...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] SLASH ELLIPSIS {
$$.val = NewStringf("%s/...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s/...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] MODULO ELLIPSIS {
$$.val = NewStringf("%s%%...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s%%...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] AND ELLIPSIS {
$$.val = NewStringf("%s&...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s&...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] OR ELLIPSIS {
$$.val = NewStringf("%s|...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s|...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] XOR ELLIPSIS {
$$.val = NewStringf("%s^...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s^...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] LSHIFT ELLIPSIS {
$$.val = NewStringf("%s << ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s << ...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] RSHIFT ELLIPSIS {
$$.val = NewStringf("%s >> ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s >> ...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] LAND ELLIPSIS {
$$.val = NewStringf("%s&&...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s&&...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LOR ELLIPSIS {
$$.val = NewStringf("%s||...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s||...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] EQUALTO ELLIPSIS {
$$.val = NewStringf("%s==...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s==...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] NOTEQUALTO ELLIPSIS {
$$.val = NewStringf("%s!=...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s!=...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Trying to parse `>` in the general case results in conflicts
@ -6989,7 +7064,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* parentheses and we can handle that case.
*/
| LPAREN expr[lhs] GREATERTHAN ELLIPSIS RPAREN {
$$.val = NewStringf("(%s > ...)", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("(%s > ...)", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Similarly for `<` except trying to handle exprcompound on the
@ -6998,20 +7073,20 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* covers all user-reported cases.
*/
| LPAREN exprsimple[lhs] LESSTHAN ELLIPSIS RPAREN {
$$.val = NewStringf("(%s < %s)", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("(%s < %s)", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] GREATERTHANOREQUALTO ELLIPSIS {
$$.val = NewStringf("%s >= ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s >= ...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LESSTHANOREQUALTO ELLIPSIS {
$$.val = NewStringf("%s <= ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s <= ...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LESSEQUALGREATER expr[rhs] {
$$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s <=> %s", $lhs.val, $rhs.val);
/* `<=>` returns one of `std::strong_ordering`,
* `std::partial_ordering` or `std::weak_ordering`. The main
* thing to do with the return value in this context is to
@ -7025,7 +7100,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
$$.unary_arg_type = 0;
}
| expr[expr1] QUESTIONMARK expr[expr2] COLON expr[expr3] %prec QUESTIONMARK {
$$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($expr1), COMPOUND_EXPR_VAL($expr2), COMPOUND_EXPR_VAL($expr3));
$$.val = NewStringf("%s?%s:%s", $expr1.val, $expr2.val, $expr3.val);
/* This may not be exactly right, but is probably good enough
* for the purposes of parsing constant expressions. */
$$.type = promote($expr2.type, $expr3.type);
@ -7053,7 +7128,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
$$.type = promote_type($in.type);
}
| LNOT expr[in] {
$$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($in));
$$.val = NewStringf("!%s", $in.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| type LPAREN {
@ -7521,22 +7596,33 @@ idcolontailnt : DCOLON identifier idcolontailnt[in] {
;
/* Concatenated strings */
string : string[in] STRING {
$$ = NewStringf("%s%s", $in, $STRING);
}
| STRING { $$ = NewString($STRING);}
;
/* Concatenated wide strings: L"str1" L"str2" */
wstring : wstring[in] WSTRING {
$$ = NewStringf("%s%s", $in, $WSTRING);
}
/* Concatenated wide string and normal string literal: L"str1" "str2" */
/*not all the compilers support this concatenation mode, so perhaps better to postpone it*/
/*| wstring STRING { here $STRING comes unescaped, we have to escape it back first via NewStringf("%(escape)s)"
$$ = NewStringf("%s%s", $wstring, $STRING);
}*/
| WSTRING { $$ = NewString($WSTRING);}
;
string : string[in] STRING {
$$ = $in;
Append($$, $STRING);
Delete($STRING);
}
| STRING
;
wstring : wstring[in] WSTRING {
// Concatenated wide strings: L"str1" L"str2"
$$ = $in;
Append($$, $WSTRING);
Delete($WSTRING);
}
| wstring[in] STRING {
// Concatenated wide string and normal string literal: L"str1" "str2" (C++11).
$$ = $in;
Append($$, $STRING);
Delete($STRING);
}
| string[in] WSTRING {
// Concatenated normal string and wide string literal: "str1" L"str2" (C++11).
$$ = $in;
Append($$, $WSTRING);
Delete($WSTRING);
}
| WSTRING
;
stringbrace : string
| LBRACE {

View File

@ -207,7 +207,8 @@ int DohCmp(const DOH *obj1, const DOH *obj2) {
b2info = b2->type;
if ((b1info == b2info) && (b1info->doh_cmp))
return (b1info->doh_cmp) (b1, b2);
return 1;
/* finally compare pointers */
return b1 < b2 ? -1 : b1 == b2 ? 0 : 1;
}
/* -----------------------------------------------------------------------------

View File

@ -258,17 +258,9 @@ static void allocation_failed(size_t n, size_t size) {
/* Report and exit as directly as possible to try to avoid further issues due
* to lack of memory. */
if (n == 1) {
#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 199901L
fprintf(stderr, "Failed to allocate %zu bytes\n", size);
#else
fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size);
#endif
fprintf(stderr, "Failed to allocate %llu bytes\n", (unsigned long long)size);
} else {
#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 199901L
fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size);
#else
fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size);
#endif
fprintf(stderr, "Failed to allocate %llu*%llu bytes\n", (unsigned long long)n, (unsigned long long)size);
}
DohExit(EXIT_FAILURE);
}

View File

@ -1230,7 +1230,7 @@ DOHString *DohNewStringWithSize(const DOHString_or_char *so, int len) {
str->str = (char *) DohMalloc(max);
str->maxsize = max;
if (s) {
strncpy(str->str, s, len);
memcpy(str->str, s, len);
str->str[l] = 0;
str->len = l;
str->sp = l;

View File

@ -97,6 +97,7 @@
#define WARN_PARSE_ASSIGNED_VALUE 328
#define WARN_PARSE_USING_CONSTRUCTOR 329
#define WARN_PARSE_TEMPLATE_FORWARD 330
#define WARN_PARSE_TEMPLATE_NESTED 331
#define WARN_CPP11_LAMBDA 340
/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_DECLARATION 341 */

View File

@ -1344,9 +1344,13 @@ public:
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%(hexescape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
String *enumstringval = Getattr(n, "enumstringval");
if (enumstringval) {
// Escape character literal for C#.
String *val = NewStringf("'%(csharpescape)s'", enumstringval);
Setattr(n, "enumvalue", val);
Delete(val);
}
}
{
@ -1468,12 +1472,12 @@ public:
virtual int constantWrapper(Node *n) {
String *symname = Getattr(n, "sym:name");
SwigType *t = Getattr(n, "type");
SwigType *valuetype = Getattr(n, "valuetype");
ParmList *l = Getattr(n, "parms");
String *tm;
String *return_type = NewString("");
String *constants_code = NewString("");
Swig_save("constantWrapper", n, "value", NIL);
// The value as C# code.
String *csvalue = Copy(Getattr(n, "value"));
Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:cstype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:cstype:outattributes", NIL);
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
@ -1521,16 +1525,23 @@ public:
Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
}
// Default (octal) escaping is no good - change to hex escaped value
String *hexescaped_value = Getattr(n, "rawvalue") ? NewStringf("%(hexescape)s", Getattr(n, "rawvalue")) : 0;
// Add the stripped quotes back in
String *new_value = NewString("");
if (SwigType_type(t) == T_STRING) {
Printf(new_value, "\"%s\"", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(new_value, "\'%s\'", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
if (Getattr(n, "stringval")) {
char quote = 0;
switch (SwigType_type(t)) {
case T_STRING:
case T_WSTRING:
quote = '\"';
break;
case T_CHAR:
case T_WCHAR:
quote = '\'';
break;
}
if (quote) {
// Escape character literal for C#.
Delete(csvalue);
csvalue = NewStringf("%c%(csharpescape)s%c", quote, Getattr(n, "stringval"), quote);
}
}
const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
@ -1571,15 +1582,16 @@ public:
// Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
if (Getattr(n, "wrappedasconstant")) {
if (SwigType_type(t) == T_CHAR) {
if (SwigType_type(valuetype) == T_CHAR)
Printf(constants_code, "\'%(hexescape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
String *stringval = Getattr(n, "stringval");
if (stringval)
Printf(constants_code, "'%(csharpescape)s';\n", stringval);
else
Printf(constants_code, "(char)%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
}
} else {
Printf(constants_code, "%s;\n", Getattr(n, "value"));
Printf(constants_code, "%s;\n", csvalue);
}
}
@ -1593,9 +1605,9 @@ public:
}
// Cleanup
Swig_restore(n);
Delete(new_value);
Delete(return_type);
Delete(constants_code);
Delete(csvalue);
return SWIG_OK;
}

View File

@ -950,10 +950,6 @@ public:
if (swigtype == T_BOOL) {
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
}
// Emit the enum item.
@ -1449,20 +1445,8 @@ public:
// Note that this is only called for global constants, static member
// constants are already handled in staticmemberfunctionHandler().
Swig_save("constantWrapper", n, "value", NIL);
Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", NIL);
// Add the stripped quotes back in.
String *old_value = Getattr(n, "value");
SwigType *t = Getattr(n, "type");
if (SwigType_type(t) == T_STRING) {
Setattr(n, "value", NewStringf("\"%s\"", old_value));
Delete(old_value);
} else if (SwigType_type(t) == T_CHAR) {
Setattr(n, "value", NewStringf("\'%s\'", old_value));
Delete(old_value);
}
SetFlag(n, "feature:immutable");
int result = globalvariableHandler(n);
@ -1472,7 +1456,6 @@ public:
String *constants_code = NewString("");
SwigType *t = Getattr(n, "type");
SwigType *valuetype = Getattr(n, "valuetype");
ParmList *l = Getattr(n, "parms");
// Attach the non-standard typemaps to the parameter list.
@ -1505,20 +1488,9 @@ public:
} else {
// Just take the value from the C definition and hope it compiles in D.
if (Getattr(n, "wrappedasconstant")) {
if (SwigType_type(valuetype) == T_CHAR)
Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
else
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {
// Add the stripped quotes back in.
String* value = Getattr(n, "value");
if (SwigType_type(t) == T_STRING) {
Printf(constants_code, "\"%s\";\n", value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(constants_code, "\'%s\';\n", value);
} else {
Printf(constants_code, "%s;\n", value);
}
Printf(constants_code, "%s;\n", Getattr(n, "value"));
}
}

View File

@ -1803,28 +1803,31 @@ private:
virtual int constantWrapper(Node *n) {
SwigType *type = Getattr(n, "type");
if (!SwigType_issimple(type) && SwigType_type(type) != T_STRING) {
return goComplexConstant(n, type);
}
if (Swig_storage_isstatic(n)) {
return goComplexConstant(n, type);
}
String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
String *tm = goType(n, type);
String *value = Getattr(n, "value");
String *copy = NULL;
if (SwigType_type(type) == T_BOOL) {
if (Cmp(value, "true") != 0 && Cmp(value, "false") != 0) {
int typecode = SwigType_type(type);
if (typecode == T_STRING) {
String *stringval = Getattr(n, "stringval");
if (!stringval) {
return goComplexConstant(n, type);
}
} else if (SwigType_type(type) == T_STRING || SwigType_type(type) == T_CHAR) {
// Backslash sequences are somewhat different in Go and C/C++.
if (Strchr(value, '\\') != 0) {
copy = NewStringf("\"%(goescape)s\"", stringval);
value = copy;
} else if (typecode == T_CHAR) {
String *stringval = Getattr(n, "stringval");
if (!stringval || Len(stringval) != 1) {
return goComplexConstant(n, type);
}
// Backslash sequences are somewhat different in Go and C/C++.
copy = NewStringf("'%(goescape)s'", stringval);
value = copy;
} else if (!SwigType_issimple(type)) {
return goComplexConstant(n, type);
} else if (Swig_storage_isstatic(n)) {
return goComplexConstant(n, type);
} else if (typecode == T_BOOL) {
if (Cmp(value, "true") != 0 && Cmp(value, "false") != 0) {
return goComplexConstant(n, type);
}
} else {
@ -1865,29 +1868,23 @@ private:
}
}
if (need_copy) {
copy = Copy(value);
if (!copy) copy = Copy(value);
Replaceall(copy, p + len, "");
value = copy;
}
}
String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
if (!checkNameConflict(go_name, n, NULL)) {
Delete(tm);
Delete(go_name);
Delete(copy);
return SWIG_NOWRAP;
}
Printv(f_go_wrappers, "const ", go_name, " ", tm, " = ", NULL);
if (SwigType_type(type) == T_STRING) {
Printv(f_go_wrappers, "\"", value, "\"", NULL);
} else if (SwigType_type(type) == T_CHAR) {
Printv(f_go_wrappers, "'", value, "'", NULL);
} else {
Printv(f_go_wrappers, value, NULL);
}
String *tm = goType(n, type);
Printv(f_go_wrappers, "\n", NULL);
Printv(f_go_wrappers, "const ", go_name, " ", tm, " = ", value, "\n", NIL);
Delete(tm);
Delete(go_name);
@ -1977,10 +1974,9 @@ private:
return SWIG_NOWRAP;
}
String *rawval = Getattr(n, "rawval");
if (rawval && Len(rawval)) {
if (!Getattr(n, "stringval") && !Getattr(n, "enumvalueDeclaration:sym:name")) {
// Based on Swig_VargetToFunction
String *nname = NewStringf("(%s)", rawval);
String *nname = NewStringf("(%s)", Getattr(n, "value"));
String *call;
if (SwigType_isclass(type)) {
call = NewStringf("%s", nname);
@ -1996,28 +1992,12 @@ private:
String *get = NewString("");
Printv(get, Swig_cresult_name(), " = ", NULL);
char quote;
if (Getattr(n, "wrappedasconstant")) {
quote = '\0';
} else if (SwigType_type(type) == T_CHAR) {
quote = '\'';
} else if (SwigType_type(type) == T_STRING) {
if (SwigType_type(type) == T_STRING) {
Printv(get, "(char *)", NULL);
quote = '"';
} else {
quote = '\0';
}
if (quote != '\0') {
Printf(get, "%c", quote);
}
Printv(get, Getattr(n, "value"), NULL);
if (quote != '\0') {
Printf(get, "%c", quote);
}
Printv(get, ";\n", NULL);
Setattr(n, "wrap:action", get);

View File

@ -1262,8 +1262,7 @@ public:
char *name = GetChar(n, "name");
char *iname = GetChar(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
int constasvar = GetFlag(n, "feature:constasvar");

View File

@ -64,8 +64,7 @@ static List *collect_interface_methods(Node *n) {
static void collect_interface_bases(List *bases, Node *n) {
if (GetFlag(n, "feature:interface")) {
String *name = Getattr(n, "interface:name");
if (!Getattr(bases, name))
if (!Swig_item_in_list(bases, n))
Append(bases, n);
}
@ -82,10 +81,11 @@ static void collect_interface_bases(List *bases, Node *n) {
/* -----------------------------------------------------------------------------
* collect_interface_base_classes()
*
* Create a hash containing all the classes up the inheritance hierarchy
* Create a list containing all the classes up the inheritance hierarchy
* marked with feature:interface (including this class n).
* Stops going up the inheritance chain as soon as a class is found without
* feature:interface.
* Remove duplicate bases (in the event of multiple inheritance).
* The idea is to find all the base interfaces that a class must implement.
* ----------------------------------------------------------------------------- */

View File

@ -78,6 +78,7 @@ class JAVA:public Language {
String *module_interfaces; //interfaces for module class from %pragma
String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma
String *module_class_modifiers; //class modifiers for module class overridden by %pragma
String *constants_modifiers; //access modifiers for constants interface overridden by %pragma
String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
String *imclass_directors; // Intermediate class director code
@ -154,6 +155,7 @@ public:
module_interfaces(NULL),
imclass_class_modifiers(NULL),
module_class_modifiers(NULL),
constants_modifiers(NULL),
upcasts_code(NULL),
imclass_cppcasts_code(NULL),
imclass_directors(NULL),
@ -436,6 +438,7 @@ public:
module_interfaces = NewString("");
module_imports = NewString("");
module_class_modifiers = NewString("");
constants_modifiers = NewString("");
imclass_imports = NewString("");
imclass_cppcasts_code = NewString("");
imclass_directors = NewString("");
@ -643,7 +646,9 @@ public:
if (module_imports)
Printf(f_module, "%s\n", module_imports);
Printf(f_module, "public interface %s {\n", constants_interface_name);
if (Len(constants_modifiers) > 0)
Printf(f_module, "%s ", constants_modifiers);
Printf(f_module, "%s {\n", constants_interface_name);
// Write out all the global constants
Printv(f_module, module_class_constants_code, NIL);
@ -722,6 +727,8 @@ public:
module_imports = NULL;
Delete(module_class_modifiers);
module_class_modifiers = NULL;
Delete(constants_modifiers);
constants_modifiers = NULL;
Delete(imclass_imports);
imclass_imports = NULL;
Delete(imclass_cppcasts_code);
@ -1415,9 +1422,11 @@ public:
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
if (Getattr(n, "enumstringval")) {
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumstringval"));
Setattr(n, "enumvalue", val);
Delete(val);
}
}
{
@ -1533,12 +1542,10 @@ public:
virtual int constantWrapper(Node *n) {
String *symname = Getattr(n, "sym:name");
SwigType *t = Getattr(n, "type");
SwigType *valuetype = Getattr(n, "valuetype");
ParmList *l = Getattr(n, "parms");
String *tm;
String *return_type = NewString("");
String *constants_code = NewString("");
Swig_save("constantWrapper", n, "value", NIL);
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
@ -1591,16 +1598,6 @@ public:
Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
}
// Add the stripped quotes back in
String *new_value = NewString("");
if (SwigType_type(t) == T_STRING) {
Printf(new_value, "\"%s\"", Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
}
const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
@ -1634,12 +1631,9 @@ public:
} else {
// Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
if (Getattr(n, "wrappedasconstant")) {
if (SwigType_type(valuetype) == T_CHAR)
Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
else
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {
Printf(constants_code, "%s;\n", Getattr(n, "value"));
Printf(constants_code, "%s;\n", Getattr(n, "value"));
}
}
@ -1653,7 +1647,6 @@ public:
}
// Cleanup
Swig_restore(n);
Delete(new_value);
Delete(return_type);
Delete(constants_code);
return SWIG_OK;
@ -1699,6 +1692,7 @@ public:
* moduleimports - import statements for the module class
* moduleinterfaces - interface (implements) for the module class
*
* constantsmodifiers - access modifiers for the constants interface
* ----------------------------------------------------------------------------- */
virtual int pragmaDirective(Node *n) {
@ -1758,6 +1752,9 @@ public:
} else if (Strcmp(code, "moduleinterfaces") == 0) {
Delete(module_interfaces);
module_interfaces = Copy(strvalue);
} else if (Strcmp(code, "constantsmodifiers") == 0) {
Delete(constants_modifiers);
constants_modifiers = Copy(strvalue);
} else {
Swig_error(input_file, line_number, "Unrecognized pragma.\n");
}

View File

@ -1207,8 +1207,7 @@ int JSEmitter::emitConstant(Node *n) {
SwigType *type = Getattr(n, "type");
String *iname = Getattr(n, "sym:name");
String *wname = Swig_name_get(Getattr(current_namespace, NAME_MANGLED), iname);
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
// HACK: forcing usage of cppvalue for v8 (which turned out to fix typedef_struct.i, et. al)
if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {

View File

@ -629,24 +629,9 @@ int Language::constantDirective(Node *n) {
if (!ImportMode) {
Swig_require("constantDirective", n, "name", "?value", NIL);
String *name = Getattr(n, "name");
String *value = Getattr(n, "value");
if (!value) {
value = Copy(name);
} else {
/* if (checkAttribute(n,"type","char")) {
value = NewString(value);
} else {
value = NewStringf("%(escape)s", value);
}
*/
Setattr(n, "rawvalue", value);
value = NewStringf("%(escape)s", value);
if (!Len(value))
Append(value, "\\0");
/* Printf(stdout,"'%s' = '%s'\n", name, value); */
if (!Getattr(n, "value")) {
Setattr(n, "value", Getattr(n, "name"));
}
Setattr(n, "value", value);
this->constantWrapper(n);
Swig_restore(n);
return SWIG_OK;
@ -2201,7 +2186,7 @@ int Language::classDirectorInit(Node *n) {
int Language::classDirectorDestructor(Node *n) {
/*
Always emit the virtual destructor in the declaration and in the
compilation unit. Been explicit here can't make any damage, and
compilation unit. Being explicit here can't make any damage, and
can solve some nasty C++ compiler problems.
*/
File *f_directors = Swig_filebyname("director");

View File

@ -1053,8 +1053,7 @@ public:
lua_name = iname;
String *nsname = Copy(iname);
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
String *tm;
String *lua_name_v2 = 0;
String *tm_v2 = 0;

View File

@ -564,53 +564,21 @@ public:
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
String *var_name = NewString("");
String *proc_name = NewString("");
String *rvalue = NewString("");
String *temp = NewString("");
String *tm;
// Make a static variable;
Printf(var_name, "_wrap_const_%s", Swig_name_mangle_string(Getattr(n, "sym:name")));
// Build the name for scheme.
Printv(proc_name, iname, NIL);
Replaceall(proc_name, "_", "-");
if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
return SWIG_NOWRAP;
}
// See if there's a typemap
Printv(rvalue, value, NIL);
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
temp = Copy(rvalue);
Clear(rvalue);
Printv(rvalue, "\"", temp, "\"", NIL);
}
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
Delete(temp);
temp = Copy(rvalue);
Clear(rvalue);
Printv(rvalue, "'", temp, "'", NIL);
}
// See if there's a typemap
if ((tm = Swig_typemap_lookup("constant", n, name, 0))) {
Replaceall(tm, "$value", rvalue);
Replaceall(tm, "$value", value);
Printf(f_init, "%s\n", tm);
} else {
// Create variable and assign it a value
Printf(f_header, "static %s = ", SwigType_lstr(type, var_name));
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
if ((SwigType_type(type) == T_STRING)) {
Printf(f_header, "\"%s\";\n", value);
} else if (SwigType_type(type) == T_CHAR && !is_enum_item) {
Printf(f_header, "\'%s\';\n", value);
} else {
Printf(f_header, "%s;\n", value);
}
// Create a static variable and assign it a value
String *var_name = NewStringf("_wrap_const_%s", Swig_name_mangle_string(Getattr(n, "sym:name")));
Printf(f_header, "static %s = %s;\n", SwigType_lstr(type, var_name), value);
// Now create a variable declaration
@ -626,10 +594,8 @@ public:
variableWrapper(nn);
Delete(nn);
}
Delete(var_name);
}
Delete(proc_name);
Delete(rvalue);
Delete(temp);
return SWIG_OK;
}

View File

@ -898,8 +898,7 @@ public:
virtual int constantWrapper(Node *n) {
String *name = Getattr(n, "feature:symname");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
SwigType *qname = Getattr(n, "qualified:name");
if (qname)

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