Merge branch 'nested' - nested structs/classes support
* nested: Deprecation of the 'nestedworkaround' feature Ensure -c++out is not used with -c++ Add missing header to new source file Nested C class setters restored in c++out mode for Octave Classprefix fixed after private nested classes some comments and spaces added Fix template partial specialization detection Minor tweaks in Swig_feature_set Swig_offset_string moved to misc.c nested private classes are discarded while parsing nested relate functions are moved to nested.cxx and renamed accordingly out-of-scope template definitions fixed nested_private test disabled again fixed out-of-scope nested class definitions, added a test enabled nested C structs assignment (still disabled for Octave), added Java runtime test fixed nested_private test case for Java & C# Testcase of private nested class usage causing segfault C nested struct passed by value example Add in Travis testing for nested branch Add C++ nested class example Minor code improvements Cosmetics/code beautification of nested class support Nested classes support
This commit is contained in:
commit
314fae460b
61 changed files with 2438 additions and 1127 deletions
|
|
@ -57,3 +57,4 @@ script:
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- nested
|
||||
|
|
|
|||
|
|
@ -185,7 +185,6 @@ The following C++ features are not currently supported:</p>
|
|||
|
||||
<ul>
|
||||
<li>Overloaded versions of certain operators (new, delete, etc.)
|
||||
<li>Nested classes, see <a href="#SWIGPlus_nested_classes">Nested classes</a> for workarounds.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
@ -4965,143 +4964,56 @@ public:
|
|||
|
||||
<H2><a name="SWIGPlus_nested_classes"></a>6.27 Nested classes</H2>
|
||||
|
||||
|
||||
<p>
|
||||
There is some support for nested structs and unions when wrapping C code,
|
||||
see <a href="SWIG.html#SWIG_nested_structs">Nested structures</a> for further details.
|
||||
The added complexity of C++ compared to C means this approach does not work well for
|
||||
C++ code (when using the -c++ command line option).
|
||||
For C++, a nested class is treated much like an opaque pointer, so anything useful within the nested class, such as its
|
||||
methods and variables, are not accessible from the target language.
|
||||
True nested class support may be added to SWIG in the future, however,
|
||||
until then some of the following workarounds can be applied to improve the situation.
|
||||
If the target language supports the nested classes concept (like Java), the nested C++ classes
|
||||
are wrapped as nested target language proxy classes. (In case of Java - "static" nested classes.)
|
||||
Only public nested classes are wrapped. Otherwise there is little difference between nested and
|
||||
normal classes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It might be possible to use partial class information as often you can accept that the nested class is not needed,
|
||||
especially if it is not actually used in any methods you need from the target language.
|
||||
Imagine you are wrapping the following <tt>Outer</tt> class which contains a nested class <tt>Inner</tt>.
|
||||
The easiest thing to do is turn a blind eye to the warning that SWIG generates, or simply suppress it:
|
||||
If the target language doesn't support nested classes directly, or the support is not implemented in the
|
||||
language module (like for python currently), then the visible nested classes are moved to the same name
|
||||
space as the containing class (nesting hierarchy is "flattened"). The same behaviour may be turned on for
|
||||
C# and Java by the %feature ("flatnested"); If there is a class with the same name in the outer namespace
|
||||
the inner class (or the global one) may be renamed or ignored:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
|
||||
|
||||
class Outer {
|
||||
public:
|
||||
class Inner {
|
||||
public:
|
||||
...
|
||||
};
|
||||
Inner getInner();
|
||||
void useInner(const Inner& inner);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Note that if <tt>Inner</tt> can be used as an opaque type, the default wrapping approach suffices.
|
||||
For example, if the nested class does not need to be created from the target language, but can be obtained via a method
|
||||
call, such as the <tt>getInner()</tt> method above, the returned value can then be passed around, such as passed into the
|
||||
<tt>useInner()</tt> method.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
With some more effort the above situation can be improved somewhat and a nested class can be constructed and used
|
||||
from the target language much like any other non-nested class. Assuming we have the <tt>Outer</tt> class in a header file:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// File outer.h
|
||||
class Outer {
|
||||
public:
|
||||
class Inner {
|
||||
public:
|
||||
int var;
|
||||
Inner(int v = 0) : var(v) {}
|
||||
};
|
||||
Inner getInner();
|
||||
void useInner(const Inner& inner);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The following interface file works around the nested class limitations by redefining the nested class as a global class.
|
||||
A typedef for the compiler and the <tt>nestedworkaround</tt>
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a> is also required in
|
||||
order for the generated wrappers to compile. This flag simply removes all the type information from SWIG, so SWIG treats
|
||||
the nested class as if it had not been parsed at all.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// File : example.i
|
||||
%module example
|
||||
|
||||
// Redefine nested class in global scope in order for SWIG to generate
|
||||
// a proxy class. Only SWIG parses this definition.
|
||||
class Inner {
|
||||
%rename (Bar_Foo) Bar::Foo;
|
||||
class Foo {};
|
||||
class Bar {
|
||||
public:
|
||||
int var;
|
||||
Inner(int v = 0) : var(v) {}
|
||||
class Foo {};
|
||||
};
|
||||
|
||||
%nestedworkaround Outer::Inner;
|
||||
|
||||
%{
|
||||
#include "outer.h"
|
||||
%}
|
||||
%include "outer.h"
|
||||
|
||||
// We've fooled SWIG into thinking that Inner is a global class, so now we need
|
||||
// to trick the C++ compiler into understanding this apparent global type.
|
||||
%{
|
||||
typedef Outer::Inner Inner;
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The downside to this approach is a more complex interface file and having to maintain two definitions of <tt>Inner</tt>,
|
||||
the real one and the one in the interface file that SWIG parses.
|
||||
However, the upside is that all the methods/variables in the nested class are available from the target language
|
||||
as a proxy class is generated instead of treating the nested class as an opaque type.
|
||||
The proxy class can be constructed from the target language and passed into any methods accepting the nested class.
|
||||
Also note that the original header file is parsed unmodified.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Finally, conditional compilation can be used as a workaround to comment out nested class definitions in the actual headers,
|
||||
assuming you are able to modify them.
|
||||
<b>Compatibility Note:</b>
|
||||
Prior to SWIG-3.0.0, there was limited nested class support. Nested classes were treated as opaque pointers.
|
||||
However, there was a workaround for nested class support in these older versions requiring the user to replicate
|
||||
the nested class in the global scope, adding in a typedef for the nested class in the global scope and
|
||||
using the "nestedworkaround" feature on the nested class. This resulted in approximately the
|
||||
same behaviour as the "flatnested" feature. With proper nested class support now available in SWIG-3.0.0, this
|
||||
feature has been deprecated and no longer works requiring code changes. If you see the following warning:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<div class="shell">
|
||||
<pre>
|
||||
// File outer.h
|
||||
class Outer {
|
||||
public:
|
||||
#ifndef SWIG
|
||||
class Inner {
|
||||
public:
|
||||
...
|
||||
};
|
||||
#endif
|
||||
...
|
||||
};
|
||||
example.i:8: Warning 126: The nestedworkaround feature is deprecated
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This workaround used to be common when SWIG could not deal with nested classes particulary well.
|
||||
This should just be a last resort for unusual corner cases now as SWIG can parse nested classes and even handle nested template classes fairly well.
|
||||
consider using the "flatnested" feature discussed above which generates a non-nested proxy class, like the
|
||||
"nestedworkaround" feature did. Alternatively, use the default nested class code generation, which may generate an
|
||||
equivalent to a nested proxy class in the target language, depending on the target language support.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Compatibility Note:</b> SWIG-1.3.40 and earlier versions did not have the <tt>nestedworkaround</tt> feature
|
||||
SWIG-1.3.40 and earlier versions did not have the <tt>nestedworkaround</tt> feature
|
||||
and the generated code resulting from parsing nested classes did not always compile.
|
||||
Nested class warnings could also not be suppressed using %warnfilter.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -382,6 +382,7 @@ example.i(4) : Syntax error in input.
|
|||
<li>119. Deprecated <tt>%typemap(ignore)</tt>.
|
||||
<li>120. Deprecated command line option (-runtime, -noruntime).
|
||||
<li>121. Deprecated <tt>%name</tt> directive.
|
||||
<li>126. The 'nestedworkaround' feature is deprecated.
|
||||
</ul>
|
||||
|
||||
<H3><a name="Warnings_nn11"></a>14.9.2 Preprocessor (200-299)</H3>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ class
|
|||
enum
|
||||
extend
|
||||
funcptr
|
||||
nested
|
||||
reference
|
||||
simple
|
||||
template
|
||||
|
|
|
|||
19
Examples/csharp/nested/Makefile
Normal file
19
Examples/csharp/nested/Makefile
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
SWIGOPT =
|
||||
CSHARPSRCS = *.cs
|
||||
CSHARPFLAGS= -nologo -out:runme.exe
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile csharp_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' csharp_cpp
|
||||
$(MAKE) -f $(TOP)/Makefile CSHARPSRCS='$(CSHARPSRCS)' CSHARPFLAGS='$(CSHARPFLAGS)' csharp_compile
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile csharp_clean
|
||||
94
Examples/csharp/nested/example-cs.csproj
Normal file
94
Examples/csharp/nested/example-cs.csproj
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<VisualStudioProject>
|
||||
<CSHARP
|
||||
ProjectType = "Local"
|
||||
ProductVersion = "7.10.3077"
|
||||
SchemaVersion = "2.0"
|
||||
ProjectGuid = "{C17D27DF-4C57-4625-AEE0-A40C4F48FF1A}"
|
||||
>
|
||||
<Build>
|
||||
<Settings
|
||||
ApplicationIcon = ""
|
||||
AssemblyKeyContainerName = ""
|
||||
AssemblyName = "runme"
|
||||
AssemblyOriginatorKeyFile = ""
|
||||
DefaultClientScript = "JScript"
|
||||
DefaultHTMLPageLayout = "Grid"
|
||||
DefaultTargetSchema = "IE50"
|
||||
DelaySign = "false"
|
||||
OutputType = "Exe"
|
||||
PreBuildEvent = ""
|
||||
PostBuildEvent = ""
|
||||
RootNamespace = "runme"
|
||||
RunPostBuildEvent = "OnBuildSuccess"
|
||||
StartupObject = ""
|
||||
>
|
||||
<Config
|
||||
Name = "Debug"
|
||||
AllowUnsafeBlocks = "false"
|
||||
BaseAddress = "285212672"
|
||||
CheckForOverflowUnderflow = "false"
|
||||
ConfigurationOverrideFile = ""
|
||||
DefineConstants = "DEBUG;TRACE"
|
||||
DocumentationFile = ""
|
||||
DebugSymbols = "true"
|
||||
FileAlignment = "4096"
|
||||
IncrementalBuild = "false"
|
||||
NoStdLib = "false"
|
||||
NoWarn = ""
|
||||
Optimize = "false"
|
||||
OutputPath = ".\"
|
||||
RegisterForComInterop = "false"
|
||||
RemoveIntegerChecks = "false"
|
||||
TreatWarningsAsErrors = "false"
|
||||
WarningLevel = "4"
|
||||
/>
|
||||
<Config
|
||||
Name = "Release"
|
||||
AllowUnsafeBlocks = "false"
|
||||
BaseAddress = "285212672"
|
||||
CheckForOverflowUnderflow = "false"
|
||||
ConfigurationOverrideFile = ""
|
||||
DefineConstants = "TRACE"
|
||||
DocumentationFile = ""
|
||||
DebugSymbols = "false"
|
||||
FileAlignment = "4096"
|
||||
IncrementalBuild = "false"
|
||||
NoStdLib = "false"
|
||||
NoWarn = ""
|
||||
Optimize = "true"
|
||||
OutputPath = ".\"
|
||||
RegisterForComInterop = "false"
|
||||
RemoveIntegerChecks = "false"
|
||||
TreatWarningsAsErrors = "false"
|
||||
WarningLevel = "4"
|
||||
/>
|
||||
</Settings>
|
||||
<References/>
|
||||
</Build>
|
||||
<Files>
|
||||
<Include>
|
||||
<File
|
||||
RelPath = "example.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "examplePINVOKE.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "MotorCar.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
<File
|
||||
RelPath = "runme.cs"
|
||||
SubType = "Code"
|
||||
BuildAction = "Compile"
|
||||
/>
|
||||
</Include>
|
||||
</Files>
|
||||
</CSHARP>
|
||||
</VisualStudioProject>
|
||||
|
||||
158
Examples/csharp/nested/example-vc.vcproj
Normal file
158
Examples/csharp/nested/example-vc.vcproj
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="example"
|
||||
ProjectGUID="{C2302635-D489-4678-96B4-70F5309DCBE6}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;EXAMPLEVC_EXPORTS"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="example.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/example.pdb"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(OutDir)/example.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;EXAMPLEVC_EXPORTS"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="example.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(OutDir)/example.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="example.cxx">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="example_wrap.cxx">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath="example.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\example.i">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="echo Invoking SWIG...
|
||||
echo on
|
||||
..\..\..\swig.exe -c++ -csharp "$(InputPath)"
|
||||
@echo off"
|
||||
Outputs="$(InputName)_wrap.cxx"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="echo Invoking SWIG...
|
||||
echo on
|
||||
..\..\..\swig.exe -c++ -csharp "$(InputPath)"
|
||||
@echo off"
|
||||
Outputs="$(InputName)_wrap.cxx"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
62
Examples/csharp/nested/example.cxx
Normal file
62
Examples/csharp/nested/example.cxx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include "example.h"
|
||||
|
||||
int MotorCar::DesignOpinion::AceDesignCount = 0;
|
||||
int MotorCar::DesignOpinion::TotalDesignCount = 0;
|
||||
|
||||
int MotorCar::DesignOpinion::PercentScore() {
|
||||
return AceDesignCount*100/TotalDesignCount;
|
||||
}
|
||||
|
||||
MotorCar::Wheels::Wheels(Shape shape, size_t count) : shape(shape), count(count) {}
|
||||
|
||||
MotorCar::WindScreen::WindScreen(bool opaque) : opaque(opaque) {}
|
||||
|
||||
MotorCar::MotorCar(const std::string &name, const Wheels &wheels, const WindScreen &windscreen) : name(name), wheels(wheels), windscreen(windscreen) {}
|
||||
|
||||
MotorCar MotorCar::DesignFromComponents(const std::string &name, const Wheels &wheels, const WindScreen &windscreen) {
|
||||
MotorCar car = MotorCar(name, wheels, windscreen);
|
||||
DesignOpinion::TotalDesignCount++;
|
||||
if (car.wheels.Opinion().itrocks && car.windscreen.Opinion().itrocks)
|
||||
DesignOpinion::AceDesignCount++;
|
||||
return car;
|
||||
}
|
||||
|
||||
MotorCar::DesignOpinion MotorCar::Wheels::Opinion() {
|
||||
DesignOpinion opinion;
|
||||
opinion.itrocks = true;
|
||||
if (shape == Square) {
|
||||
opinion.itrocks = false;
|
||||
opinion.reason = "you'll have a few issues with wheel rotation";
|
||||
}
|
||||
if (count <= 2) {
|
||||
opinion.reason += opinion.itrocks ? "" : " and ";
|
||||
opinion.itrocks = false;
|
||||
opinion.reason += "a few more wheels are needed for stability";
|
||||
}
|
||||
if (opinion.itrocks)
|
||||
opinion.reason = "your choice of wheels was top notch";
|
||||
|
||||
return opinion;
|
||||
}
|
||||
|
||||
MotorCar::DesignOpinion MotorCar::WindScreen::Opinion() {
|
||||
DesignOpinion opinion;
|
||||
opinion.itrocks = !opaque;
|
||||
opinion.reason = opinion.itrocks ? "the driver will have a commanding view out the window" : "you can't see out the windscreen";
|
||||
return opinion;
|
||||
}
|
||||
|
||||
std::string MotorCar::WillItWork() {
|
||||
DesignOpinion wh = wheels.Opinion();
|
||||
DesignOpinion ws = windscreen.Opinion();
|
||||
std::string willit;
|
||||
if (wh.itrocks && ws.itrocks) {
|
||||
willit = "Great car design because " + wh.reason + " and " + ws.reason;
|
||||
} else {
|
||||
willit = "You need a rethink because ";
|
||||
willit += wh.itrocks ? "" : wh.reason;
|
||||
willit += (!wh.itrocks && !ws.itrocks) ? " and " : "";
|
||||
willit += ws.itrocks ? "" : ws.reason;
|
||||
}
|
||||
return willit;
|
||||
}
|
||||
48
Examples/csharp/nested/example.h
Normal file
48
Examples/csharp/nested/example.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#include <string>
|
||||
|
||||
/** Design a motor car from various components */
|
||||
struct MotorCar {
|
||||
|
||||
/** Information about an opinion of the design of a car component */
|
||||
struct DesignOpinion {
|
||||
bool itrocks;
|
||||
std::string reason;
|
||||
static int AceDesignCount;
|
||||
static int TotalDesignCount;
|
||||
static int PercentScore();
|
||||
};
|
||||
|
||||
/** Wheels component */
|
||||
struct Wheels {
|
||||
enum Shape { Round, Square };
|
||||
Wheels(Shape shape, size_t count);
|
||||
DesignOpinion Opinion();
|
||||
private:
|
||||
Shape shape;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
/** Windscreen component */
|
||||
struct WindScreen {
|
||||
WindScreen(bool opaque);
|
||||
DesignOpinion Opinion();
|
||||
private:
|
||||
bool opaque;
|
||||
};
|
||||
|
||||
/** Factory method for creating a car */
|
||||
static MotorCar DesignFromComponents(const std::string &name, const Wheels &wheels, const WindScreen &windscreen);
|
||||
|
||||
std::string Name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Get an overall opinion on the car design */
|
||||
std::string WillItWork();
|
||||
|
||||
private:
|
||||
MotorCar(const std::string &name, const Wheels &wheels, const WindScreen &windscreen);
|
||||
std::string name;
|
||||
Wheels wheels;
|
||||
WindScreen windscreen;
|
||||
};
|
||||
13
Examples/csharp/nested/example.i
Normal file
13
Examples/csharp/nested/example.i
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
%module example
|
||||
|
||||
// This example shows how wrappers for numerous aspects of C++ nested classes work:
|
||||
// Nested static and instance variables and methods and nested enums
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "example.h"
|
||||
|
||||
30
Examples/csharp/nested/example.sln
Normal file
30
Examples/csharp/nested/example.sln
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-cs", "example-cs.csproj", "{C17D27DF-4C57-4625-AEE0-A40C4F48FF1A}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{C2302635-D489-4678-96B4-70F5309DCBE6} = {C2302635-D489-4678-96B4-70F5309DCBE6}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example-vc", "example-vc.vcproj", "{C2302635-D489-4678-96B4-70F5309DCBE6}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{C17D27DF-4C57-4625-AEE0-A40C4F48FF1A}.Debug.ActiveCfg = Debug|.NET
|
||||
{C17D27DF-4C57-4625-AEE0-A40C4F48FF1A}.Debug.Build.0 = Debug|.NET
|
||||
{C17D27DF-4C57-4625-AEE0-A40C4F48FF1A}.Release.ActiveCfg = Release|.NET
|
||||
{C17D27DF-4C57-4625-AEE0-A40C4F48FF1A}.Release.Build.0 = Release|.NET
|
||||
{C2302635-D489-4678-96B4-70F5309DCBE6}.Debug.ActiveCfg = Debug|Win32
|
||||
{C2302635-D489-4678-96B4-70F5309DCBE6}.Debug.Build.0 = Debug|Win32
|
||||
{C2302635-D489-4678-96B4-70F5309DCBE6}.Release.ActiveCfg = Release|Win32
|
||||
{C2302635-D489-4678-96B4-70F5309DCBE6}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
27
Examples/csharp/nested/runme.cs
Normal file
27
Examples/csharp/nested/runme.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// This example illustrates how C++ classes can be used from C# using SWIG.
|
||||
// The C# class gets mapped onto the C++ class and behaves as if it is a C# class.
|
||||
|
||||
using System;
|
||||
|
||||
public class runme
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
MotorCar car1 = MotorCar.DesignFromComponents("Bumpy", new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 4), new MotorCar.WindScreen(false));
|
||||
MotorCar car2 = MotorCar.DesignFromComponents("Wobbly", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 2), new MotorCar.WindScreen(false));
|
||||
MotorCar car3 = MotorCar.DesignFromComponents("Batty", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(true));
|
||||
MotorCar car4 = MotorCar.DesignFromComponents("Spiffing", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(false));
|
||||
|
||||
Console.WriteLine("Expert opinion on " + car1.Name() + " : \n " + car1.WillItWork());
|
||||
Console.WriteLine("Expert opinion on " + car2.Name() + " : \n " + car2.WillItWork());
|
||||
Console.WriteLine("Expert opinion on " + car3.Name() + " : \n " + car3.WillItWork());
|
||||
Console.WriteLine("Expert opinion on " + car4.Name() + " : \n " + car4.WillItWork());
|
||||
|
||||
int count = MotorCar.DesignOpinion.AceDesignCount;
|
||||
int total = MotorCar.DesignOpinion.TotalDesignCount;
|
||||
int percent = MotorCar.DesignOpinion.PercentScore();
|
||||
Console.WriteLine("Overall opinion rating on car design is " + count + "/" + total + " = " + percent + "%");
|
||||
|
||||
Console.WriteLine("Single square wheel thoughts: " + new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 1).Opinion().reason);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ extend
|
|||
funcptr
|
||||
multimap
|
||||
native
|
||||
nested
|
||||
pointer
|
||||
reference
|
||||
simple
|
||||
|
|
|
|||
18
Examples/java/nested/Makefile
Normal file
18
Examples/java/nested/Makefile
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
SWIGOPT =
|
||||
JAVASRCS = *.java
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile java_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java_cpp
|
||||
$(MAKE) -f $(TOP)/Makefile JAVASRCS='$(JAVASRCS)' JAVAFLAGS='$(JAVAFLAGS)' java_compile
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile java_clean
|
||||
62
Examples/java/nested/example.cxx
Normal file
62
Examples/java/nested/example.cxx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include "example.h"
|
||||
|
||||
int MotorCar::DesignOpinion::AceDesignCount = 0;
|
||||
int MotorCar::DesignOpinion::TotalDesignCount = 0;
|
||||
|
||||
int MotorCar::DesignOpinion::PercentScore() {
|
||||
return AceDesignCount*100/TotalDesignCount;
|
||||
}
|
||||
|
||||
MotorCar::Wheels::Wheels(Shape shape, size_t count) : shape(shape), count(count) {}
|
||||
|
||||
MotorCar::WindScreen::WindScreen(bool opaque) : opaque(opaque) {}
|
||||
|
||||
MotorCar::MotorCar(const std::string &name, const Wheels &wheels, const WindScreen &windscreen) : name(name), wheels(wheels), windscreen(windscreen) {}
|
||||
|
||||
MotorCar MotorCar::DesignFromComponents(const std::string &name, const Wheels &wheels, const WindScreen &windscreen) {
|
||||
MotorCar car = MotorCar(name, wheels, windscreen);
|
||||
DesignOpinion::TotalDesignCount++;
|
||||
if (car.wheels.Opinion().itrocks && car.windscreen.Opinion().itrocks)
|
||||
DesignOpinion::AceDesignCount++;
|
||||
return car;
|
||||
}
|
||||
|
||||
MotorCar::DesignOpinion MotorCar::Wheels::Opinion() {
|
||||
DesignOpinion opinion;
|
||||
opinion.itrocks = true;
|
||||
if (shape == Square) {
|
||||
opinion.itrocks = false;
|
||||
opinion.reason = "you'll have a few issues with wheel rotation";
|
||||
}
|
||||
if (count <= 2) {
|
||||
opinion.reason += opinion.itrocks ? "" : " and ";
|
||||
opinion.itrocks = false;
|
||||
opinion.reason += "a few more wheels are needed for stability";
|
||||
}
|
||||
if (opinion.itrocks)
|
||||
opinion.reason = "your choice of wheels was top notch";
|
||||
|
||||
return opinion;
|
||||
}
|
||||
|
||||
MotorCar::DesignOpinion MotorCar::WindScreen::Opinion() {
|
||||
DesignOpinion opinion;
|
||||
opinion.itrocks = !opaque;
|
||||
opinion.reason = opinion.itrocks ? "the driver will have a commanding view out the window" : "you can't see out the windscreen";
|
||||
return opinion;
|
||||
}
|
||||
|
||||
std::string MotorCar::WillItWork() {
|
||||
DesignOpinion wh = wheels.Opinion();
|
||||
DesignOpinion ws = windscreen.Opinion();
|
||||
std::string willit;
|
||||
if (wh.itrocks && ws.itrocks) {
|
||||
willit = "Great car design because " + wh.reason + " and " + ws.reason;
|
||||
} else {
|
||||
willit = "You need a rethink because ";
|
||||
willit += wh.itrocks ? "" : wh.reason;
|
||||
willit += (!wh.itrocks && !ws.itrocks) ? " and " : "";
|
||||
willit += ws.itrocks ? "" : ws.reason;
|
||||
}
|
||||
return willit;
|
||||
}
|
||||
162
Examples/java/nested/example.dsp
Normal file
162
Examples/java/nested/example.dsp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=example - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "example.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "example - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_INCLUDE)" /I "$(JAVA_INCLUDE)\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /out:"example.dll" /pdbtype:sept
|
||||
# Begin Special Build Tool
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Desc=Java compile post-build step
|
||||
PostBuild_Cmds=echo on "%JAVA_BIN%\javac" *.java
|
||||
# End Special Build Tool
|
||||
|
||||
!ELSEIF "$(CFG)" == "example - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(JAVA_INCLUDE)" /I "$(JAVA_INCLUDE)\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386 /out:"example.dll"
|
||||
# Begin Special Build Tool
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Desc=Java compile post-build step
|
||||
PostBuild_Cmds=echo on "%JAVA_BIN%\javac" *.java
|
||||
# End Special Build Tool
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "example - Win32 Debug"
|
||||
# Name "example - Win32 Release"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\example.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\example_wrap.cxx
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\example.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\example.i
|
||||
|
||||
!IF "$(CFG)" == "example - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=.\example.i
|
||||
InputName=example
|
||||
|
||||
"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
echo In order to function correctly, please ensure the following environment variables are correctly set:
|
||||
echo JAVA_INCLUDE: %JAVA_INCLUDE%
|
||||
echo JAVA_BIN: %JAVA_BIN%
|
||||
echo on
|
||||
..\..\..\swig.exe -c++ -java "$(InputPath)"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "example - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=.\example.i
|
||||
InputName=example
|
||||
|
||||
"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
echo In order to function correctly, please ensure the following environment variables are correctly set:
|
||||
echo JAVA_INCLUDE: %JAVA_INCLUDE%
|
||||
echo JAVA_BIN: %JAVA_BIN%
|
||||
echo on
|
||||
..\..\..\swig.exe -c++ -java "$(InputPath)"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
48
Examples/java/nested/example.h
Normal file
48
Examples/java/nested/example.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#include <string>
|
||||
|
||||
/** Design a motor car from various components */
|
||||
struct MotorCar {
|
||||
|
||||
/** Information about an opinion of the design of a car component */
|
||||
struct DesignOpinion {
|
||||
bool itrocks;
|
||||
std::string reason;
|
||||
static int AceDesignCount;
|
||||
static int TotalDesignCount;
|
||||
static int PercentScore();
|
||||
};
|
||||
|
||||
/** Wheels component */
|
||||
struct Wheels {
|
||||
enum Shape { Round, Square };
|
||||
Wheels(Shape shape, size_t count);
|
||||
DesignOpinion Opinion();
|
||||
private:
|
||||
Shape shape;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
/** Windscreen component */
|
||||
struct WindScreen {
|
||||
WindScreen(bool opaque);
|
||||
DesignOpinion Opinion();
|
||||
private:
|
||||
bool opaque;
|
||||
};
|
||||
|
||||
/** Factory method for creating a car */
|
||||
static MotorCar DesignFromComponents(const std::string &name, const Wheels &wheels, const WindScreen &windscreen);
|
||||
|
||||
std::string Name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Get an overall opinion on the car design */
|
||||
std::string WillItWork();
|
||||
|
||||
private:
|
||||
MotorCar(const std::string &name, const Wheels &wheels, const WindScreen &windscreen);
|
||||
std::string name;
|
||||
Wheels wheels;
|
||||
WindScreen windscreen;
|
||||
};
|
||||
13
Examples/java/nested/example.i
Normal file
13
Examples/java/nested/example.i
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
%module example
|
||||
|
||||
// This example shows how wrappers for numerous aspects of C++ nested classes work:
|
||||
// Nested static and instance variables and methods and nested enums
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "example.h"
|
||||
|
||||
32
Examples/java/nested/runme.java
Normal file
32
Examples/java/nested/runme.java
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// This example illustrates wrapping of nested C++ classes
|
||||
|
||||
public class runme {
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("example");
|
||||
} 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[])
|
||||
{
|
||||
MotorCar car1 = MotorCar.DesignFromComponents("Bumpy", new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 4), new MotorCar.WindScreen(false));
|
||||
MotorCar car2 = MotorCar.DesignFromComponents("Wobbly", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 2), new MotorCar.WindScreen(false));
|
||||
MotorCar car3 = MotorCar.DesignFromComponents("Batty", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(true));
|
||||
MotorCar car4 = MotorCar.DesignFromComponents("Spiffing", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(false));
|
||||
|
||||
System.out.println("Expert opinion on " + car1.Name() + " : \n " + car1.WillItWork());
|
||||
System.out.println("Expert opinion on " + car2.Name() + " : \n " + car2.WillItWork());
|
||||
System.out.println("Expert opinion on " + car3.Name() + " : \n " + car3.WillItWork());
|
||||
System.out.println("Expert opinion on " + car4.Name() + " : \n " + car4.WillItWork());
|
||||
|
||||
int count = MotorCar.DesignOpinion.getAceDesignCount();
|
||||
int total = MotorCar.DesignOpinion.getTotalDesignCount();
|
||||
int percent = MotorCar.DesignOpinion.PercentScore();
|
||||
System.out.println("Overall opinion rating on car design is " + count + "/" + total + " = " + percent + "%");
|
||||
|
||||
System.out.println("Single square wheel thoughts: " + new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 1).Opinion().getReason());
|
||||
}
|
||||
}
|
||||
|
|
@ -84,6 +84,7 @@ CPP_TEST_BROKEN += \
|
|||
extend_variable \
|
||||
li_std_vector_ptr \
|
||||
li_boost_shared_ptr_template \
|
||||
nested_private \
|
||||
overload_complicated \
|
||||
template_default_pointer \
|
||||
template_expr \
|
||||
|
|
@ -279,6 +280,7 @@ CPP_TEST_CASES += \
|
|||
naturalvar_more \
|
||||
nested_class \
|
||||
nested_comment \
|
||||
nested_scope \
|
||||
nested_workaround \
|
||||
newobject1 \
|
||||
null_pointer \
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@ This was reported in bug #909389 */
|
|||
|
||||
%module derived_nested
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::CC;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::DD;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::EE;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::FF;
|
||||
|
||||
%inline %{
|
||||
|
||||
class A { int x; };
|
||||
class A {
|
||||
public:
|
||||
int x;
|
||||
};
|
||||
class B {
|
||||
class C { int y; }; //generates a warning
|
||||
class D : public A { int z; }; //ok
|
||||
|
|
|
|||
|
|
@ -14,59 +14,59 @@ public class nested_class_runme {
|
|||
|
||||
public static void main(String argv[]) {
|
||||
Outer outer = new Outer();
|
||||
SWIGTYPE_p_Outer__InnerStruct1 is1 = outer.makeInnerStruct1();
|
||||
SWIGTYPE_p_Outer__InnerClass1 ic1 = outer.makeInnerClass1();
|
||||
SWIGTYPE_p_Outer__InnerUnion1 iu1 = outer.makeInnerUnion1();
|
||||
Outer.InnerStruct1 is1 = outer.makeInnerStruct1();
|
||||
Outer.InnerClass1 ic1 = outer.makeInnerClass1();
|
||||
Outer.InnerUnion1 iu1 = outer.makeInnerUnion1();
|
||||
|
||||
SWIGTYPE_p_Outer__InnerStruct2 is2 = outer.makeInnerStruct2();
|
||||
SWIGTYPE_p_Outer__InnerClass2 ic2 = outer.makeInnerClass2();
|
||||
SWIGTYPE_p_Outer__InnerUnion2 iu2 = outer.makeInnerUnion2();
|
||||
Outer.InnerStruct2 is2 = outer.makeInnerStruct2();
|
||||
Outer.InnerClass2 ic2 = outer.makeInnerClass2();
|
||||
Outer.InnerUnion2 iu2 = outer.makeInnerUnion2();
|
||||
|
||||
SWIGTYPE_p_Outer__InnerClass4Typedef ic4 = outer.makeInnerClass4Typedef();
|
||||
SWIGTYPE_p_Outer__InnerStruct4Typedef is4 = outer.makeInnerStruct4Typedef();
|
||||
SWIGTYPE_p_Outer__InnerUnion4Typedef iu4 = outer.makeInnerUnion4Typedef();
|
||||
Outer.InnerClass4Typedef ic4 = outer.makeInnerClass4Typedef();
|
||||
Outer.InnerStruct4Typedef is4 = outer.makeInnerStruct4Typedef();
|
||||
Outer.InnerUnion4Typedef iu4 = outer.makeInnerUnion4Typedef();
|
||||
|
||||
SWIGTYPE_p_Outer__InnerClass5 ic5 = outer.makeInnerClass5();
|
||||
SWIGTYPE_p_Outer__InnerStruct5 is5 = outer.makeInnerStruct5();
|
||||
SWIGTYPE_p_Outer__InnerUnion5 iu5 = outer.makeInnerUnion5();
|
||||
Outer.InnerClass5Typedef ic5 = outer.makeInnerClass5();
|
||||
Outer.InnerStruct5Typedef is5 = outer.makeInnerStruct5();
|
||||
Outer.InnerUnion5Typedef iu5 = outer.makeInnerUnion5();
|
||||
|
||||
ic5 = outer.makeInnerClass5Typedef();
|
||||
is5 = outer.makeInnerStruct5Typedef();
|
||||
iu5 = outer.makeInnerUnion5Typedef();
|
||||
|
||||
{
|
||||
SWIGTYPE_p_Outer__InnerMultiple im1 = outer.getMultipleInstance1();
|
||||
SWIGTYPE_p_Outer__InnerMultiple im2 = outer.getMultipleInstance2();
|
||||
SWIGTYPE_p_Outer__InnerMultiple im3 = outer.getMultipleInstance3();
|
||||
SWIGTYPE_p_Outer__InnerMultiple im4 = outer.getMultipleInstance4();
|
||||
Outer.InnerMultiple im1 = outer.getMultipleInstance1();
|
||||
Outer.InnerMultiple im2 = outer.getMultipleInstance2();
|
||||
Outer.InnerMultiple im3 = outer.getMultipleInstance3();
|
||||
Outer.InnerMultiple im4 = outer.getMultipleInstance4();
|
||||
}
|
||||
|
||||
{
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
|
||||
Outer.InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
|
||||
Outer.InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
|
||||
Outer.InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
|
||||
Outer.InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
|
||||
}
|
||||
|
||||
{
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
|
||||
SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
|
||||
Outer.InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
|
||||
Outer.InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
|
||||
Outer.InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
|
||||
Outer.InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
|
||||
}
|
||||
|
||||
{
|
||||
SWIGTYPE_p_Outer__InnerMultipleAnonTypedef1 mat1 = outer.makeInnerMultipleAnonTypedef1();
|
||||
SWIGTYPE_p_Outer__InnerMultipleAnonTypedef2 mat2 = outer.makeInnerMultipleAnonTypedef2();
|
||||
SWIGTYPE_p_Outer__InnerMultipleAnonTypedef3 mat3 = outer.makeInnerMultipleAnonTypedef3();
|
||||
Outer.InnerMultipleAnonTypedef1 mat1 = outer.makeInnerMultipleAnonTypedef1();
|
||||
Outer.InnerMultipleAnonTypedef1 mat2 = outer.makeInnerMultipleAnonTypedef2();
|
||||
SWIGTYPE_p_p_Outer__InnerMultipleAnonTypedef1 mat3 = outer.makeInnerMultipleAnonTypedef3();
|
||||
|
||||
SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt = outer.makeInnerMultipleNamedTypedef();
|
||||
SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt1 = outer.makeInnerMultipleNamedTypedef1();
|
||||
SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt2 = outer.makeInnerMultipleNamedTypedef2();
|
||||
Outer.InnerMultipleNamedTypedef1 mnt = outer.makeInnerMultipleNamedTypedef();
|
||||
Outer.InnerMultipleNamedTypedef1 mnt1 = outer.makeInnerMultipleNamedTypedef1();
|
||||
Outer.InnerMultipleNamedTypedef1 mnt2 = outer.makeInnerMultipleNamedTypedef2();
|
||||
SWIGTYPE_p_p_Outer__InnerMultipleNamedTypedef mnt3 = outer.makeInnerMultipleNamedTypedef3();
|
||||
}
|
||||
{
|
||||
SWIGTYPE_p_Outer__InnerSameName isn = outer.makeInnerSameName();
|
||||
Outer.InnerSameName isn = outer.makeInnerSameName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,21 +17,28 @@ public class nested_structs_runme {
|
|||
nested_structs.setValues(outer, 10);
|
||||
|
||||
Outer_inner1 inner1 = outer.getInner1();
|
||||
Outer_inner2 inner2 = outer.getInner2();
|
||||
Outer_inner3 inner3 = outer.getInner3();
|
||||
Outer_inner4 inner4 = outer.getInner4();
|
||||
Outer_inner1 inner2 = outer.getInner2();
|
||||
Outer_inner1 inner3 = outer.getInner3();
|
||||
Outer_inner1 inner4 = outer.getInner4();
|
||||
if (inner1.getVal() != 10) throw new RuntimeException("failed inner1");
|
||||
if (inner2.getVal() != 20) throw new RuntimeException("failed inner2");
|
||||
if (inner3.getVal() != 20) throw new RuntimeException("failed inner3");
|
||||
if (inner4.getVal() != 40) throw new RuntimeException("failed inner4");
|
||||
|
||||
Outer_inside1 inside1 = outer.getInside1();
|
||||
Outer_inside2 inside2 = outer.getInside2();
|
||||
Outer_inside3 inside3 = outer.getInside3();
|
||||
Outer_inside4 inside4 = outer.getInside4();
|
||||
Named inside1 = outer.getInside1();
|
||||
Named inside2 = outer.getInside2();
|
||||
Named inside3 = outer.getInside3();
|
||||
Named inside4 = outer.getInside4();
|
||||
if (inside1.getVal() != 100) throw new RuntimeException("failed inside1");
|
||||
if (inside2.getVal() != 200) throw new RuntimeException("failed inside2");
|
||||
if (inside3.getVal() != 200) throw new RuntimeException("failed inside3");
|
||||
if (inside4.getVal() != 400) throw new RuntimeException("failed inside4");
|
||||
|
||||
outer.getInner1().setVal(11);
|
||||
if (inner1.getVal() != 11) throw new RuntimeException("failed inner1 assignment");
|
||||
Named named = new Named();
|
||||
named.setVal(22);
|
||||
outer.setInside2(named);
|
||||
if (outer.getInside2().getVal() != 22) throw new RuntimeException("failed inside2 assignment");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ public class template_nested_runme {
|
|||
T_NestedOuterTemplateDouble tn = new T_NestedOuterTemplateDouble();
|
||||
if (tn.hohum(-12.3) != -12.3)
|
||||
throw new RuntimeException("it failed");
|
||||
OuterClass.T_OuterClassInner1Int inner1 = new OuterClass().useInner1(new OuterClass.T_OuterClassInner1Int());
|
||||
OuterClass.T_OuterClassInner2NormalClass inner2 = new OuterClass.T_OuterClassInner2NormalClass();
|
||||
inner2.setEmbeddedVar(2);
|
||||
OuterClass.T_OuterClassInner2NormalClass inner22 = new OuterClass().useInner2Again(inner2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
%module namespace_class
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Ala::Ola;
|
||||
|
||||
#ifdef SWIGD
|
||||
%warnfilter(SWIGWARN_IGNORE_OPERATOR_LT);
|
||||
|
|
@ -216,9 +215,6 @@ namespace a
|
|||
|
||||
%}
|
||||
|
||||
// %copyctor doesn't work with nested class workaround
|
||||
%nocopyctor;
|
||||
|
||||
%inline %{
|
||||
class Ala {
|
||||
public :
|
||||
|
|
@ -236,12 +232,6 @@ namespace a
|
|||
};
|
||||
%}
|
||||
|
||||
%rename(Ala__Ola) Ala::Ola;
|
||||
class Ala::Ola {
|
||||
public:
|
||||
Ola() {}
|
||||
void eek() {}
|
||||
};
|
||||
|
||||
%template(hi) Ala::hi<int>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
%module namespace_union
|
||||
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||
|
||||
%inline %{
|
||||
namespace SpatialIndex
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,25 +1,5 @@
|
|||
%module nested_class
|
||||
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct1;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass1;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion1;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4Typedef;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4Typedef;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4Typedef;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass5;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct5;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion5;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultiple;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleDerived;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleAnonTypedef1;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleNamedTypedef;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerSameName;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer2::IgnoreMe;
|
||||
|
||||
%inline %{
|
||||
struct Outer {
|
||||
typedef int Integer;
|
||||
|
|
@ -39,7 +19,7 @@ struct Outer {
|
|||
};
|
||||
|
||||
///////////////////////////////////////////
|
||||
#ifdef SWIG
|
||||
#if defined(__GNUC__) || defined(_MSC_VER) || defined(SWIG)
|
||||
/* some compilers do not accept these */
|
||||
class {
|
||||
public:
|
||||
|
|
@ -154,7 +134,7 @@ struct Outer {
|
|||
Integer xx;
|
||||
} MultipleInstanceAnonDerived1, MultipleInstanceAnonDerived2, *MultipleInstanceAnonDerived3, MultipleInstanceAnonDerived4[2];
|
||||
|
||||
#ifdef SWIG
|
||||
#if defined(__GNUC__) || defined(_MSC_VER) || defined(SWIG)
|
||||
/* some compilers do not accept these */
|
||||
struct : public InnerMultiple {
|
||||
Integer xx;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
%module nested_comment
|
||||
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||
|
||||
// this example shows a problem with 'dump_nested' (parser.y).
|
||||
|
||||
// bug #949654
|
||||
|
|
|
|||
32
Examples/test-suite/nested_private.i
Normal file
32
Examples/test-suite/nested_private.i
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
%module nested_private
|
||||
|
||||
// segfault due to private nested class usage
|
||||
|
||||
%inline %{
|
||||
#include <string>
|
||||
class MotorCar {
|
||||
|
||||
struct DesignOpinion {
|
||||
std::string reason;
|
||||
};
|
||||
|
||||
public:
|
||||
struct WindScreen {
|
||||
WindScreen(bool opaque) : opaque(opaque) {}
|
||||
DesignOpinion Opinion();
|
||||
private:
|
||||
bool opaque;
|
||||
};
|
||||
|
||||
std::string WindScreenOpinion() {
|
||||
return MotorCar::WindScreen(true).Opinion().reason;
|
||||
}
|
||||
};
|
||||
|
||||
MotorCar::DesignOpinion MotorCar::WindScreen::Opinion() {
|
||||
DesignOpinion opinion;
|
||||
opinion.reason = !opaque ? "great design" : "you can't see out the windscreen";
|
||||
return opinion;
|
||||
}
|
||||
|
||||
%}
|
||||
14
Examples/test-suite/nested_scope.i
Normal file
14
Examples/test-suite/nested_scope.i
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
%module nested_scope
|
||||
|
||||
%inline %{
|
||||
namespace ns {
|
||||
struct Global {
|
||||
struct Outer {
|
||||
struct Nested;
|
||||
};
|
||||
struct Outer::Nested {
|
||||
int data;
|
||||
} instance;
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
|
@ -25,5 +25,21 @@ void setValues(struct Outer *outer, int val) {
|
|||
outer->inside4[0].val = val * 4;
|
||||
outer->inside5 = &outer->inside3;
|
||||
}
|
||||
|
||||
int getInside1Val(struct Outer *n) { return n->inside1.val; }
|
||||
%}
|
||||
|
||||
/*
|
||||
Below was causing problems in Octave as wrappers were compiled as C++.
|
||||
Solution requires regenerating the inner struct into
|
||||
the global C++ namespace (which is where it is intended to be in C).
|
||||
*/
|
||||
%inline %{
|
||||
int nestedByVal(struct Named s);
|
||||
int nestedByPtr(struct Named *s);
|
||||
%}
|
||||
%{
|
||||
int nestedByVal(struct Named s) { return s.val; }
|
||||
int nestedByPtr(struct Named *s) { return s->val; }
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,6 @@
|
|||
%module nested_workaround
|
||||
// Similar to "Nested classes" documentation example.
|
||||
|
||||
class Inner {
|
||||
int val;
|
||||
public:
|
||||
Inner(int v = 0) : val(v) {}
|
||||
void setValue(int v) { val = v; }
|
||||
int getValue() const { return val; }
|
||||
};
|
||||
%nestedworkaround Outer::Inner;
|
||||
// "flatnested" emulates deprecated feature "nested_workaround" for the languages not supporting nested classes
|
||||
%feature ("flatnested");
|
||||
|
||||
%inline %{
|
||||
class Outer {
|
||||
|
|
@ -28,11 +20,3 @@ public:
|
|||
}
|
||||
};
|
||||
%}
|
||||
|
||||
// We've fooled SWIG into thinking that Inner is a global class, so now we need
|
||||
// to trick the C++ compiler into understanding this apparent global type.
|
||||
%{
|
||||
typedef Outer::Inner Inner;
|
||||
%}
|
||||
|
||||
|
||||
|
|
|
|||
14
Examples/test-suite/octave/nested_structs_runme.m
Normal file
14
Examples/test-suite/octave/nested_structs_runme.m
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
nested_structs
|
||||
|
||||
named = nested_structs.Named();
|
||||
named.val = 999;
|
||||
assert(nested_structs.nestedByVal(named), 999);
|
||||
assert(nested_structs.nestedByPtr(named), 999);
|
||||
|
||||
outer = nested_structs.Outer();
|
||||
outer.inside1.val = 456;
|
||||
assert(nested_structs.getInside1Val(outer), 456);
|
||||
|
||||
outer.inside1 = named;
|
||||
assert(nested_structs.getInside1Val(outer), 999);
|
||||
|
||||
|
|
@ -2,13 +2,6 @@
|
|||
|
||||
// Test nested templates - that is template classes and template methods within a class.
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner1;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate1;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate3;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedStruct;
|
||||
|
||||
namespace ns {
|
||||
template <class T> struct ForwardTemplate;
|
||||
}
|
||||
|
|
@ -33,7 +26,13 @@ namespace ns {
|
|||
template <class T> struct NormalTemplate {
|
||||
void tmethod(T t) {}
|
||||
};
|
||||
}
|
||||
%}
|
||||
%template(T_NormalTemplateNormalClass) ns::NormalTemplate<ns::NormalClass>;
|
||||
%template(T_NormalTemplateInt) ns::NormalTemplate<int>;
|
||||
|
||||
%inline %{
|
||||
namespace ns {
|
||||
class OuterClass {
|
||||
public:
|
||||
template <class T> struct Inner1 {
|
||||
|
|
@ -70,6 +69,7 @@ namespace ns {
|
|||
};
|
||||
};
|
||||
Inner2<int> useInner2(const Inner2<int>& inner) { return inner; }
|
||||
Inner2<NormalClass> useInner2Again(const Inner2<NormalClass>& inner) { return inner; }
|
||||
int iii;
|
||||
};
|
||||
struct ABC {
|
||||
|
|
@ -108,9 +108,10 @@ namespace ns {
|
|||
|
||||
%}
|
||||
|
||||
%template(T_NormalTemplateNormalClass) ns::NormalTemplate<ns::NormalClass>;
|
||||
%template(T_OuterTMethodNormalClass) ns::OuterClass::InnerTMethod<ns::NormalClass>;
|
||||
%template(T_TemplateFuncs1Int) ns::TemplateFuncs::templateMethod1<int>;
|
||||
%template(T_TemplateFuncs2Double) ns::TemplateFuncs::templateMethod2<double>;
|
||||
%template(T_NestedOuterTemplateDouble) ns::OuterTemplate<double>;
|
||||
|
||||
%template(T_OuterClassInner1Int) ns::OuterClass::Inner1<int>;
|
||||
%template(T_OuterClassInner2NormalClass) ns::OuterClass::Inner2<ns::NormalClass>;
|
||||
%template(T_OuterClassInner2Int) ns::OuterClass::Inner2<int>;
|
||||
|
|
|
|||
|
|
@ -4,18 +4,22 @@
|
|||
|
||||
// Testing that the typemaps invoked within a class via %template are picked up by appropriate methods
|
||||
|
||||
%inline %{
|
||||
template <typename T> struct Typemap {
|
||||
#ifdef SWIG
|
||||
%typemap(in) T {
|
||||
$1 = -99;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
template <> struct Typemap<short> { // Note explicit specialization
|
||||
#ifdef SWIG
|
||||
%typemap(in) short {
|
||||
$1 = -77;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
%inline %{
|
||||
int globalInt1(int s) { return s; }
|
||||
short globalShort1(short s) { return s; }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState; // Ruby, wrong class name
|
||||
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState_rstate; // Ruby, wrong class name
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||
|
||||
%inline %{
|
||||
class nRState {
|
||||
|
|
|
|||
11
Lib/swig.swg
11
Lib/swig.swg
|
|
@ -9,7 +9,7 @@
|
|||
* User Directives
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Deprecated SWIG directives */
|
||||
/* Deprecated SWIG-1.1 directives */
|
||||
|
||||
#define %disabledoc %warn "104:%disabledoc is deprecated"
|
||||
#define %enabledoc %warn "105:%enabledoc is deprecated"
|
||||
|
|
@ -136,11 +136,16 @@
|
|||
#define %nocallback %feature("callback","0")
|
||||
#define %clearcallback %feature("callback","")
|
||||
|
||||
/* the %nestedworkaround directive */
|
||||
/* the %nestedworkaround directive (deprecated) */
|
||||
#define %nestedworkaround %feature("nestedworkaround")
|
||||
#define %nonestedworkaround %feature("nestedworkaround","0")
|
||||
#define %clearnestedworkaround %feature("nestedworkaround","")
|
||||
|
||||
/* the %flatnested directive */
|
||||
#define %flatnested %feature("flatnested")
|
||||
#define %noflatnested %feature("flatnested","0")
|
||||
#define %clearflatnested %feature("flatnested","")
|
||||
|
||||
/* the %fastdispatch directive */
|
||||
#define %fastdispatch %feature("fastdispatch")
|
||||
#define %nofastdispatch %feature("fastdispatch","0")
|
||||
|
|
@ -302,7 +307,7 @@ static int NAME(TYPE x) {
|
|||
%define %$ismemberset "match$memberset"="1" %enddef
|
||||
|
||||
%define %$classname %$ismember,"match$parentNode$name" %enddef
|
||||
|
||||
%define %$isnested "match$nested"="1" %enddef
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Include all the warnings labels and macros
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@
|
|||
%typemap(memberin) SWIGTYPE [ANY] {
|
||||
if ($input) {
|
||||
size_t ii = 0;
|
||||
for (; ii < (size_t)$1_dim0; ++ii) $1[ii] = $input[ii];
|
||||
for (; ii < (size_t)$1_dim0; ++ii) *($1_ltype)&$1[ii] = ($*1_ltype)$input[ii];
|
||||
} else {
|
||||
%variable_nullref("$type","$name");
|
||||
}
|
||||
|
|
@ -168,7 +168,7 @@
|
|||
%typemap(globalin) SWIGTYPE [ANY] {
|
||||
if ($input) {
|
||||
size_t ii = 0;
|
||||
for (; ii < (size_t)$1_dim0; ++ii) $1[ii] = $input[ii];
|
||||
for (; ii < (size_t)$1_dim0; ++ii) *($1_ltype)&$1[ii] = ($*1_ltype)$input[ii];
|
||||
} else {
|
||||
%variable_nullref("$type","$name");
|
||||
}
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
%variable_fail(res, "$type", "$name");
|
||||
} else if (inp) {
|
||||
size_t ii = 0;
|
||||
for (; ii < (size_t)$1_dim0; ++ii) $1[ii] = inp[ii];
|
||||
for (; ii < (size_t)$1_dim0; ++ii) *($1_ltype)&$1[ii] = ($*1_ltype)inp[ii];
|
||||
} else {
|
||||
%variable_nullref("$type", "$name");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,15 @@ extern "C" {
|
|||
extern String *cparse_file;
|
||||
extern int cparse_line;
|
||||
extern int cparse_cplusplus;
|
||||
extern int cparse_cplusplusout;
|
||||
extern int cparse_start_line;
|
||||
|
||||
extern void Swig_cparse_cplusplus(int);
|
||||
extern void Swig_cparse_cplusplusout(int);
|
||||
extern void scanner_file(File *);
|
||||
extern void scanner_next_token(int);
|
||||
extern void skip_balanced(int startchar, int endchar);
|
||||
extern String *get_raw_text_balanced(int startchar, int endchar);
|
||||
extern void skip_decl(void);
|
||||
extern void scanner_check_typedef(void);
|
||||
extern void scanner_ignore_typedef(void);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ int cparse_start_line = 0;
|
|||
/* C++ mode */
|
||||
int cparse_cplusplus = 0;
|
||||
|
||||
/* Generate C++ compatible code when wrapping C code */
|
||||
int cparse_cplusplusout = 0;
|
||||
|
||||
/* Private vars */
|
||||
static int scan_init = 0;
|
||||
static int num_brace = 0;
|
||||
|
|
@ -52,6 +55,14 @@ void Swig_cparse_cplusplus(int v) {
|
|||
cparse_cplusplus = v;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_cparse_cplusplusout()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_cparse_cplusplusout(int v) {
|
||||
cparse_cplusplusout = v;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* scanner_init()
|
||||
*
|
||||
|
|
@ -118,6 +129,16 @@ void skip_balanced(int startchar, int endchar) {
|
|||
return;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* get_raw_text_balanced()
|
||||
*
|
||||
* Returns raw text between 2 braces
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *get_raw_text_balanced(int startchar, int endchar) {
|
||||
return Scanner_get_raw_text_balanced(scan, startchar, endchar);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* void skip_decl(void)
|
||||
*
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -52,6 +52,7 @@
|
|||
#define WARN_DEPRECATED_NODEFAULT 123
|
||||
#define WARN_DEPRECATED_TYPEMAP_LANG 124
|
||||
#define WARN_DEPRECATED_INPUT_FILE 125
|
||||
#define WARN_DEPRECATED_NESTED_WORKAROUND 126
|
||||
|
||||
/* -- Preprocessor -- */
|
||||
|
||||
|
|
@ -75,7 +76,6 @@
|
|||
#define WARN_PARSE_PRIVATE_INHERIT 309
|
||||
#define WARN_PARSE_TEMPLATE_REPEAT 310
|
||||
#define WARN_PARSE_TEMPLATE_PARTIAL 311
|
||||
#define WARN_PARSE_UNNAMED_NESTED_CLASS 312
|
||||
#define WARN_PARSE_UNDEFINED_EXTERN 313
|
||||
#define WARN_PARSE_KEYWORD 314
|
||||
#define WARN_PARSE_USING_UNDEF 315
|
||||
|
|
@ -88,7 +88,6 @@
|
|||
#define WARN_PARSE_REDUNDANT 322
|
||||
#define WARN_PARSE_REC_INHERITANCE 323
|
||||
#define WARN_PARSE_NESTED_TEMPLATE 324
|
||||
#define WARN_PARSE_NAMED_NESTED_CLASS 325
|
||||
#define WARN_PARSE_EXTEND_NAME 326
|
||||
|
||||
#define WARN_CPP11_LAMBDA 340
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ eswig_SOURCES = CParse/cscanner.c \
|
|||
Modules/modula3.cxx \
|
||||
Modules/module.cxx \
|
||||
Modules/mzscheme.cxx \
|
||||
Modules/nested.cxx \
|
||||
Modules/ocaml.cxx \
|
||||
Modules/octave.cxx \
|
||||
Modules/overload.cxx \
|
||||
|
|
|
|||
|
|
@ -559,6 +559,8 @@ Allocate():
|
|||
virtual int classDeclaration(Node *n) {
|
||||
Symtab *symtab = Swig_symbol_current();
|
||||
Swig_symbol_setscope(Getattr(n, "symtab"));
|
||||
Node *oldInclass = inclass;
|
||||
AccessMode oldAcessMode = cplus_mode;
|
||||
|
||||
if (!CPlusPlus) {
|
||||
/* Always have default constructors/destructors in C */
|
||||
|
|
@ -580,7 +582,6 @@ Allocate():
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
inclass = n;
|
||||
String *kind = Getattr(n, "kind");
|
||||
if (Strcmp(kind, "class") == 0) {
|
||||
|
|
@ -728,7 +729,8 @@ Allocate():
|
|||
|
||||
/* Only care about default behavior. Remove temporary values */
|
||||
Setattr(n, "allocate:visit", "1");
|
||||
inclass = 0;
|
||||
inclass = oldInclass;
|
||||
cplus_mode = oldAcessMode;
|
||||
Swig_symbol_setscope(symtab);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,11 +342,13 @@ int Contracts::namespaceDeclaration(Node *n) {
|
|||
|
||||
int Contracts::classDeclaration(Node *n) {
|
||||
int ret = SWIG_OK;
|
||||
int oldInClass = InClass;
|
||||
Node *oldClass = CurrentClass;
|
||||
InClass = 1;
|
||||
CurrentClass = n;
|
||||
emit_children(n);
|
||||
InClass = 0;
|
||||
CurrentClass = 0;
|
||||
InClass = oldInClass;
|
||||
CurrentClass = oldClass;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class CSHARP:public Language {
|
|||
String *proxy_class_code;
|
||||
String *module_class_code;
|
||||
String *proxy_class_name; // proxy class name
|
||||
String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
|
||||
String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
|
||||
String *variable_name; //Name of a variable being wrapped
|
||||
String *proxy_class_constants_code;
|
||||
|
|
@ -87,6 +86,7 @@ class CSHARP:public Language {
|
|||
int n_directors;
|
||||
int first_class_dmethod;
|
||||
int curr_class_dmethod;
|
||||
int nesting_depth;
|
||||
|
||||
enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
|
||||
|
||||
|
|
@ -125,7 +125,6 @@ public:
|
|||
proxy_class_code(NULL),
|
||||
module_class_code(NULL),
|
||||
proxy_class_name(NULL),
|
||||
full_proxy_class_name(NULL),
|
||||
full_imclass_name(NULL),
|
||||
variable_name(NULL),
|
||||
proxy_class_constants_code(NULL),
|
||||
|
|
@ -156,7 +155,8 @@ public:
|
|||
n_dmethods(0),
|
||||
n_directors(0),
|
||||
first_class_dmethod(0),
|
||||
curr_class_dmethod(0) {
|
||||
curr_class_dmethod(0),
|
||||
nesting_depth(0){
|
||||
/* for now, multiple inheritance in directors is disabled, this
|
||||
should be easy to implement though */
|
||||
director_multiple_inheritance = 0;
|
||||
|
|
@ -179,7 +179,13 @@ public:
|
|||
proxyname = Getattr(n, "proxyname");
|
||||
if (!proxyname) {
|
||||
String *nspace = Getattr(n, "sym:nspace");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *symname = Copy(Getattr(n, "sym:name"));
|
||||
if (symname && !GetFlag(n, "feature:flatnested")) {
|
||||
for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
|
||||
Push(symname, ".");
|
||||
Push(symname, Getattr(outer_class, "sym:name"));
|
||||
}
|
||||
}
|
||||
if (nspace) {
|
||||
if (namespce)
|
||||
proxyname = NewStringf("%s.%s.%s", namespce, nspace, symname);
|
||||
|
|
@ -190,12 +196,33 @@ public:
|
|||
}
|
||||
Setattr(n, "proxyname", proxyname);
|
||||
Delete(proxyname);
|
||||
Delete(symname);
|
||||
}
|
||||
}
|
||||
}
|
||||
return proxyname;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* directorClassName()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *directorClassName(Node *n) {
|
||||
String *dirclassname;
|
||||
const char *attrib = "director:classname";
|
||||
|
||||
if (!(dirclassname = Getattr(n, attrib))) {
|
||||
String *classname = getClassPrefix();
|
||||
|
||||
dirclassname = NewStringf("SwigDirector_%s", classname);
|
||||
Setattr(n, attrib, dirclassname);
|
||||
}
|
||||
else
|
||||
dirclassname = Copy(dirclassname);
|
||||
|
||||
return dirclassname;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* main()
|
||||
* ------------------------------------------------------------ */
|
||||
|
|
@ -1025,7 +1052,7 @@ public:
|
|||
*/
|
||||
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
|
||||
// Capitalize the first letter in the variable in the getter/setter function name
|
||||
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0;
|
||||
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0;
|
||||
|
||||
String *getter_setter_name = NewString("");
|
||||
if (!getter_flag)
|
||||
|
|
@ -1589,6 +1616,7 @@ public:
|
|||
String *c_baseclassname = NULL;
|
||||
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
||||
bool feature_director = Swig_directorclass(n) ? true : false;
|
||||
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
|
||||
|
||||
// Inheritance from pure C# classes
|
||||
Node *attributes = NewHash();
|
||||
|
|
@ -1648,7 +1676,8 @@ public:
|
|||
// Pure C# interfaces
|
||||
const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
|
||||
// Start writing the proxy class
|
||||
Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
|
||||
if (!has_outerclass)
|
||||
Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
|
||||
"\n", NIL);
|
||||
|
||||
// Class attributes
|
||||
|
|
@ -1719,7 +1748,7 @@ public:
|
|||
Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid);
|
||||
Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, overname);
|
||||
}
|
||||
String *director_connect_method_name = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
|
||||
String *director_connect_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
|
||||
Printf(proxy_class_code, " %s.%s(swigCPtr", imclass_name, director_connect_method_name);
|
||||
for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
|
||||
UpcallData *udata = Getitem(dmethods_seq, i);
|
||||
|
|
@ -1795,7 +1824,7 @@ public:
|
|||
// Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
|
||||
if (derived) {
|
||||
String *smartptr = Getattr(n, "feature:smartptr");
|
||||
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
|
||||
String *upcast_method = Swig_name_member(getNSpace(), getClassPrefix(), smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
|
||||
String *wname = Swig_name_wrapper(upcast_method);
|
||||
|
||||
Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
|
||||
|
|
@ -1846,11 +1875,35 @@ public:
|
|||
|
||||
String *nspace = getNSpace();
|
||||
File *f_proxy = NULL;
|
||||
// save class local variables
|
||||
String *old_proxy_class_name = proxy_class_name;
|
||||
String *old_full_imclass_name = full_imclass_name;
|
||||
String *old_destructor_call = destructor_call;
|
||||
String *old_proxy_class_constants_code = proxy_class_constants_code;
|
||||
String *old_proxy_class_def = proxy_class_def;
|
||||
String *old_proxy_class_code = proxy_class_code;
|
||||
|
||||
if (proxy_flag) {
|
||||
proxy_class_name = NewString(Getattr(n, "sym:name"));
|
||||
if (Node *outer = Getattr(n, "nested:outer")) {
|
||||
String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
|
||||
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
|
||||
Push(outerClassesPrefix, "::");
|
||||
Push(outerClassesPrefix, Getattr(outer, "sym:name"));
|
||||
}
|
||||
String *fnspace = nspace ? NewStringf("%s::%s", nspace, outerClassesPrefix) : outerClassesPrefix;
|
||||
if (!addSymbol(proxy_class_name, n, fnspace))
|
||||
return SWIG_ERROR;
|
||||
if (nspace)
|
||||
Delete(fnspace);
|
||||
Delete(outerClassesPrefix);
|
||||
}
|
||||
else {
|
||||
if (!addSymbol(proxy_class_name, n, nspace))
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
|
||||
if (!nspace) {
|
||||
full_proxy_class_name = NewStringf("%s", proxy_class_name);
|
||||
full_imclass_name = NewStringf("%s", imclass_name);
|
||||
if (Cmp(proxy_class_name, imclass_name) == 0) {
|
||||
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
|
||||
|
|
@ -1863,36 +1916,34 @@ public:
|
|||
}
|
||||
} else {
|
||||
if (namespce) {
|
||||
full_proxy_class_name = NewStringf("%s.%s.%s", namespce, nspace, proxy_class_name);
|
||||
full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
|
||||
} else {
|
||||
full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
|
||||
full_imclass_name = NewStringf("%s", imclass_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!addSymbol(proxy_class_name, n, nspace))
|
||||
return SWIG_ERROR;
|
||||
// inner class doesn't need this prologue
|
||||
if (!Getattr(n, "nested:outer")) {
|
||||
String *output_directory = outputDirectory(nspace);
|
||||
String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name);
|
||||
f_proxy = NewFile(filen, "w", SWIG_output_files());
|
||||
if (!f_proxy) {
|
||||
FileErrorDisplay(filen);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
Append(filenames_list, Copy(filen));
|
||||
Delete(filen);
|
||||
filen = NULL;
|
||||
|
||||
String *output_directory = outputDirectory(nspace);
|
||||
String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name);
|
||||
f_proxy = NewFile(filen, "w", SWIG_output_files());
|
||||
if (!f_proxy) {
|
||||
FileErrorDisplay(filen);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
// Start writing out the proxy class file
|
||||
emitBanner(f_proxy);
|
||||
|
||||
addOpenNamespace(nspace, f_proxy);
|
||||
}
|
||||
Append(filenames_list, Copy(filen));
|
||||
Delete(filen);
|
||||
filen = NULL;
|
||||
|
||||
// Start writing out the proxy class file
|
||||
emitBanner(f_proxy);
|
||||
|
||||
addOpenNamespace(nspace, f_proxy);
|
||||
|
||||
Clear(proxy_class_def);
|
||||
Clear(proxy_class_code);
|
||||
|
||||
else
|
||||
++nesting_depth;
|
||||
proxy_class_def = NewString("");
|
||||
proxy_class_code = NewString("");
|
||||
destructor_call = NewString("");
|
||||
proxy_class_constants_code = NewString("");
|
||||
}
|
||||
|
|
@ -1903,7 +1954,7 @@ public:
|
|||
|
||||
emitProxyClassDefAndCPPCasts(n);
|
||||
|
||||
String *csclazzname = Swig_name_member(getNSpace(), proxy_class_name, ""); // mangled full proxy class name
|
||||
String *csclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name
|
||||
|
||||
Replaceall(proxy_class_def, "$csclassname", proxy_class_name);
|
||||
Replaceall(proxy_class_code, "$csclassname", proxy_class_name);
|
||||
|
|
@ -1924,17 +1975,36 @@ public:
|
|||
Replaceall(proxy_class_def, "$dllimport", dllimport);
|
||||
Replaceall(proxy_class_code, "$dllimport", dllimport);
|
||||
Replaceall(proxy_class_constants_code, "$dllimport", dllimport);
|
||||
|
||||
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
|
||||
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
|
||||
if (!has_outerclass)
|
||||
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
|
||||
else {
|
||||
Swig_offset_string(proxy_class_def, nesting_depth);
|
||||
Append(old_proxy_class_code, proxy_class_def);
|
||||
Swig_offset_string(proxy_class_code, nesting_depth);
|
||||
Append(old_proxy_class_code, proxy_class_code);
|
||||
}
|
||||
|
||||
// Write out all the constants
|
||||
if (Len(proxy_class_constants_code) != 0)
|
||||
Printv(f_proxy, proxy_class_constants_code, NIL);
|
||||
|
||||
Printf(f_proxy, "}\n");
|
||||
addCloseNamespace(nspace, f_proxy);
|
||||
Delete(f_proxy);
|
||||
f_proxy = NULL;
|
||||
if (Len(proxy_class_constants_code) != 0) {
|
||||
if (!has_outerclass)
|
||||
Printv(f_proxy, proxy_class_constants_code, NIL);
|
||||
else {
|
||||
Swig_offset_string(proxy_class_constants_code, nesting_depth);
|
||||
Append(old_proxy_class_code, proxy_class_constants_code);
|
||||
}
|
||||
}
|
||||
if (!has_outerclass) {
|
||||
Printf(f_proxy, "}\n");
|
||||
addCloseNamespace(nspace, f_proxy);
|
||||
Delete(f_proxy);
|
||||
f_proxy = NULL;
|
||||
} else {
|
||||
for (int i = 0; i < nesting_depth; ++i)
|
||||
Append(old_proxy_class_code, " ");
|
||||
Append(old_proxy_class_code, "}\n\n");
|
||||
--nesting_depth;
|
||||
}
|
||||
|
||||
/* Output the downcast method, if necessary. Note: There's no other really
|
||||
good place to put this code, since Abstract Base Classes (ABCs) can and should have
|
||||
|
|
@ -1971,17 +2041,18 @@ public:
|
|||
|
||||
Delete(csclazzname);
|
||||
Delete(proxy_class_name);
|
||||
proxy_class_name = NULL;
|
||||
Delete(full_proxy_class_name);
|
||||
full_proxy_class_name = NULL;
|
||||
proxy_class_name = old_proxy_class_name;
|
||||
Delete(full_imclass_name);
|
||||
full_imclass_name = NULL;
|
||||
full_imclass_name = old_full_imclass_name;
|
||||
Delete(destructor_call);
|
||||
destructor_call = NULL;
|
||||
destructor_call = old_destructor_call;
|
||||
Delete(proxy_class_constants_code);
|
||||
proxy_class_constants_code = NULL;
|
||||
proxy_class_constants_code = old_proxy_class_constants_code;
|
||||
Delete(proxy_class_def);
|
||||
proxy_class_def = old_proxy_class_def;
|
||||
Delete(proxy_class_code);
|
||||
proxy_class_code = old_proxy_class_code;
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1994,7 +2065,7 @@ public:
|
|||
|
||||
if (proxy_flag) {
|
||||
String *overloaded_name = getOverloadedName(n);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
|
||||
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
|
||||
Setattr(n, "imfuncname", intermediary_function_name);
|
||||
proxyClassFunctionHandler(n);
|
||||
|
|
@ -2014,7 +2085,7 @@ public:
|
|||
|
||||
if (proxy_flag) {
|
||||
String *overloaded_name = getOverloadedName(n);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
|
||||
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
|
||||
Setattr(n, "imfuncname", intermediary_function_name);
|
||||
proxyClassFunctionHandler(n);
|
||||
|
|
@ -2094,7 +2165,7 @@ public:
|
|||
|
||||
if (wrapping_member_flag && !enum_constant_flag) {
|
||||
// Properties
|
||||
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0);
|
||||
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
|
||||
if (setter_flag)
|
||||
Swig_typemap_attach_parms("csvarin", l, NULL);
|
||||
}
|
||||
|
|
@ -2264,7 +2335,7 @@ public:
|
|||
Node *explicit_n = Getattr(n, "explicitcallnode");
|
||||
if (explicit_n) {
|
||||
String *ex_overloaded_name = getOverloadedName(explicit_n);
|
||||
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
|
||||
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name);
|
||||
|
||||
String *ex_imcall = Copy(imcall);
|
||||
Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
|
||||
|
|
@ -3376,14 +3447,21 @@ public:
|
|||
|
||||
// Output the director connect method:
|
||||
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
||||
String *swig_director_connect = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
|
||||
String *dirclassname = directorClassName(n);
|
||||
String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
|
||||
String *wname = Swig_name_wrapper(swig_director_connect);
|
||||
String *sym_name = Getattr(n, "sym:name");
|
||||
String *qualified_classname = Copy(sym_name);
|
||||
String *nspace = getNSpace();
|
||||
String *dirClassName = directorClassName(n);
|
||||
String *smartptr = Getattr(n, "feature:smartptr");
|
||||
if (!GetFlag(n, "feature:flatnested")) {
|
||||
for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
|
||||
|
||||
Push(qualified_classname, ".");
|
||||
Push(qualified_classname, Getattr(outer_class, "sym:name"));
|
||||
}
|
||||
}
|
||||
if (nspace)
|
||||
Insert(qualified_classname, 0, NewStringf("%s.", nspace));
|
||||
|
||||
|
|
@ -3415,7 +3493,7 @@ public:
|
|||
Printf(code_wrap->def, ", ");
|
||||
if (i != first_class_dmethod)
|
||||
Printf(code_wrap->code, ", ");
|
||||
Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirClassName, methid, methid);
|
||||
Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirclassname, methid, methid);
|
||||
Printf(code_wrap->code, "callback%s", methid);
|
||||
Printf(imclass_class_code, ", %s.SwigDelegate%s_%s delegate%s", qualified_classname, sym_name, methid, methid);
|
||||
}
|
||||
|
|
@ -3432,7 +3510,7 @@ public:
|
|||
Delete(wname);
|
||||
Delete(swig_director_connect);
|
||||
Delete(qualified_classname);
|
||||
Delete(dirClassName);
|
||||
Delete(dirclassname);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------
|
||||
|
|
@ -3485,7 +3563,7 @@ public:
|
|||
// we're consistent with the sym:overload name in functionWrapper. (?? when
|
||||
// does the overloaded method name get set?)
|
||||
|
||||
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name));
|
||||
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name));
|
||||
|
||||
qualified_return = SwigType_rcaststr(returntype, "c_result");
|
||||
|
||||
|
|
@ -3931,6 +4009,7 @@ public:
|
|||
Delete(proxy_method_types);
|
||||
Delete(callback_def);
|
||||
Delete(callback_code);
|
||||
Delete(dirclassname);
|
||||
DelWrapper(w);
|
||||
|
||||
return status;
|
||||
|
|
@ -3970,13 +4049,11 @@ public:
|
|||
String *basetype = Getattr(parent, "classtype");
|
||||
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
|
||||
String *call = Swig_csuperclass_call(0, basetype, superparms);
|
||||
String *classtype = SwigType_namestr(Getattr(n, "name"));
|
||||
|
||||
Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
|
||||
Printf(f_directors, " swig_init_callbacks();\n");
|
||||
Printf(f_directors, "}\n\n");
|
||||
|
||||
Delete(classtype);
|
||||
Delete(target);
|
||||
Delete(call);
|
||||
}
|
||||
|
|
@ -4047,6 +4124,29 @@ public:
|
|||
return Language::classDirectorInit(n);
|
||||
}
|
||||
|
||||
int classDeclaration(Node *n) {
|
||||
String *old_director_callback_typedefs = director_callback_typedefs;
|
||||
String *old_director_callbacks = director_callbacks;
|
||||
String *old_director_delegate_callback = director_delegate_callback;
|
||||
String *old_director_delegate_definitions = director_delegate_definitions;
|
||||
String *old_director_delegate_instances = director_delegate_instances;
|
||||
String *old_director_method_types = director_method_types;
|
||||
String *old_director_connect_parms = director_connect_parms;
|
||||
|
||||
int ret = Language::classDeclaration(n);
|
||||
|
||||
// these variables are deleted in emitProxyClassDefAndCPPCasts, hence no Delete here
|
||||
director_callback_typedefs = old_director_callback_typedefs;
|
||||
director_callbacks = old_director_callbacks;
|
||||
director_delegate_callback = old_director_delegate_callback;
|
||||
director_delegate_definitions = old_director_delegate_definitions;
|
||||
director_delegate_instances = old_director_delegate_instances;
|
||||
director_method_types = old_director_method_types;
|
||||
director_connect_parms = old_director_connect_parms;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* classDirectorDestructor()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
@ -4079,7 +4179,7 @@ public:
|
|||
|
||||
int classDirectorEnd(Node *n) {
|
||||
int i;
|
||||
String *director_classname = directorClassName(n);
|
||||
String *dirclassname = directorClassName(n);
|
||||
|
||||
Wrapper *w = NewWrapper();
|
||||
|
||||
|
|
@ -4089,7 +4189,7 @@ public:
|
|||
|
||||
Printf(f_directors_h, " void swig_connect_director(");
|
||||
|
||||
Printf(w->def, "void %s::swig_connect_director(", director_classname);
|
||||
Printf(w->def, "void %s::swig_connect_director(", dirclassname);
|
||||
|
||||
for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
|
||||
UpcallData *udata = Getitem(dmethods_seq, i);
|
||||
|
|
@ -4116,7 +4216,7 @@ public:
|
|||
Printf(f_directors_h, "};\n\n");
|
||||
Printf(w->code, "}\n\n");
|
||||
|
||||
Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname);
|
||||
Printf(w->code, "void %s::swig_init_callbacks() {\n", dirclassname);
|
||||
for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
|
||||
UpcallData *udata = Getitem(dmethods_seq, i);
|
||||
String *overname = Getattr(udata, "overname");
|
||||
|
|
@ -4127,6 +4227,7 @@ public:
|
|||
Wrapper_print(w, f_directors);
|
||||
|
||||
DelWrapper(w);
|
||||
Delete(dirclassname);
|
||||
|
||||
return Language::classDirectorEnd(n);
|
||||
}
|
||||
|
|
@ -4159,8 +4260,8 @@ public:
|
|||
String *base = Getattr(n, "classtype");
|
||||
String *class_ctor = NewString("Swig::Director()");
|
||||
|
||||
String *directorname = directorClassName(n);
|
||||
String *declaration = Swig_class_declaration(n, directorname);
|
||||
String *dirclassname = directorClassName(n);
|
||||
String *declaration = Swig_class_declaration(n, dirclassname);
|
||||
|
||||
Printf(declaration, " : public %s, public Swig::Director", base);
|
||||
|
||||
|
|
@ -4168,9 +4269,12 @@ public:
|
|||
Setattr(n, "director:decl", declaration);
|
||||
Setattr(n, "director:ctor", class_ctor);
|
||||
|
||||
Delete(directorname);
|
||||
Delete(dirclassname);
|
||||
}
|
||||
|
||||
bool nestedClassesSupported() const {
|
||||
return true;
|
||||
}
|
||||
}; /* class CSHARP */
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class JAVA:public Language {
|
|||
int n_directors;
|
||||
int first_class_dmethod;
|
||||
int curr_class_dmethod;
|
||||
int nesting_depth;
|
||||
|
||||
enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
|
||||
|
||||
|
|
@ -154,7 +155,8 @@ public:
|
|||
n_dmethods(0),
|
||||
n_directors(0),
|
||||
first_class_dmethod(0),
|
||||
curr_class_dmethod(0) {
|
||||
curr_class_dmethod(0),
|
||||
nesting_depth(0){
|
||||
/* for now, multiple inheritance in directors is disabled, this
|
||||
should be easy to implement though */
|
||||
director_multiple_inheritance = 0;
|
||||
|
|
@ -204,7 +206,13 @@ public:
|
|||
proxyname = Getattr(n, "proxyname");
|
||||
if (!proxyname || jnidescriptor) {
|
||||
String *nspace = Getattr(n, "sym:nspace");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *symname = Copy(Getattr(n, "sym:name"));
|
||||
if (symname && !GetFlag(n, "feature:flatnested")) {
|
||||
for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
|
||||
Push(symname, ".");
|
||||
Push(symname, Getattr(outer_class, "sym:name"));
|
||||
}
|
||||
}
|
||||
if (nspace) {
|
||||
if (package && !jnidescriptor)
|
||||
proxyname = NewStringf("%s.%s.%s", package, nspace, symname);
|
||||
|
|
@ -217,6 +225,7 @@ public:
|
|||
Setattr(n, "proxyname", proxyname); // Cache it
|
||||
Delete(proxyname);
|
||||
}
|
||||
Delete(symname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1134,7 +1143,7 @@ public:
|
|||
*/
|
||||
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
|
||||
// Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
|
||||
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0;
|
||||
bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0;
|
||||
|
||||
String *getter_setter_name = NewString("");
|
||||
if (!getter_flag)
|
||||
|
|
@ -1713,6 +1722,7 @@ public:
|
|||
String *c_baseclassname = NULL;
|
||||
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
||||
bool feature_director = Swig_directorclass(n) ? true : false;
|
||||
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
|
||||
|
||||
// Inheritance from pure Java classes
|
||||
Node *attributes = NewHash();
|
||||
|
|
@ -1773,8 +1783,11 @@ public:
|
|||
const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
|
||||
|
||||
// Start writing the proxy class
|
||||
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
|
||||
"\n", typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
|
||||
if (!has_outerclass) // Import statements
|
||||
Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE),"\n", NIL);
|
||||
else
|
||||
Printv(proxy_class_def, "static ", NIL); // C++ nested classes correspond to static java classes
|
||||
Printv(proxy_class_def, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
|
||||
" $javaclassname", // Class name and bases
|
||||
(*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces) ? // Pure Java interfaces
|
||||
" implements " : "", pure_interfaces, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
|
||||
|
|
@ -1825,7 +1838,7 @@ public:
|
|||
/* Also insert the swigTakeOwnership and swigReleaseOwnership methods */
|
||||
if (feature_director) {
|
||||
String *destruct_jnicall, *release_jnicall, *take_jnicall;
|
||||
String *changeown_method_name = Swig_name_member(getNSpace(), proxy_class_name, "change_ownership");
|
||||
String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership");
|
||||
|
||||
destruct_jnicall = NewStringf("%s()", destruct_methodname);
|
||||
release_jnicall = NewStringf("%s.%s(this, swigCPtr, false)", full_imclass_name, changeown_method_name);
|
||||
|
|
@ -1851,7 +1864,7 @@ public:
|
|||
// Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
|
||||
if (derived) {
|
||||
String *smartptr = Getattr(n, "feature:smartptr");
|
||||
String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
|
||||
String *upcast_method = Swig_name_member(getNSpace(), getClassPrefix(), smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
|
||||
String *jniname = makeValidJniName(upcast_method);
|
||||
String *wname = Swig_name_wrapper(jniname);
|
||||
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method);
|
||||
|
|
@ -1908,13 +1921,29 @@ public:
|
|||
virtual int classHandler(Node *n) {
|
||||
|
||||
File *f_proxy = NULL;
|
||||
String *old_proxy_class_name = proxy_class_name;
|
||||
String *old_full_proxy_class_name = full_proxy_class_name;
|
||||
String *old_full_imclass_name = full_imclass_name;
|
||||
String *old_destructor_call = destructor_call;
|
||||
String *old_destructor_throws_clause = destructor_throws_clause;
|
||||
String *old_proxy_class_constants_code = proxy_class_constants_code;
|
||||
String *old_proxy_class_def = proxy_class_def;
|
||||
String *old_proxy_class_code = proxy_class_code;
|
||||
if (proxy_flag) {
|
||||
proxy_class_name = NewString(Getattr(n, "sym:name"));
|
||||
String *nspace = getNSpace();
|
||||
constructIntermediateClassName(n);
|
||||
|
||||
String *outerClassesPrefix = 0;
|
||||
if (Node *outer = Getattr(n, "nested:outer")) {
|
||||
outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
|
||||
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
|
||||
Push(outerClassesPrefix, ".");
|
||||
Push(outerClassesPrefix, Getattr(outer, "sym:name"));
|
||||
}
|
||||
}
|
||||
if (!nspace) {
|
||||
full_proxy_class_name = NewStringf("%s", proxy_class_name);
|
||||
full_proxy_class_name = outerClassesPrefix ? NewStringf("%s.%s", outerClassesPrefix, proxy_class_name) : NewStringf("%s", proxy_class_name);
|
||||
|
||||
if (Cmp(proxy_class_name, imclass_name) == 0) {
|
||||
Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
|
||||
|
|
@ -1926,54 +1955,73 @@ public:
|
|||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
if (package)
|
||||
full_proxy_class_name = NewStringf("%s.%s.%s", package, nspace, proxy_class_name);
|
||||
else
|
||||
full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
|
||||
if (outerClassesPrefix) {
|
||||
if (package)
|
||||
full_proxy_class_name = NewStringf("%s.%s.%s.%s", package, nspace, outerClassesPrefix, proxy_class_name);
|
||||
else
|
||||
full_proxy_class_name = NewStringf("%s.%s.%s", nspace, outerClassesPrefix, proxy_class_name);
|
||||
} else {
|
||||
if (package)
|
||||
full_proxy_class_name = NewStringf("%s.%s.%s", package, nspace, proxy_class_name);
|
||||
else
|
||||
full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!addSymbol(proxy_class_name, n, nspace))
|
||||
return SWIG_ERROR;
|
||||
|
||||
String *output_directory = outputDirectory(nspace);
|
||||
String *filen = NewStringf("%s%s.java", output_directory, proxy_class_name);
|
||||
f_proxy = NewFile(filen, "w", SWIG_output_files());
|
||||
if (!f_proxy) {
|
||||
FileErrorDisplay(filen);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
Append(filenames_list, Copy(filen));
|
||||
Delete(filen);
|
||||
filen = NULL;
|
||||
|
||||
// Start writing out the proxy class file
|
||||
emitBanner(f_proxy);
|
||||
|
||||
if (package || nspace) {
|
||||
Printf(f_proxy, "package ");
|
||||
if (package)
|
||||
Printv(f_proxy, package, nspace ? "." : "", NIL);
|
||||
if (outerClassesPrefix) {
|
||||
Replaceall(outerClassesPrefix, ".", "::");
|
||||
String *fnspace = nspace ? NewStringf("%s::%s", nspace, outerClassesPrefix) : outerClassesPrefix;
|
||||
if (!addSymbol(proxy_class_name, n, fnspace))
|
||||
return SWIG_ERROR;
|
||||
if (nspace)
|
||||
Printv(f_proxy, nspace, NIL);
|
||||
Printf(f_proxy, ";\n");
|
||||
Delete(fnspace);
|
||||
Delete(outerClassesPrefix);
|
||||
}
|
||||
else {
|
||||
if (!addSymbol(proxy_class_name, n, nspace))
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
|
||||
Clear(proxy_class_def);
|
||||
Clear(proxy_class_code);
|
||||
if (!Getattr(n, "nested:outer")) {
|
||||
String *output_directory = outputDirectory(nspace);
|
||||
String *filen = NewStringf("%s%s.java", output_directory, proxy_class_name);
|
||||
f_proxy = NewFile(filen, "w", SWIG_output_files());
|
||||
if (!f_proxy) {
|
||||
FileErrorDisplay(filen);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
Append(filenames_list, Copy(filen));
|
||||
Delete(filen);
|
||||
Delete(output_directory);
|
||||
|
||||
// Start writing out the proxy class file
|
||||
emitBanner(f_proxy);
|
||||
|
||||
if (package || nspace) {
|
||||
Printf(f_proxy, "package ");
|
||||
if (package)
|
||||
Printv(f_proxy, package, nspace ? "." : "", NIL);
|
||||
if (nspace)
|
||||
Printv(f_proxy, nspace, NIL);
|
||||
Printf(f_proxy, ";\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
++nesting_depth;
|
||||
|
||||
proxy_class_def = NewString("");
|
||||
proxy_class_code = NewString("");
|
||||
destructor_call = NewString("");
|
||||
destructor_throws_clause = NewString("");
|
||||
proxy_class_constants_code = NewString("");
|
||||
Delete(output_directory);
|
||||
}
|
||||
|
||||
Language::classHandler(n);
|
||||
|
||||
if (proxy_flag) {
|
||||
|
||||
emitProxyClassDefAndCPPCasts(n);
|
||||
|
||||
String *javaclazzname = Swig_name_member(getNSpace(), proxy_class_name, ""); // mangled full proxy class name
|
||||
String *javaclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name
|
||||
|
||||
Replaceall(proxy_class_def, "$javaclassname", proxy_class_name);
|
||||
Replaceall(proxy_class_code, "$javaclassname", proxy_class_name);
|
||||
|
|
@ -1991,22 +2039,43 @@ public:
|
|||
Replaceall(proxy_class_code, "$imclassname", full_imclass_name);
|
||||
Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name);
|
||||
|
||||
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
|
||||
bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
|
||||
if (!has_outerclass)
|
||||
Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
|
||||
else {
|
||||
Swig_offset_string(proxy_class_def, nesting_depth);
|
||||
Append(old_proxy_class_code, proxy_class_def);
|
||||
Swig_offset_string(proxy_class_code, nesting_depth);
|
||||
Append(old_proxy_class_code, proxy_class_code);
|
||||
}
|
||||
|
||||
// Write out all the constants
|
||||
if (Len(proxy_class_constants_code) != 0)
|
||||
Printv(f_proxy, proxy_class_constants_code, NIL);
|
||||
if (Len(proxy_class_constants_code) != 0) {
|
||||
if (!has_outerclass)
|
||||
Printv(f_proxy, proxy_class_constants_code, NIL);
|
||||
else {
|
||||
Swig_offset_string(proxy_class_constants_code, nesting_depth);
|
||||
Append(old_proxy_class_code, proxy_class_constants_code);
|
||||
}
|
||||
}
|
||||
|
||||
Printf(f_proxy, "}\n");
|
||||
Delete(f_proxy);
|
||||
f_proxy = NULL;
|
||||
if (!has_outerclass) {
|
||||
Printf(f_proxy, "}\n");
|
||||
Delete(f_proxy);
|
||||
f_proxy = NULL;
|
||||
} else {
|
||||
for (int i = 0; i < nesting_depth; ++i)
|
||||
Append(old_proxy_class_code, " ");
|
||||
Append(old_proxy_class_code, "}\n\n");
|
||||
--nesting_depth;
|
||||
}
|
||||
|
||||
/* Output the downcast method, if necessary. Note: There's no other really
|
||||
good place to put this code, since Abstract Base Classes (ABCs) can and should have
|
||||
downcasts, making the constructorHandler() a bad place (because ABCs don't get to
|
||||
have constructors emitted.) */
|
||||
if (GetFlag(n, "feature:javadowncast")) {
|
||||
String *downcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGDowncast");
|
||||
String *downcast_method = Swig_name_member(getNSpace(), getClassPrefix(), "SWIGDowncast");
|
||||
String *jniname = makeValidJniName(downcast_method);
|
||||
String *wname = Swig_name_wrapper(jniname);
|
||||
|
||||
|
|
@ -2038,17 +2107,21 @@ public:
|
|||
|
||||
Delete(javaclazzname);
|
||||
Delete(proxy_class_name);
|
||||
proxy_class_name = NULL;
|
||||
proxy_class_name = old_proxy_class_name;
|
||||
Delete(full_proxy_class_name);
|
||||
full_proxy_class_name = NULL;
|
||||
full_proxy_class_name = old_full_proxy_class_name;
|
||||
Delete(full_imclass_name);
|
||||
full_imclass_name = NULL;
|
||||
full_imclass_name = old_full_imclass_name;
|
||||
Delete(destructor_call);
|
||||
destructor_call = NULL;
|
||||
destructor_call = old_destructor_call;
|
||||
Delete(destructor_throws_clause);
|
||||
destructor_throws_clause = NULL;
|
||||
destructor_throws_clause = old_destructor_throws_clause;
|
||||
Delete(proxy_class_constants_code);
|
||||
proxy_class_constants_code = NULL;
|
||||
proxy_class_constants_code = old_proxy_class_constants_code;
|
||||
Delete(proxy_class_def);
|
||||
proxy_class_def = old_proxy_class_def;
|
||||
Delete(proxy_class_code);
|
||||
proxy_class_code = old_proxy_class_code;
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
|
|
@ -2064,7 +2137,7 @@ public:
|
|||
|
||||
if (proxy_flag) {
|
||||
String *overloaded_name = getOverloadedName(n);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
|
||||
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
|
||||
Setattr(n, "imfuncname", intermediary_function_name);
|
||||
proxyClassFunctionHandler(n);
|
||||
|
|
@ -2086,7 +2159,7 @@ public:
|
|||
|
||||
if (proxy_flag) {
|
||||
String *overloaded_name = getOverloadedName(n);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
|
||||
String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
|
||||
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
|
||||
Setattr(n, "imfuncname", intermediary_function_name);
|
||||
proxyClassFunctionHandler(n);
|
||||
|
|
@ -2162,7 +2235,7 @@ public:
|
|||
|
||||
if (wrapping_member_flag && !enum_constant_flag) {
|
||||
// For wrapping member variables (Javabean setter)
|
||||
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0);
|
||||
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
|
||||
}
|
||||
|
||||
/* Start generating the proxy function */
|
||||
|
|
@ -2316,7 +2389,7 @@ public:
|
|||
Node *explicit_n = Getattr(n, "explicitcallnode");
|
||||
if (explicit_n) {
|
||||
String *ex_overloaded_name = getOverloadedName(explicit_n);
|
||||
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
|
||||
String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name);
|
||||
|
||||
String *ex_imcall = Copy(imcall);
|
||||
Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
|
||||
|
|
@ -3399,7 +3472,7 @@ public:
|
|||
// Output the director connect method:
|
||||
String *jni_imclass_name = makeValidJniName(imclass_name);
|
||||
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
||||
String *swig_director_connect = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
|
||||
String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
|
||||
String *swig_director_connect_jni = makeValidJniName(swig_director_connect);
|
||||
String *smartptr = Getattr(n, "feature:smartptr");
|
||||
String *dirClassName = directorClassName(n);
|
||||
|
|
@ -3439,7 +3512,7 @@ public:
|
|||
Delete(swig_director_connect);
|
||||
|
||||
// Output the swigReleaseOwnership, swigTakeOwnership methods:
|
||||
String *changeown_method_name = Swig_name_member(getNSpace(), proxy_class_name, "change_ownership");
|
||||
String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership");
|
||||
String *changeown_jnimethod_name = makeValidJniName(changeown_method_name);
|
||||
|
||||
Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean take_or_release);\n", changeown_method_name, full_proxy_class_name);
|
||||
|
|
@ -4519,6 +4592,9 @@ public:
|
|||
Setattr(n, "director:ctor", class_ctor);
|
||||
}
|
||||
|
||||
bool nestedClassesSupported() const {
|
||||
return true;
|
||||
}
|
||||
}; /* class JAVA */
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ static int director_mode = 0;
|
|||
static int director_protected_mode = 1;
|
||||
static int all_protected_mode = 0;
|
||||
static int naturalvar_mode = 0;
|
||||
Language* Language::this_ = 0;
|
||||
Language *Language::this_ = 0;
|
||||
|
||||
/* Set director_protected_mode */
|
||||
void Wrapper_director_mode_set(int flag) {
|
||||
|
|
@ -355,7 +355,7 @@ Language::~Language() {
|
|||
String *dirclassname;
|
||||
String *nspace = NewString(Getattr(n, "sym:nspace"));
|
||||
const char *attrib = "director:classname";
|
||||
String *classname = Getattr(n, "sym:name");
|
||||
String *classname = getClassPrefix();
|
||||
|
||||
Replace(nspace, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY);
|
||||
if (Len(nspace) > 0)
|
||||
|
|
@ -1015,8 +1015,6 @@ int Language::cDeclaration(Node *n) {
|
|||
/* Some kind of variable declaration */
|
||||
String *declaration = Copy(decl);
|
||||
Delattr(n, "decl");
|
||||
if (Getattr(n, "nested"))
|
||||
SetFlag(n, "feature:immutable");
|
||||
if (!CurrentClass) {
|
||||
if (Swig_storage_isextern(n) || ForceExtern) {
|
||||
if (AddExtern) {
|
||||
|
|
@ -2362,6 +2360,15 @@ int Language::classDeclaration(Node *n) {
|
|||
return SWIG_NOWRAP;
|
||||
}
|
||||
|
||||
// save class local variables for nested classes support
|
||||
int oldInClass = InClass;
|
||||
String *oldClassType = ClassType;
|
||||
String *oldClassPrefix = ClassPrefix;
|
||||
String *oldClassName = ClassName;
|
||||
String *oldDirectorClassName = DirectorClassName;
|
||||
String *oldNSpace = NSpace;
|
||||
Node *oldCurrentClass = CurrentClass;
|
||||
|
||||
String *kind = Getattr(n, "kind");
|
||||
String *name = Getattr(n, "name");
|
||||
String *tdname = Getattr(n, "tdname");
|
||||
|
|
@ -2370,6 +2377,8 @@ int Language::classDeclaration(Node *n) {
|
|||
|
||||
int strip = CPlusPlus ? 1 : unnamed && tdname;
|
||||
|
||||
if (cplus_mode != PUBLIC)
|
||||
return SWIG_NOWRAP;
|
||||
if (!name) {
|
||||
Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
|
||||
return SWIG_NOWRAP;
|
||||
|
|
@ -2380,15 +2389,21 @@ int Language::classDeclaration(Node *n) {
|
|||
Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname));
|
||||
return SWIG_NOWRAP;
|
||||
}
|
||||
|
||||
AccessMode oldAccessMode = cplus_mode;
|
||||
Node *outerClass = Getattr(n, "nested:outer");
|
||||
if (outerClass && oldAccessMode != PUBLIC)
|
||||
return SWIG_NOWRAP;
|
||||
ClassName = Copy(name);
|
||||
ClassPrefix = Copy(symname);
|
||||
if (Cmp(kind, "class") == 0) {
|
||||
cplus_mode = PRIVATE;
|
||||
} else {
|
||||
cplus_mode = PUBLIC;
|
||||
}
|
||||
|
||||
ClassName = Copy(name);
|
||||
ClassPrefix = Copy(symname);
|
||||
for (; outerClass; outerClass = Getattr(outerClass, "nested:outer")) {
|
||||
Push(ClassPrefix, "_");
|
||||
Push(ClassPrefix, Getattr(outerClass, "sym:name"));
|
||||
}
|
||||
if (strip) {
|
||||
ClassType = Copy(name);
|
||||
} else {
|
||||
|
|
@ -2399,9 +2414,8 @@ int Language::classDeclaration(Node *n) {
|
|||
|
||||
InClass = 1;
|
||||
CurrentClass = n;
|
||||
|
||||
String *oldNSpace = NSpace;
|
||||
NSpace = Getattr(n, "sym:nspace");
|
||||
int oldAbstract = Abstract;
|
||||
|
||||
/* Call classHandler() here */
|
||||
if (!ImportMode) {
|
||||
|
|
@ -2443,25 +2457,27 @@ int Language::classDeclaration(Node *n) {
|
|||
classDirector(n);
|
||||
}
|
||||
/* check for abstract after resolving directors */
|
||||
Abstract = abstractClassTest(n);
|
||||
|
||||
Abstract = abstractClassTest(n);
|
||||
classHandler(n);
|
||||
} else {
|
||||
Abstract = abstractClassTest(n);
|
||||
Language::classHandler(n);
|
||||
}
|
||||
|
||||
Abstract = oldAbstract;
|
||||
cplus_mode = oldAccessMode;
|
||||
NSpace = oldNSpace;
|
||||
InClass = 0;
|
||||
CurrentClass = 0;
|
||||
InClass = oldInClass;
|
||||
CurrentClass = oldCurrentClass;
|
||||
Delete(ClassType);
|
||||
ClassType = 0;
|
||||
ClassType = oldClassType;
|
||||
Delete(ClassPrefix);
|
||||
ClassPrefix = 0;
|
||||
ClassPrefix = oldClassPrefix;
|
||||
Delete(ClassName);
|
||||
ClassName = 0;
|
||||
ClassName = oldClassName;
|
||||
Delete(DirectorClassName);
|
||||
DirectorClassName = 0;
|
||||
DirectorClassName = oldDirectorClassName;
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2640,7 +2656,7 @@ int Language::constructorDeclaration(Node *n) {
|
|||
String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
|
||||
String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
|
||||
Delete(scope);
|
||||
if (!Equal(actual_name, expected_name) && !(Getattr(n, "template"))) {
|
||||
if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name)) {
|
||||
bool illegal_name = true;
|
||||
if (Extend) {
|
||||
// Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous
|
||||
|
|
@ -3426,6 +3442,9 @@ bool Language::extraDirectorProtectedCPPMethodsRequired() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Language::nestedClassesSupported() const {
|
||||
return false;
|
||||
}
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::is_wrapping_class()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -3612,3 +3631,4 @@ Language *Language::instance() {
|
|||
Hash *Language::getClassHash() const {
|
||||
return classhash;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -483,6 +483,10 @@ void SWIG_getoptions(int argc, char *argv[]) {
|
|||
Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);
|
||||
Swig_cparse_cplusplus(1);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-c++out") == 0) {
|
||||
// Undocumented
|
||||
Swig_cparse_cplusplusout(1);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-fcompact") == 0) {
|
||||
Wrapper_compact_print_mode_set(1);
|
||||
Swig_mark_arg(i);
|
||||
|
|
@ -855,8 +859,9 @@ void SWIG_getoptions(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void flatten_nested() {
|
||||
Swig_feature_set(Swig_cparse_features(), "", 0, "feature:flatnested", "1", 0);
|
||||
}
|
||||
|
||||
|
||||
int SWIG_main(int argc, char *argv[], Language *l) {
|
||||
|
|
@ -947,6 +952,11 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
// Don't check for an input file if -external-runtime is passed
|
||||
Swig_check_options(external_runtime ? 0 : 1);
|
||||
|
||||
if (CPlusPlus && cparse_cplusplusout) {
|
||||
Printf(stderr, "The -c++out option is for C input but C++ input has been requested via -c++\n");
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
install_opts(argc, argv);
|
||||
|
||||
// Add language dependent directory to the search path
|
||||
|
|
@ -1151,6 +1161,10 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
// add "ignore" directive if nested classes are not supported
|
||||
if (!lang->nestedClassesSupported())
|
||||
flatten_nested();
|
||||
|
||||
Node *top = Swig_cparse(cpps);
|
||||
|
||||
if (dump_top & STAGE1) {
|
||||
|
|
@ -1161,6 +1175,11 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
Printf(stdout, "debug-module stage 1\n");
|
||||
Swig_print_tree(Getattr(top, "module"));
|
||||
}
|
||||
if (!CPlusPlus) {
|
||||
if (Verbose)
|
||||
Printf(stdout, "Processing unnamed structs...\n");
|
||||
Swig_nested_name_unnamed_c_structs(top);
|
||||
}
|
||||
|
||||
if (Verbose) {
|
||||
Printf(stdout, "Processing types...\n");
|
||||
|
|
@ -1181,6 +1200,12 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
}
|
||||
Swig_default_allocators(top);
|
||||
|
||||
if (CPlusPlus) {
|
||||
if (Verbose)
|
||||
Printf(stdout, "Processing nested classes...\n");
|
||||
Swig_nested_process_classes(top);
|
||||
}
|
||||
|
||||
if (dump_top & STAGE3) {
|
||||
Printf(stdout, "debug-top stage 3\n");
|
||||
Swig_print_tree(top);
|
||||
|
|
|
|||
444
Source/Modules/nested.cxx
Normal file
444
Source/Modules/nested.cxx
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* This file is part of SWIG, which is licensed as a whole under version 3
|
||||
* (or any later version) of the GNU General Public License. Some additional
|
||||
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
||||
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
||||
* included with the SWIG source code as distributed by the SWIG developers
|
||||
* and at http://www.swig.org/legal.html.
|
||||
*
|
||||
* nested.cxx
|
||||
*
|
||||
* Nested structs support
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swigmod.h"
|
||||
#include "cparse.h"
|
||||
|
||||
// Nested classes processing section
|
||||
static Hash *classhash = 0;
|
||||
|
||||
static String *make_name(Node *n, String *name, SwigType *decl) {
|
||||
int destructor = name && (*(Char(name)) == '~');
|
||||
if (String *yyrename = Getattr(n, "class_rename")) {
|
||||
String *s = NewString(yyrename);
|
||||
Delattr(n, "class_rename");
|
||||
if (destructor && (*(Char(s)) != '~')) {
|
||||
Insert(s, 0, "~");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
if (!name)
|
||||
return 0;
|
||||
return Swig_name_make(n, 0, name, decl, 0);
|
||||
}
|
||||
|
||||
// C version of add_symbols()
|
||||
static void add_symbols_c(Node *n) {
|
||||
String *decl;
|
||||
String *wrn = 0;
|
||||
String *symname = 0;
|
||||
int iscdecl = Cmp(nodeType(n), "cdecl") == 0;
|
||||
Setattr(n, "ismember", "1");
|
||||
Setattr(n, "access", "public");
|
||||
if (Getattr(n, "sym:name"))
|
||||
return;
|
||||
decl = Getattr(n, "decl");
|
||||
if (!SwigType_isfunction(decl)) {
|
||||
String *name = Getattr(n, "name");
|
||||
String *makename = Getattr(n, "parser:makename");
|
||||
if (iscdecl) {
|
||||
String *storage = Getattr(n, "storage");
|
||||
if (Cmp(storage, "typedef") == 0) {
|
||||
Setattr(n, "kind", "typedef");
|
||||
} else {
|
||||
SwigType *type = Getattr(n, "type");
|
||||
String *value = Getattr(n, "value");
|
||||
Setattr(n, "kind", "variable");
|
||||
if (value && Len(value)) {
|
||||
Setattr(n, "hasvalue", "1");
|
||||
}
|
||||
if (type) {
|
||||
SwigType *ty;
|
||||
SwigType *tmp = 0;
|
||||
if (decl) {
|
||||
ty = tmp = Copy(type);
|
||||
SwigType_push(ty, decl);
|
||||
} else {
|
||||
ty = type;
|
||||
}
|
||||
if (!SwigType_ismutable(ty)) {
|
||||
SetFlag(n, "hasconsttype");
|
||||
SetFlag(n, "feature:immutable");
|
||||
}
|
||||
if (tmp)
|
||||
Delete(tmp);
|
||||
}
|
||||
if (!type) {
|
||||
Printf(stderr, "notype name %s\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
Swig_features_get(Swig_cparse_features(), 0, name, 0, n);
|
||||
if (makename) {
|
||||
symname = make_name(n, makename, 0);
|
||||
Delattr(n, "parser:makename"); /* temporary information, don't leave it hanging around */
|
||||
} else {
|
||||
makename = name;
|
||||
symname = make_name(n, makename, 0);
|
||||
}
|
||||
|
||||
if (!symname) {
|
||||
symname = Copy(Getattr(n, "unnamed"));
|
||||
}
|
||||
if (symname) {
|
||||
wrn = Swig_name_warning(n, 0, symname, 0);
|
||||
}
|
||||
} else {
|
||||
String *name = Getattr(n, "name");
|
||||
SwigType *fdecl = Copy(decl);
|
||||
SwigType *fun = SwigType_pop_function(fdecl);
|
||||
if (iscdecl) {
|
||||
Setattr(n, "kind", "function");
|
||||
}
|
||||
|
||||
Swig_features_get(Swig_cparse_features(), 0, name, fun, n);
|
||||
|
||||
symname = make_name(n, name, fun);
|
||||
wrn = Swig_name_warning(n, 0, symname, fun);
|
||||
|
||||
Delete(fdecl);
|
||||
Delete(fun);
|
||||
|
||||
}
|
||||
if (!symname)
|
||||
return;
|
||||
if (GetFlag(n, "feature:ignore")) {
|
||||
/* Only add to C symbol table and continue */
|
||||
Swig_symbol_add(0, n);
|
||||
} else if (strncmp(Char(symname), "$ignore", 7) == 0) {
|
||||
char *c = Char(symname) + 7;
|
||||
SetFlag(n, "feature:ignore");
|
||||
if (strlen(c)) {
|
||||
SWIG_WARN_NODE_BEGIN(n);
|
||||
Swig_warning(0, Getfile(n), Getline(n), "%s\n", c + 1);
|
||||
SWIG_WARN_NODE_END(n);
|
||||
}
|
||||
Swig_symbol_add(0, n);
|
||||
} else {
|
||||
Node *c;
|
||||
if ((wrn) && (Len(wrn))) {
|
||||
String *metaname = symname;
|
||||
if (!Getmeta(metaname, "already_warned")) {
|
||||
SWIG_WARN_NODE_BEGIN(n);
|
||||
Swig_warning(0, Getfile(n), Getline(n), "%s\n", wrn);
|
||||
SWIG_WARN_NODE_END(n);
|
||||
Setmeta(metaname, "already_warned", "1");
|
||||
}
|
||||
}
|
||||
c = Swig_symbol_add(symname, n);
|
||||
|
||||
if (c != n) {
|
||||
/* symbol conflict attempting to add in the new symbol */
|
||||
if (Getattr(n, "sym:weak")) {
|
||||
Setattr(n, "sym:name", symname);
|
||||
} else {
|
||||
String *e = NewStringEmpty();
|
||||
String *en = NewStringEmpty();
|
||||
String *ec = NewStringEmpty();
|
||||
int redefined = Swig_need_redefined_warn(n, c, true);
|
||||
if (redefined) {
|
||||
Printf(en, "Identifier '%s' redefined (ignored)", symname);
|
||||
Printf(ec, "previous definition of '%s'", symname);
|
||||
} else {
|
||||
Printf(en, "Redundant redeclaration of '%s'", symname);
|
||||
Printf(ec, "previous declaration of '%s'", symname);
|
||||
}
|
||||
if (Cmp(symname, Getattr(n, "name"))) {
|
||||
Printf(en, " (Renamed from '%s')", SwigType_namestr(Getattr(n, "name")));
|
||||
}
|
||||
Printf(en, ",");
|
||||
if (Cmp(symname, Getattr(c, "name"))) {
|
||||
Printf(ec, " (Renamed from '%s')", SwigType_namestr(Getattr(c, "name")));
|
||||
}
|
||||
Printf(ec, ".");
|
||||
SWIG_WARN_NODE_BEGIN(n);
|
||||
if (redefined) {
|
||||
Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
|
||||
Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
|
||||
} else {
|
||||
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en);
|
||||
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec);
|
||||
}
|
||||
SWIG_WARN_NODE_END(n);
|
||||
Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec);
|
||||
Setattr(n, "error", e);
|
||||
Delete(e);
|
||||
Delete(en);
|
||||
Delete(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
Delete(symname);
|
||||
}
|
||||
|
||||
/* Strips C-style and C++-style comments from string in-place. */
|
||||
static void strip_comments(char *string) {
|
||||
int state = 0;
|
||||
/*
|
||||
* 0 - not in comment
|
||||
* 1 - in c-style comment
|
||||
* 2 - in c++-style comment
|
||||
* 3 - in string
|
||||
* 4 - after reading / not in comments
|
||||
* 5 - after reading * in c-style comments
|
||||
* 6 - after reading \ in strings
|
||||
*/
|
||||
char *c = string;
|
||||
while (*c) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (*c == '\"')
|
||||
state = 3;
|
||||
else if (*c == '/')
|
||||
state = 4;
|
||||
break;
|
||||
case 1:
|
||||
if (*c == '*')
|
||||
state = 5;
|
||||
*c = ' ';
|
||||
break;
|
||||
case 2:
|
||||
if (*c == '\n')
|
||||
state = 0;
|
||||
else
|
||||
*c = ' ';
|
||||
break;
|
||||
case 3:
|
||||
if (*c == '\"')
|
||||
state = 0;
|
||||
else if (*c == '\\')
|
||||
state = 6;
|
||||
break;
|
||||
case 4:
|
||||
if (*c == '/') {
|
||||
*(c - 1) = ' ';
|
||||
*c = ' ';
|
||||
state = 2;
|
||||
} else if (*c == '*') {
|
||||
*(c - 1) = ' ';
|
||||
*c = ' ';
|
||||
state = 1;
|
||||
} else
|
||||
state = 0;
|
||||
break;
|
||||
case 5:
|
||||
if (*c == '/')
|
||||
state = 0;
|
||||
else
|
||||
state = 1;
|
||||
*c = ' ';
|
||||
break;
|
||||
case 6:
|
||||
state = 3;
|
||||
break;
|
||||
}
|
||||
++c;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a %insert with a typedef to make a new name visible to C
|
||||
static Node *create_insert(Node *n, bool noTypedef = false) {
|
||||
// format a typedef
|
||||
String *ccode = Getattr(n, "code");
|
||||
Push(ccode, " ");
|
||||
if (noTypedef) {
|
||||
Push(ccode, Getattr(n, "name"));
|
||||
Push(ccode, " ");
|
||||
Push(ccode, Getattr(n, "kind"));
|
||||
} else {
|
||||
Push(ccode, Getattr(n, "kind"));
|
||||
Push(ccode, "typedef ");
|
||||
Append(ccode, " ");
|
||||
Append(ccode, Getattr(n, "tdname"));
|
||||
}
|
||||
Append(ccode, ";");
|
||||
|
||||
/* Strip comments - further code may break in presence of comments. */
|
||||
strip_comments(Char(ccode));
|
||||
|
||||
/* Make all SWIG created typedef structs/unions/classes unnamed else
|
||||
redefinition errors occur - nasty hack alert. */
|
||||
if (!noTypedef) {
|
||||
const char *types_array[3] = { "struct", "union", "class" };
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char *code_ptr = Char(ccode);
|
||||
while (code_ptr) {
|
||||
/* Replace struct name (as in 'struct name {...}' ) with whitespace
|
||||
name will be between struct and opening brace */
|
||||
|
||||
code_ptr = strstr(code_ptr, types_array[i]);
|
||||
if (code_ptr) {
|
||||
char *open_bracket_pos;
|
||||
code_ptr += strlen(types_array[i]);
|
||||
open_bracket_pos = strchr(code_ptr, '{');
|
||||
if (open_bracket_pos) {
|
||||
/* Make sure we don't have something like struct A a; */
|
||||
char *semi_colon_pos = strchr(code_ptr, ';');
|
||||
if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
|
||||
while (code_ptr < open_bracket_pos)
|
||||
*code_ptr++ = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
/* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
|
||||
char *code_ptr = Char(ccode);
|
||||
while (code_ptr) {
|
||||
code_ptr = strstr(code_ptr, "%constant");
|
||||
if (code_ptr) {
|
||||
char *directive_end_pos = strchr(code_ptr, ';');
|
||||
if (directive_end_pos) {
|
||||
while (code_ptr <= directive_end_pos)
|
||||
*code_ptr++ = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Node *newnode = NewHash();
|
||||
set_nodeType(newnode, "insert");
|
||||
Setfile(newnode, Getfile(n));
|
||||
Setline(newnode, Getline(n));
|
||||
String *code = NewStringEmpty();
|
||||
Wrapper_pretty_print(ccode, code);
|
||||
Setattr(newnode, "code", code);
|
||||
Delete(code);
|
||||
Delattr(n, "code");
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static void insertNodeAfter(Node *n, Node *c) {
|
||||
Node *g = parentNode(n);
|
||||
set_parentNode(c, g);
|
||||
Node *ns = nextSibling(n);
|
||||
if (Node *outer = Getattr(c, "nested:outer")) {
|
||||
while (ns && outer == Getattr(ns, "nested:outer")) {
|
||||
n = ns;
|
||||
ns = nextSibling(n);
|
||||
}
|
||||
}
|
||||
if (!ns) {
|
||||
set_lastChild(g, c);
|
||||
} else {
|
||||
set_nextSibling(c, ns);
|
||||
set_previousSibling(ns, c);
|
||||
}
|
||||
set_nextSibling(n, c);
|
||||
set_previousSibling(c, n);
|
||||
}
|
||||
|
||||
void Swig_nested_name_unnamed_c_structs(Node *n) {
|
||||
if (!classhash)
|
||||
classhash = Getattr(n, "classes");
|
||||
Node *c = firstChild(n);
|
||||
while (c) {
|
||||
Node *next = nextSibling(c);
|
||||
if (String *declName = Getattr(c, "nested:unnamed")) {
|
||||
if (Node *outer = Getattr(c, "nested:outer")) {
|
||||
// generate a name
|
||||
String *name = NewStringf("%s_%s", Getattr(outer, "name"), declName);
|
||||
Delattr(c, "nested:unnamed");
|
||||
// set the name to the class and symbol table
|
||||
Setattr(c, "tdname", name);
|
||||
Setattr(c, "name", name);
|
||||
Swig_symbol_setscope(Getattr(c, "symtab"));
|
||||
Swig_symbol_setscopename(name);
|
||||
// now that we have a name - gather base symbols
|
||||
if (List *publicBases = Getattr(c, "baselist")) {
|
||||
List *bases = Swig_make_inherit_list(name, publicBases, 0);
|
||||
Swig_inherit_base_symbols(bases);
|
||||
Delete(bases);
|
||||
}
|
||||
Setattr(classhash, name, c);
|
||||
Swig_symbol_popscope();
|
||||
// process declarations following this type (assign correct new type)
|
||||
SwigType *ty = Copy(name);
|
||||
Node *decl = nextSibling(c);
|
||||
List *declList = NewList();
|
||||
while (decl && Getattr(decl, "nested:unnamedtype") == c) {
|
||||
Setattr(decl, "type", ty);
|
||||
Append(declList, decl);
|
||||
Delattr(decl, "nested:unnamedtype");
|
||||
SetFlag(decl, "feature:immutable");
|
||||
add_symbols_c(decl);
|
||||
decl = nextSibling(decl);
|
||||
}
|
||||
Delete(ty);
|
||||
// Check for extensions
|
||||
/* // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing
|
||||
if (extendhash) {
|
||||
if (Node *am = Getattr(extendhash, name)) {
|
||||
// Merge the extension into the symbol table
|
||||
merge_extensions(c, am);
|
||||
append_previous_extension(c, am);
|
||||
Delattr(extendhash, clsname);
|
||||
}
|
||||
}*/
|
||||
Swig_symbol_setscope(Swig_symbol_global_scope());
|
||||
add_symbols_c(c);
|
||||
|
||||
Node *ins = create_insert(c);
|
||||
insertNodeAfter(c, ins);
|
||||
removeNode(c);
|
||||
insertNodeAfter(n, c);
|
||||
Delete(ins);
|
||||
Delattr(c, "nested:outer");
|
||||
} else {
|
||||
// global unnamed struct - ignore it
|
||||
c = next;
|
||||
continue;
|
||||
}
|
||||
} else if (cparse_cplusplusout) {
|
||||
if (Getattr(c, "nested:outer")) {
|
||||
Node *ins = create_insert(c, true);
|
||||
insertNodeAfter(c, ins);
|
||||
Delete(ins);
|
||||
Delattr(c, "nested:outer");
|
||||
}
|
||||
}
|
||||
// process children
|
||||
Swig_nested_name_unnamed_c_structs(c);
|
||||
c = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_outer_class_reference(Node *n) {
|
||||
for (Node *c = firstChild(n); c; c = nextSibling(c)) {
|
||||
if (GetFlag(c, "feature:flatnested")) {
|
||||
Delattr(c, "nested:outer");
|
||||
remove_outer_class_reference(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Swig_nested_process_classes(Node *n) {
|
||||
Node *c = firstChild(n);
|
||||
while (c) {
|
||||
Node *next = nextSibling(c);
|
||||
if (!Getattr(c, "templatetype")) {
|
||||
if (GetFlag(c, "nested") && GetFlag(c, "feature:flatnested")) {
|
||||
removeNode(c);
|
||||
if (!checkAttribute(c, "access", "public"))
|
||||
SetFlag(c, "feature:ignore");
|
||||
else
|
||||
insertNodeAfter(n, c);
|
||||
}
|
||||
Swig_nested_process_classes(c);
|
||||
}
|
||||
c = next;
|
||||
}
|
||||
remove_outer_class_reference(n);
|
||||
}
|
||||
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swigmod.h"
|
||||
#include "cparse.h"
|
||||
|
||||
static String *global_name = 0;
|
||||
static String *op_prefix = 0;
|
||||
|
|
@ -132,6 +133,10 @@ public:
|
|||
SWIG_config_file("octave.swg");
|
||||
SWIG_typemap_lang("octave");
|
||||
allow_overloading();
|
||||
|
||||
// Octave API is C++, so output must be C++ compatibile even when wrapping C code
|
||||
if (!cparse_cplusplus)
|
||||
Swig_cparse_cplusplusout(1);
|
||||
}
|
||||
|
||||
virtual int top(Node *n) {
|
||||
|
|
|
|||
|
|
@ -297,6 +297,16 @@ protected:
|
|||
/* Some language modules require additional wrappers for virtual methods not declared in sub-classes */
|
||||
virtual bool extraDirectorProtectedCPPMethodsRequired() const;
|
||||
|
||||
public:
|
||||
/* Does target language support nested classes? Default is 'false'. If 'false' is returned, then
|
||||
%rename("$ignore", %$isnested) statement will be issued at the top, and the nested classes
|
||||
will be ignored. Note that even if the target language does not support the notion of class
|
||||
nesting, the language module may nevertheless return true from this function, and use
|
||||
%feature "flatnested" to move nested classes to the global scope, instead of ignoring them.
|
||||
*/
|
||||
virtual bool nestedClassesSupported() const;
|
||||
|
||||
protected:
|
||||
/* Identifies if a protected members that are generated when the allprotected option is used.
|
||||
This does not include protected virtual methods as they are turned on with the dirprot option. */
|
||||
bool isNonVirtualProtectedAccess(Node *n) const;
|
||||
|
|
@ -410,5 +420,7 @@ int Swig_contract_mode_get();
|
|||
void Swig_browser(Node *n, int);
|
||||
void Swig_default_allocators(Node *n);
|
||||
void Swig_process_types(Node *n);
|
||||
void Swig_nested_process_classes(Node *n);
|
||||
void Swig_nested_name_unnamed_c_structs(Node *n);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -178,6 +178,20 @@ class TypePass:private Dispatcher {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
// A case when both outer and nested classes inherit from the same parent. Constructor may be found instead of the class itself.
|
||||
} else if (GetFlag(cls, "nested") && checkAttribute(bcls, "nodeType", "constructor")) {
|
||||
bcls = Getattr(bcls, "parentNode");
|
||||
if (Getattr(bcls, "typepass:visit")) {
|
||||
if (!Getattr(bcls, "feature:onlychildren")) {
|
||||
if (!ilist)
|
||||
ilist = alist = NewList();
|
||||
Append(ilist, bcls);
|
||||
} else {
|
||||
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname));
|
||||
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (Strcmp(nodeType(bcls), "classforward") != 0) {
|
||||
Swig_error(Getfile(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
|
||||
|
|
@ -462,6 +476,17 @@ class TypePass:private Dispatcher {
|
|||
if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
|
||||
SwigType_typedef(unnamed, tdname);
|
||||
}
|
||||
// name of the outer class should already be patched to contain it's outer classes names, but not to contain namespaces
|
||||
// namespace name (if present) is added after processing child nodes
|
||||
if (Getattr(n, "nested:outer") && name) {
|
||||
String *outerName = Getattr(Getattr(n, "nested:outer"), "name");
|
||||
name = NewStringf("%s::%s", outerName, name);
|
||||
Setattr(n, "name", name);
|
||||
if (tdname) {
|
||||
tdname = NewStringf("%s::%s", outerName, tdname);
|
||||
Setattr(n, "tdname", tdname);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsname && name) {
|
||||
nname = NewStringf("%s::%s", nsname, name);
|
||||
|
|
@ -479,7 +504,7 @@ class TypePass:private Dispatcher {
|
|||
SwigType_attach_symtab(Getattr(n, "symtab"));
|
||||
|
||||
/* Inherit type definitions into the class */
|
||||
if (name) {
|
||||
if (name && !(GetFlag(n, "nested") && GetFlag(n, "feature:flatnested") && !checkAttribute(n, "access", "public"))) {
|
||||
cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +678,7 @@ class TypePass:private Dispatcher {
|
|||
if (GetFlag(n, "conversion_operator")) {
|
||||
/* The call to the operator in the generated wrapper must be fully qualified in order to compile */
|
||||
SwigType *name = Getattr(n, "name");
|
||||
SwigType *qualifiedname = Swig_symbol_string_qualify(name,0);
|
||||
SwigType *qualifiedname = Swig_symbol_string_qualify(name, 0);
|
||||
Clear(name);
|
||||
Append(name, qualifiedname);
|
||||
Delete(qualifiedname);
|
||||
|
|
@ -1090,8 +1115,7 @@ class TypePass:private Dispatcher {
|
|||
* list of overloaded methods we have just added in as child nodes to the "using" node.
|
||||
* The node will still exist, it is just the symbol table linked list of overloaded methods
|
||||
* which is hacked. */
|
||||
if (Getattr(n, "sym:overloaded"))
|
||||
{
|
||||
if (Getattr(n, "sym:overloaded")) {
|
||||
int cnt = 0;
|
||||
#ifdef DEBUG_OVERLOADED
|
||||
Node *debugnode = n;
|
||||
|
|
@ -1154,7 +1178,7 @@ class TypePass:private Dispatcher {
|
|||
#ifdef DEBUG_OVERLOADED
|
||||
show_overloaded(debugnode);
|
||||
#endif
|
||||
clean_overloaded(n); // Needed?
|
||||
clean_overloaded(n); // Needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1258,3 +1282,4 @@ void Swig_process_types(Node *n) {
|
|||
return;
|
||||
TypePass::pass(n);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swig.h"
|
||||
#include "cparse.h"
|
||||
|
||||
extern int cparse_cplusplus;
|
||||
static const char *cresult_variable_name = "result";
|
||||
|
||||
static Parm *nonvoid_parms(Parm *p) {
|
||||
|
|
@ -775,7 +775,25 @@ String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, Stri
|
|||
if (SwigType_type(type) != T_ARRAY) {
|
||||
if (!Strstr(type, "enum $unnamed")) {
|
||||
String *dref = Swig_wrapped_var_deref(type, pname1, varcref);
|
||||
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
|
||||
int extra_cast = 0;
|
||||
if (cparse_cplusplusout) {
|
||||
/* Required for C nested structs compiled as C++ as a duplicate of the nested struct is put into the global namespace.
|
||||
* We could improve this by adding the extra casts just for nested structs rather than all structs. */
|
||||
String *base = SwigType_base(type);
|
||||
extra_cast = SwigType_isclass(base);
|
||||
Delete(base);
|
||||
}
|
||||
if (extra_cast) {
|
||||
String *lstr;
|
||||
SwigType *ptype = Copy(type);
|
||||
SwigType_add_pointer(ptype);
|
||||
lstr = SwigType_lstr(ptype, 0);
|
||||
Printf(func, "if (%s) *(%s)&%s%s = %s", pname0, lstr, self, name, dref);
|
||||
Delete(lstr);
|
||||
Delete(ptype);
|
||||
} else {
|
||||
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
|
||||
}
|
||||
Delete(dref);
|
||||
} else {
|
||||
Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1);
|
||||
|
|
|
|||
|
|
@ -1147,6 +1147,55 @@ String *Swig_string_strip(String *s) {
|
|||
return ns;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_offset_string()
|
||||
*
|
||||
* Insert number tabs before each new line in s
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_offset_string(String *s, int number) {
|
||||
char *res;
|
||||
char *p;
|
||||
char *end;
|
||||
/* count a number of lines in s */
|
||||
int lines = 1;
|
||||
int len = Len(s);
|
||||
char *start = strchr(Char(s), '\n');
|
||||
while (start) {
|
||||
++lines;
|
||||
start = strchr(start + 1, '\n');
|
||||
}
|
||||
/* do not count pending new line */
|
||||
if ((Char(s))[len-1] == '\n')
|
||||
--lines;
|
||||
/* allocate a temporary storage for a padded string */
|
||||
res = (char*)malloc(len + lines * number * 2 + 1);
|
||||
res[len + lines * number * 2] = 0;
|
||||
|
||||
/* copy lines to res, prepending tabs to each line */
|
||||
p = res; /* output pointer */
|
||||
start = Char(s); /* start of a current line */
|
||||
end = strchr(start, '\n'); /* end of a current line */
|
||||
while (end) {
|
||||
memset(p, ' ', number*2);
|
||||
p += number*2;
|
||||
memcpy(p, start, end - start + 1);
|
||||
p += end - start + 1;
|
||||
start = end + 1;
|
||||
end = strchr(start, '\n');
|
||||
}
|
||||
/* process the last line */
|
||||
if (*start) {
|
||||
memset(p, ' ', number*2);
|
||||
p += number*2;
|
||||
strcpy(p, start);
|
||||
}
|
||||
/* replace 's' contents with 'res' */
|
||||
Clear(s);
|
||||
Append(s, res);
|
||||
free(res);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_PCRE
|
||||
#include <pcre.h>
|
||||
|
|
|
|||
|
|
@ -774,7 +774,7 @@ void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *d
|
|||
* concatenating the feature name plus ':' plus the attribute name.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs) {
|
||||
void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs) {
|
||||
Hash *n;
|
||||
Hash *fhash;
|
||||
|
||||
|
|
@ -1648,6 +1648,80 @@ void Swig_name_inherit(String *base, String *derived) {
|
|||
Swig_name_object_inherit(Swig_cparse_features(), base, derived);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_inherit_base_symbols()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_inherit_base_symbols(List *bases) {
|
||||
if (bases) {
|
||||
Iterator s;
|
||||
for (s = First(bases); s.item; s = Next(s)) {
|
||||
Symtab *st = Getattr(s.item, "symtab");
|
||||
if (st) {
|
||||
Setfile(st, Getfile(s.item));
|
||||
Setline(st, Getline(s.item));
|
||||
Swig_symbol_inherit(st);
|
||||
}
|
||||
}
|
||||
Delete(bases);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_make_inherit_list()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix) {
|
||||
int i, ilen;
|
||||
String *derived;
|
||||
List *bases = NewList();
|
||||
|
||||
if (Namespaceprefix)
|
||||
derived = NewStringf("%s::%s", Namespaceprefix, clsname);
|
||||
else
|
||||
derived = NewString(clsname);
|
||||
|
||||
ilen = Len(names);
|
||||
for (i = 0; i < ilen; i++) {
|
||||
String *base;
|
||||
String *n = Getitem(names, i);
|
||||
/* Try to figure out where this symbol is */
|
||||
Node *s = Swig_symbol_clookup(n, 0);
|
||||
if (s) {
|
||||
while (s && (Strcmp(nodeType(s), "class") != 0)) {
|
||||
/* Not a class. Could be a typedef though. */
|
||||
String *storage = Getattr(s, "storage");
|
||||
if (storage && (Strcmp(storage, "typedef") == 0)) {
|
||||
String *nn = Getattr(s, "type");
|
||||
s = Swig_symbol_clookup(nn, Getattr(s, "sym:symtab"));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (s && ((Strcmp(nodeType(s), "class") == 0) || (Strcmp(nodeType(s), "template") == 0))) {
|
||||
String *q = Swig_symbol_qualified(s);
|
||||
Append(bases, s);
|
||||
if (q) {
|
||||
base = NewStringf("%s::%s", q, Getattr(s, "name"));
|
||||
Delete(q);
|
||||
} else {
|
||||
base = NewString(Getattr(s, "name"));
|
||||
}
|
||||
} else {
|
||||
base = NewString(n);
|
||||
}
|
||||
} else {
|
||||
base = NewString(n);
|
||||
}
|
||||
if (base) {
|
||||
Swig_name_inherit(base, derived);
|
||||
Delete(base);
|
||||
}
|
||||
}
|
||||
return bases;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* void Swig_name_str()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1546,6 +1546,114 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_get_raw_text_balanced()
|
||||
*
|
||||
* Returns raw text between 2 braces, does not change scanner state in any way
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
|
||||
String *result = 0;
|
||||
char c;
|
||||
int old_line = s->line;
|
||||
String *old_text = Copy(s->text);
|
||||
int position = Tell(s->str);
|
||||
|
||||
int num_levels = 1;
|
||||
int state = 0;
|
||||
char temp[2] = { 0, 0 };
|
||||
temp[0] = (char) startchar;
|
||||
Clear(s->text);
|
||||
Setfile(s->text, Getfile(s->str));
|
||||
Setline(s->text, s->line);
|
||||
Append(s->text, temp);
|
||||
while (num_levels > 0) {
|
||||
if ((c = nextchar(s)) == 0) {
|
||||
Clear(s->text);
|
||||
Append(s->text, old_text);
|
||||
Delete(old_text);
|
||||
s->line = old_line;
|
||||
return 0;
|
||||
}
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (c == startchar)
|
||||
num_levels++;
|
||||
else if (c == endchar)
|
||||
num_levels--;
|
||||
else if (c == '/')
|
||||
state = 10;
|
||||
else if (c == '\"')
|
||||
state = 20;
|
||||
else if (c == '\'')
|
||||
state = 30;
|
||||
break;
|
||||
case 10:
|
||||
if (c == '/')
|
||||
state = 11;
|
||||
else if (c == '*')
|
||||
state = 12;
|
||||
else if (c == startchar) {
|
||||
state = 0;
|
||||
num_levels++;
|
||||
}
|
||||
else
|
||||
state = 0;
|
||||
break;
|
||||
case 11:
|
||||
if (c == '\n')
|
||||
state = 0;
|
||||
else
|
||||
state = 11;
|
||||
break;
|
||||
case 12: /* first character inside C comment */
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
else
|
||||
state = 13;
|
||||
break;
|
||||
case 13:
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
break;
|
||||
case 14: /* possible end of C comment */
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
else if (c == '/')
|
||||
state = 0;
|
||||
else
|
||||
state = 13;
|
||||
break;
|
||||
case 20:
|
||||
if (c == '\"')
|
||||
state = 0;
|
||||
else if (c == '\\')
|
||||
state = 21;
|
||||
break;
|
||||
case 21:
|
||||
state = 20;
|
||||
break;
|
||||
case 30:
|
||||
if (c == '\'')
|
||||
state = 0;
|
||||
else if (c == '\\')
|
||||
state = 31;
|
||||
break;
|
||||
case 31:
|
||||
state = 30;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Seek(s->str, position, SEEK_SET);
|
||||
result = Copy(s->text);
|
||||
Clear(s->text);
|
||||
Append(s->text, old_text);
|
||||
Delete(old_text);
|
||||
s->line = old_line;
|
||||
return result;
|
||||
}
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_isoperator()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -286,6 +286,8 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
extern Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl);
|
||||
extern void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *namewrn, ParmList *declaratorparms);
|
||||
extern void Swig_name_inherit(String *base, String *derived);
|
||||
extern List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix);
|
||||
extern void Swig_inherit_base_symbols(List *bases);
|
||||
extern int Swig_need_protected(Node *n);
|
||||
extern int Swig_need_name_warning(Node *n);
|
||||
extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass);
|
||||
|
|
@ -302,7 +304,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
extern DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl);
|
||||
extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived);
|
||||
extern void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *n);
|
||||
extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs);
|
||||
extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs);
|
||||
|
||||
/* --- Misc --- */
|
||||
extern char *Swig_copy_string(const char *c);
|
||||
|
|
@ -330,6 +332,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
|
|||
extern String *Swig_string_lower(String *s);
|
||||
extern String *Swig_string_upper(String *s);
|
||||
extern String *Swig_string_title(String *s);
|
||||
extern void Swig_offset_string(String *s, int number);
|
||||
extern String *Swig_pcre_version(void);
|
||||
extern void Swig_init(void);
|
||||
extern int Swig_value_wrapper_mode(int mode);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ extern int Scanner_token(Scanner *);
|
|||
extern String *Scanner_text(Scanner *);
|
||||
extern void Scanner_skip_line(Scanner *);
|
||||
extern int Scanner_skip_balanced(Scanner *, int startchar, int endchar);
|
||||
extern String *Scanner_get_raw_text_balanced(Scanner *, int startchar, int endchar);
|
||||
extern void Scanner_set_location(Scanner *, String *file, int line);
|
||||
extern String *Scanner_file(Scanner *);
|
||||
extern int Scanner_line(Scanner *);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ extern void appendChild(Node *node, Node *child);
|
|||
extern void prependChild(Node *node, Node *child);
|
||||
extern void removeNode(Node *node);
|
||||
extern Node *copyNode(Node *node);
|
||||
extern void appendSibling(Node *node, Node *child);
|
||||
|
||||
/* Node restoration/restore functions */
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,24 @@ void prependChild(Node *node, Node *chd) {
|
|||
}
|
||||
}
|
||||
|
||||
void appendSibling(Node *node, Node *chd) {
|
||||
Node *parent;
|
||||
Node *lc = node;
|
||||
while (nextSibling(lc))
|
||||
lc = nextSibling(lc);
|
||||
set_nextSibling(lc, chd);
|
||||
set_previousSibling(chd, lc);
|
||||
parent = parentNode(node);
|
||||
if (parent) {
|
||||
while (chd) {
|
||||
lc = chd;
|
||||
set_parentNode(chd, parent);
|
||||
chd = nextSibling(chd);
|
||||
}
|
||||
set_lastChild(parent, lc);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* removeNode()
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue