#error behaviour is back like it was in 1.3.27, so removed entry that turned default #error behaviour into #warning. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8567 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2000 lines
63 KiB
Text
2000 lines
63 KiB
Text
Version 1.3.28 (unreleased).
|
|
===========================
|
|
|
|
01/24/2006: mgossage
|
|
[Lua]
|
|
- Removed the type swig_lua_command_info & replace with luaL_reg
|
|
(which then broke the code), fixed this
|
|
- added an additional cast in the typemaps for enum's
|
|
due to the issue that VC.Net will not allow casting of
|
|
a double to an enum directly. Therefore cast to int then to enum
|
|
(thenks to Jason Rego for this observation)
|
|
|
|
01/16/2006: mmatus (Change disabled)
|
|
Add initial support for regexp via the external library
|
|
RxSpencer. SWIG doesn't require this library to compile
|
|
and/or run. But if you specify --with-rxspencer, and the
|
|
library is found during installation, then swig will use
|
|
it in three places:
|
|
|
|
- In %renames rules, via the new rxsmatch rules, for example:
|
|
|
|
%rename("%(lowercase)",rxsmatch$name="GSL_.*") "";
|
|
%rename("%(lowercase)",rxsmatch$nodeType="enum GSL_.*") "";
|
|
|
|
rxsmatch is similar to the match rule, it just uses
|
|
the RxSpencer regexp library to decide if there is a
|
|
match with the provided regexp. As with the match
|
|
rule, you can also use the negate rule notrxsmatch.
|
|
|
|
- In the %rename target name via the rxstarget option, for example:
|
|
|
|
%rename("%(lowercase)",rxstarget=1) "GSL_.*";
|
|
|
|
where the target name "GSL.*" is now understood as a
|
|
regexp to be matched.
|
|
|
|
- In the new encoder "rxspencer", which looks like:
|
|
|
|
%(rxspencer:[regexp][replace])s
|
|
|
|
where "regexp" is the regular expression and "replace"
|
|
is a string used as a replacement, where the @0,@1,...,@9
|
|
pseudo arguments are used to represent the
|
|
corresponding matching items in the reg expression.
|
|
|
|
For example:
|
|
|
|
%(rxspencer:[GSL.*][@0])s <- Hello ->
|
|
%(rxspencer:[GSL.*][@0])s <- GSLHello -> GSLHello
|
|
%(rxspencer:[GSL(.*)][@1])s <- GSLHello -> Hello
|
|
%(rxspencer:[GSL(.*)][gsl@1])s <- GSLHello -> gslHello
|
|
|
|
Another example could be:
|
|
|
|
%rename("%(lowercase)s",sourcefmt="%(rxspencer:[GSL_(.*)][@1])s",%$isfunction) "";
|
|
|
|
which take out the prefix "GSL_" and returns all the
|
|
function names in lower cases, as following:
|
|
|
|
void GSL_Hello(); -> hello();
|
|
void GSL_Hi(); -> hi();
|
|
const int GSL_MAX; -> GSL_MAX; // no change, is not a function
|
|
|
|
We use the RxSpencer as an initial test bed to
|
|
implemention while we decide which library will be
|
|
finally added to swig.
|
|
|
|
You can obtain the RxSpencer library from
|
|
|
|
http://arglist.com/regex (Unix)
|
|
|
|
or
|
|
|
|
http://gnuwin32.sourceforge.net/packages.html (Windows)
|
|
|
|
Once installed, use "man rxspencer" to get more info
|
|
about the regexp format, or just google rxspencer.
|
|
|
|
Since now you can enable the rxsmatch rules (see above),
|
|
the simple or '|' support for the match rules
|
|
(01/12/2006: mmatus) is disabled. Still, if you have
|
|
problems with the rxspencer library, you can re-enable
|
|
the simple 'match or' support using
|
|
-DSWIG_USE_SIMPLE_MATCHOR.
|
|
|
|
|
|
01/16/2006: mmatus
|
|
Change the %rename predicates to use the prefix '%$', as in:
|
|
|
|
%rename("%(utitle)s",%$isfunction,%$ismember) "";
|
|
|
|
to avoid clashings with other swig macros/directives.
|
|
|
|
01/14/2006: cfisavage
|
|
[Ruby]
|
|
Added support for Ruby bang! methods via a new %bang feature.
|
|
Bang methods end in exclamation points and indicate that the
|
|
object being processed will be modified in-place as
|
|
opposed to being copied.
|
|
|
|
01/12/2006: cfisavage
|
|
[Ruby]
|
|
Updated the Ruby module to automatically convert
|
|
method names to lower_case_with_underscores using the
|
|
new %rename functionality.
|
|
|
|
01/12/2006: mmatus
|
|
- Add aliases for 'case' encoders used with %rename/%namewarn
|
|
|
|
%(uppercase)s hello_world -> HELLO_WORLD
|
|
%(lowercase)s HelloWorld -> helloworld
|
|
%(camelcase)s hello_world -> HelloWorld
|
|
%(undercase)s HelloWorld -> hello_world
|
|
|
|
|
|
01/12/2006: mmatus
|
|
- Add the -dump_parse_module and -dump_parse_top options,
|
|
which are similar to -dump_module and -dump_top, but they
|
|
dump the node trees just after parsing, showing only the
|
|
attributes visible at the parsing stage, and not the added
|
|
later in typemap.cxx, allocate.cxx, lang.cxx or elsewhere.
|
|
|
|
Besides debugging porpuses, these options are very useful
|
|
if you plan to use %rename in an "advance way", since it
|
|
shows only and all the node's attributes you can use
|
|
inside the match rules.
|
|
|
|
|
|
01/12/2006: mmatus
|
|
- Add predicates to %rename, so, you don't need to
|
|
remember, for example, how to match a member function.
|
|
|
|
Now it is easy, for example to use the 'utitle' encoder
|
|
in all the member methods, you type:
|
|
|
|
%rename("%(utitle)s",%isfunction,%ismember) "";
|
|
|
|
or to ignore all the enumitems in a given class:
|
|
|
|
%rename("$ignore", %isenumitem, %classname="MyClass") "";
|
|
|
|
Available predicates are (see swig.swg):
|
|
|
|
%isenum
|
|
%isenumitem
|
|
%isaccess
|
|
%isclass
|
|
%isextend
|
|
%isextend
|
|
%isconstructor
|
|
%isdestructor
|
|
%isnamespace
|
|
%istemplate
|
|
%isconstant
|
|
|
|
%isunion
|
|
%isfunction
|
|
%isvariable
|
|
%isimmutable
|
|
|
|
%isstatic
|
|
%isfriend
|
|
%istypedef
|
|
%isvirtual
|
|
%isexplicit
|
|
%isextern
|
|
|
|
%ismember
|
|
%isglobal
|
|
%innamespace
|
|
|
|
%ispublic
|
|
%isprotected
|
|
%isprivate
|
|
|
|
%classname
|
|
|
|
These predicates correspond to specific 'match'
|
|
declarations, which sometimes are not as evident as the
|
|
predicates names.
|
|
|
|
|
|
- Add the or '|' operation in %rename match, for
|
|
example to capitalize all the constants (%constant or
|
|
const cdecl):
|
|
|
|
%rename("%(upper)s",match="cdecl|constant",%isimmutable) "";
|
|
|
|
|
|
|
|
01/12/2006: mgossage
|
|
- Partial fixed of errors under C89, bug #1356574
|
|
(converted C++ style comments to C style)
|
|
- Added patches from neomantra@users.sf.net #1379988 and #1388343
|
|
missing a 'return' statement for error conditions
|
|
also updated the %init block bug #1356586
|
|
|
|
01/10/2006: mmatus
|
|
- Add the 'utitle' encoder, as an example of how to add
|
|
your own encoder. I added the encoder method in misc.c
|
|
but developers can add others, the same way, inside any
|
|
target language.
|
|
|
|
Well, 'utitle' is the reverse of 'ctitle', ie:
|
|
|
|
%rename("%(ctitle)s") camel_case; -> CamelCase;
|
|
%rename("%(utitle)s") CamelCase; -> camel_case;
|
|
|
|
|
|
01/10/2006: cfisavage
|
|
[Ruby]
|
|
Updated Ruby Exception handling. Classes that are specified in throws clauses,
|
|
or are marked as %exceptionclass, are now inherited from rb_eRuntimeError.
|
|
This allows instances of these classes to be returned to Ruby as exceptions.
|
|
Thus if a C++ method throws an instance of MyException, the calling Ruby
|
|
method will get back a MyException object. To see an example,
|
|
look at ruby/examples/exception_class.
|
|
|
|
01/10/2006: mmatus
|
|
|
|
- Add the %catches directive, which complements the %exception
|
|
directive in a more automatic way. For example, if you have
|
|
|
|
int foo() throw(E1);
|
|
|
|
swig generates the proper try/catch code to dispatch E1.
|
|
|
|
But if you have:
|
|
|
|
|
|
int barfoo(int i) {
|
|
if (i == 1) {
|
|
throw E1();
|
|
} else {
|
|
throw E2();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ie, where there is no explicit exception specification in the decl, you
|
|
end up doing:
|
|
|
|
%exception barfoo {
|
|
try {
|
|
$action
|
|
} catch(E1) { ... }
|
|
} catch(E2) { ... }
|
|
}
|
|
|
|
which is very tedious. Well, the %catches directive defines
|
|
the list of exceptions to catch, and from swig:
|
|
|
|
%catches(E1,E2) barfoo(int i);
|
|
int barfoo(int i);
|
|
|
|
is equivalent to
|
|
|
|
int barfoo(int i) throw(E1,E2);
|
|
|
|
Note, however, that the %catches list doesn't have to
|
|
correspond to the C++ exception specification. For example, if you
|
|
have:
|
|
|
|
struct E {};
|
|
struct E1 : E {};
|
|
struct E2 : E {};
|
|
|
|
int barfoo(int i) throw(E1,E2);
|
|
|
|
you can define
|
|
|
|
%catches(E) barfoo(int i);
|
|
|
|
and swig will generate an action code equivalent to
|
|
|
|
try {
|
|
$action
|
|
} catch(E &_e) {
|
|
<raise _e>;
|
|
}
|
|
|
|
Of course, you still have to satisfy the C++ restrictions,
|
|
and the catches list must be compatible (not the same)
|
|
as the original list of types in the exception specification.
|
|
|
|
Also, you can now specify that you want to catch the
|
|
unknown exception '...', for example:
|
|
|
|
%catches(E1,E2,...) barfoo(int);
|
|
|
|
In any case, the %catches directive will emit the
|
|
code to convert into the target language error/exception
|
|
using the 'throws' typemap.
|
|
|
|
For the '...' case to work, you need to
|
|
write the proper typemap in your target language. In the
|
|
UTL, this looks like:
|
|
|
|
%typemap(throws) (...) {
|
|
SWIG_exception(SWIG_RuntimeError,"unknown exception");
|
|
}
|
|
|
|
|
|
01/05/2006: wsfulton
|
|
[Java] Fix unsigned long long and const unsigned long long & typemaps
|
|
- Bug #1398394 with patch from Dries Decock
|
|
|
|
01/06/2006: mmatus
|
|
Add 'named' warning codes, now in addition to:
|
|
|
|
%warnfilter(813);
|
|
|
|
you can use
|
|
|
|
%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE);
|
|
|
|
just use the same code name found in Source/Include/swigwarn.h
|
|
plus the 'SWIG' prefix.
|
|
|
|
If a developer adds a new warning code, the Lib/swigwarn.swg file
|
|
will be generated when running the top level make.
|
|
|
|
01/05/2006: cfisavage
|
|
[Ruby]
|
|
Reimplemented object tracking for Ruby. The new implementation works
|
|
by expanding the swig_class structure for Ruby by adding a trackObjects
|
|
field. This field can be set/unset via %trackobjects as explained
|
|
in the Ruby documentation. The new implementation is more robust
|
|
and takes less code to implement.
|
|
|
|
01/05/2006: wsfulton
|
|
Fix for %extend and static const integral types, eg:
|
|
|
|
class Foo {
|
|
public:
|
|
%extend {
|
|
static const int bar = 42;
|
|
}
|
|
};
|
|
|
|
12/30/2005: mmatus
|
|
|
|
- Add info for old and new debug options:
|
|
|
|
-dump_top - Print information of the entire node tree, including system nodes
|
|
-dump_module - Print information of the module node tree, avoiding system nodes
|
|
-dump_classes - Print information about the classes found in the interface
|
|
-dump_typedef - Print information about the types and typedefs found in the interface
|
|
-dump_tags - Print information about the tags found in the interface
|
|
-debug_typemap - Print information for debugging typemaps
|
|
-debug_template - Print information for debugging templates
|
|
|
|
- Add the fakeversion. If you have a project that uses
|
|
configure/setup.py, or another automatic building system
|
|
and requires a specific swig version, let say 1.3.22
|
|
you can use:
|
|
|
|
SWIG_FEATURES="-fakeversion 1.3.22"
|
|
|
|
or
|
|
|
|
swig -fakeversion 1.3.22
|
|
|
|
and then swig -version will report 1.3.22 instead of the
|
|
current version.
|
|
|
|
Typical use would be
|
|
|
|
SWIG_FEATURES="-fakeversion 1.3.22" ./configure
|
|
|
|
12/30/2005: mmatus
|
|
|
|
- Add option/format support to %rename and %namewarn.
|
|
Now %namewarn can force renaming, for example:
|
|
|
|
%namewarn("314: import is a keyword",rename="_%s") "import";
|
|
|
|
and rename can also support format forms:
|
|
|
|
%rename("swig_%s") import;
|
|
|
|
Now, since the format is processed via swig Printf, you
|
|
can use encoders as follows:
|
|
|
|
%rename("%(title)s") import; -> Import
|
|
%rename("%(upper)s") import; -> IMPORT
|
|
%rename("%(lower)s") Import; -> import
|
|
%rename("%(ctitle)s") camel_case; -> CamelCase
|
|
|
|
This will allow us to add more encoders, as the
|
|
expected one for regular expressions.
|
|
|
|
- Add the above 'ctitle' encoder, which does the camel case:
|
|
|
|
camel_case -> CamelCase
|
|
|
|
- Also, while we get the regexp support, add the 'command' encoder,
|
|
you can use it as follows
|
|
|
|
%rename("%(command:sed -e 's/\([a-z]\)/\U\\1/' <<< )s") import;
|
|
|
|
then swig will popen the command
|
|
|
|
"sed -e 's/\([a-z]\)/\U\\1/' <<< import"
|
|
|
|
see below for anonymous renames for better examples.
|
|
|
|
- The rename directive now also allows:
|
|
|
|
- simple match: only apply the rename if a type match
|
|
happen, for example
|
|
|
|
%rename(%(title)s,match="enumitem") hello;
|
|
|
|
enum Hello {
|
|
hi, hello -> hi, Hello
|
|
};
|
|
int hello() -> hello;
|
|
|
|
- extended match: only apply the rename if the 'extended attribute' match
|
|
occurred, for example:
|
|
|
|
// same as simple match
|
|
%rename(%(title)s,match$nodeType="enumitem") hello;
|
|
|
|
enum Hello {
|
|
hi, hello -> hi, Hello
|
|
};
|
|
|
|
Note that the symbol '$' is used to define the attribute name in
|
|
a 'recursive' way, for example:
|
|
|
|
// match only hello in 'enum Hello'
|
|
%rename(%(title)s,match$parentNode$type="enum Hello") hello;
|
|
|
|
enum Hello {
|
|
hi, hello -> hi, Hello // match
|
|
};
|
|
|
|
enum Hi {
|
|
hi, hello -> hi, hello // no match
|
|
};
|
|
|
|
here, for Hello::hi, the "parentNode" is "Hello", and its "type"
|
|
is "enum Hello".
|
|
|
|
|
|
- Anonymous renames: you can use 'anonymous' rename directives, for example:
|
|
|
|
// rename all the enum items in Hello
|
|
%rename(%(title)s,match$parentNode$type="enum Hello") "";
|
|
|
|
enum Hello {
|
|
hi, hello -> Hi, Hello // match both
|
|
};
|
|
|
|
enum Hi {
|
|
hi, hello -> hi, hello // no match
|
|
};
|
|
|
|
// rename all the enum items
|
|
%rename(%(title)s,match$nodeType="enumitem") "";
|
|
|
|
// rename all the items in given command (sloooow, but...)
|
|
%rename(%(command:<my external cmd>)s) "";
|
|
|
|
|
|
Anonymous renames with commands can be very powerful, since you
|
|
can 'outsource' all the renaming mechanism (or part of it) to an
|
|
external program:
|
|
|
|
// Uppercase all (and only) the names that start with 'i'
|
|
%rename("%(command:awk '/^i/{print toupper($1)}' <<<)s") "";
|
|
|
|
int imported() -> IMPORTED;
|
|
int hello() -> hello
|
|
|
|
Note that if the 'command' encoder returns an empty string, swig
|
|
understands that no rename is necessary.
|
|
|
|
Also note that %rename 'passes' the matched name. For example, in
|
|
this case
|
|
|
|
namespace ns1 {
|
|
int foo();
|
|
}
|
|
|
|
namespace ns2 {
|
|
int bar();
|
|
}
|
|
|
|
the external program only receives "foo" and "bar". If needed,
|
|
however, you can request the 'fullname'
|
|
|
|
%rename("%(command:awk 'awk '/ns1::/{l=split($1,a,"::"); print toupper(a[l])}'' <<<)s",fullname=1) "";
|
|
|
|
ns1::foo -> FOO
|
|
ns2::bar -> bar
|
|
|
|
- Mixing encoders and matching: of course, you can do mix commands
|
|
and match fields, for example:
|
|
|
|
%rename("%(<my encoder for fncs>)",match="cdecl") "";
|
|
%rename("%(<my encoder for enums>)",match="enumitem") "";
|
|
%rename("%(<my encoder for enums inside a class>)",match="enumitem",
|
|
match$parentNode$parentNode$nodeType="class") "";
|
|
|
|
Use "swig -dump_parse_module" to see the attribute names you can use to
|
|
match a specific case.
|
|
|
|
- 'sourcefmt' and 'targetfmt': sometimes you need to
|
|
process the 'source' name before comparing, for example
|
|
|
|
%namewarn("314: empty is a keyword",sourcefmt="%(lower)s") "empty";
|
|
|
|
then if you have
|
|
|
|
int Empty(); // "Empty" is the source
|
|
|
|
you will get the keyword warning since 'Empty' will be
|
|
lower cased, via the sourcefmt="%(lower)s" option,
|
|
before been compared to the 'target' "empty".
|
|
|
|
There is an additional 'targetfmt' option to process the
|
|
'target' before comparing.
|
|
|
|
- complementing 'match': you can use 'notmatch', for example
|
|
|
|
%namewarn("314: empty is a keyword",sourcefmt="%(lower)s",notmatch="namespace") "empty";
|
|
|
|
here, the name warning will be applied to all the symbols except namespaces.
|
|
|
|
|
|
12/30/2005: mmatus
|
|
|
|
- Add initial support for gcj and Java -> <target language> mechanism.
|
|
|
|
See examples in:
|
|
|
|
Examples/python/java
|
|
Examples/ruby/java
|
|
Examples/tcl/java
|
|
|
|
to see how to use gcj+swig to export java classes into
|
|
python/ruby/tcl.
|
|
|
|
The idea is to put all the common code for gcj inside
|
|
|
|
Lib/gcj
|
|
|
|
and localize specific types such as jstring, as can be found
|
|
in
|
|
|
|
Lib/python/jstring.i
|
|
Lib/ruby/jstring.i
|
|
Lib/tcl/jstring.i
|
|
|
|
Using the UTL, this is very easy, and the perl version for
|
|
jstring.i will be next.
|
|
|
|
|
|
12/29/2005: mmatus
|
|
- Add the copyctor feature/directive/option to enable the automatic
|
|
generation of copy constructors. Use as in:
|
|
|
|
%copyctor A;
|
|
|
|
struct A {
|
|
|
|
};
|
|
|
|
then this will work
|
|
|
|
a1 = A();
|
|
a2 = A(a1);
|
|
|
|
Also, since it is a feature, if you just type
|
|
|
|
%copyctor;
|
|
|
|
that will enable the automatic generation for all the
|
|
classes. It is also equivalent to
|
|
|
|
swig -copyctor -c++ ...
|
|
|
|
Notes:
|
|
|
|
1.- The feature only works in C++ mode.
|
|
|
|
2.- The automatic creation of the copy constructor will
|
|
usually produce overloading. Hence, if the target
|
|
language doesn't support overloading, a special name
|
|
will be used (A_copy).
|
|
|
|
3.- For the overloading reasons above, it is probably not
|
|
a good idea to use the flag when, for example, you are
|
|
using keywords in Python.
|
|
|
|
4.- The copyctor automatic mechanism follows more or less
|
|
the same rules as the default constructor mechanism,
|
|
i.e., a copy constructor will not be added if the
|
|
class is abstract or if there is a pertinent non-public
|
|
copy ctor in the class or its hierarchy.
|
|
|
|
Hence, it might be necessary for you to complete the
|
|
class declaration with the proper non-public copy ctor
|
|
to avoid a wrong constructor addition.
|
|
|
|
- Fix features/rename for templates ctor/dtor and other
|
|
things around while adding the copyctor mechanism.
|
|
|
|
|
|
12/27/2005: mmatus
|
|
- Add the 'match' option to typemaps. Assume you have:
|
|
|
|
%typemap(in) SWIGTYPE * (int res) {..}
|
|
%typemap(freearg) SWIGTYPE * { if (res$argnum) ...}
|
|
|
|
then if you do
|
|
|
|
%typemap(in) A * {...}
|
|
|
|
swig will 'overload the 'in' typemap, but the 'freearg'
|
|
typemap will be also applied, even when this is wrong. The old
|
|
solutions is to write:
|
|
|
|
%typemap(in) A * {...}
|
|
%typemap(freeag) A * "";
|
|
|
|
overload 'freearg' with an empty definition.
|
|
|
|
The problem is, however, there is no way to know you need
|
|
to do that until you start getting broken C++ code, or
|
|
worse, broken runtime code.
|
|
|
|
The same applies to the infamous 'typecheck' typemap,
|
|
which always confuses people, since the first thing you do
|
|
is to just write the 'in' typemap.
|
|
|
|
The 'match' option solves the problem, and if instead you write:
|
|
|
|
%typemap(in) SWIGTYPE * (int res) {..}
|
|
%typemap(freearg,match="in") SWIGTYPE * { if (res$argnum) ...}
|
|
%typemap(typecheck,match="in",precedence...) SWIGTYPE * {...}
|
|
|
|
it will tell swig to apply the 'freearg/typecheck'
|
|
typemaps only if they 'match' the type of the 'in'
|
|
typemap. The same can be done with other typemaps as:
|
|
|
|
%typemap(directorout) SWIGTYPE * {...}
|
|
%typemap(directorfree,match="directorout") SWIGTYPE * {...}
|
|
|
|
|
|
12/27/2005: mmatus
|
|
- Add the 'naturalvar' option/mode/feature to treat member
|
|
variables in a more natural way, ie, similar to the global
|
|
variable behavior.
|
|
|
|
You can use it in a global way via the command line
|
|
|
|
swig -naturalvar ...
|
|
|
|
or the module mode option
|
|
|
|
%module(naturalvar=1)
|
|
|
|
both forms make swig treat all the member variables in the
|
|
same way it treats global variables.
|
|
|
|
Also, you can use it in a case by case approach for
|
|
specific member variables using the directive form:
|
|
|
|
%naturalvar Bar::s;
|
|
|
|
Then, in the following case for example:
|
|
|
|
std::string s;
|
|
struct Bar {
|
|
std::string s;
|
|
};
|
|
|
|
you can do:
|
|
|
|
b = Bar()
|
|
b.s ="hello"
|
|
cvar.s = "hello"
|
|
|
|
if (b.s != cvar.s):
|
|
raise RuntimeError
|
|
|
|
|
|
This is valid for all the languages, and the
|
|
implementation is based on forcing the use of the
|
|
const SWIGTYPE& (C++)/SWIGTYPE (C) typemaps for the
|
|
get/set methods instead of the SWIGTYPE * typemaps.
|
|
Hence, for 'naturalvar' to work, each target language
|
|
must implement 'typemap(in/out) const Type&' properly.
|
|
|
|
The 'naturalvar' option replaces or makes workarounds such as:
|
|
|
|
%apply const std::string & { std::string *}
|
|
|
|
unnecessary.
|
|
|
|
Note1: If your interface has other kinds of workarounds to
|
|
deal with the old 'unnatural' way to deal with member
|
|
variables (returning/expecting pointers), the
|
|
'naturalvar' option could break them.
|
|
|
|
Note2: the option has no effect on unnamed types, such
|
|
as unnamed nested unions.
|
|
|
|
|
|
12/27/2005: mmatus
|
|
- Add more 'expressive' result states for the typemap
|
|
libraries.
|
|
|
|
In the past, for scripting languages, you would do checking something like:
|
|
|
|
if (ConvertPtr(obj,&vptr,ty,flags) != -1) {
|
|
// success
|
|
} else {
|
|
// error
|
|
}
|
|
|
|
Now the result state can carry more information,
|
|
including:
|
|
|
|
- Error state: like the old -1/0, but with error codes from swigerrors.swg.
|
|
|
|
int res = ConvertPtr(obj,&vptr,ty,flags);
|
|
if (SWIG_IsOK(res)) {
|
|
// success code
|
|
} else {
|
|
SWIG_Error(res); // res carries the error code
|
|
}
|
|
|
|
- Cast rank: when returning a simple successful
|
|
conversion, you just return SWIG_OK, but if you need
|
|
to do a 'cast', you can add the casting rank, ie:
|
|
|
|
if (PyFloat_Check(obj)) {
|
|
value = PyFloat_AsDouble(obj);
|
|
return SWIG_OK;
|
|
} else if (PyInt_Check(obj)) {
|
|
value = (double) PyInt_AsLong(obj);
|
|
return SWIG_AddCast(SWIG_OK);
|
|
}
|
|
|
|
later, the casting rank is used to properly dispatch
|
|
the overloaded function, for example. This of course
|
|
requires your language to support and use the new
|
|
dispatch cast/rank mechanism (Now mainly supported in
|
|
perl and python, and easily expandable to ruby and tcl).
|
|
|
|
- [UTL] Add support for the new 'expressive' result states.
|
|
|
|
12/27/2005: mmatus
|
|
- Add support for the C++ implicit conversion mechanism, which
|
|
required some modifications in parser.y (to recognize
|
|
'explicit') and overload.cxx (to replace $implicitconv as
|
|
needed).
|
|
|
|
Still, real support in each target language requires each
|
|
target language to be modified. Python provides an example,
|
|
see below.
|
|
|
|
|
|
- Add support for native C++ implicit conversions, ie, if you
|
|
have
|
|
|
|
%implicitconv A;
|
|
|
|
struct A {
|
|
int ii;
|
|
A() {ii = 1;}
|
|
A(int) {ii = 2;}
|
|
A(double) {ii = 3;}
|
|
explicit A(char *s) {ii = 4;}
|
|
};
|
|
|
|
int get(const A& a) {return a.ii;}
|
|
|
|
you can call:
|
|
|
|
a = A()
|
|
ai = A(1)
|
|
ad = A(1.0)
|
|
as = A("hello")
|
|
|
|
# old forms
|
|
get(a) -> 1
|
|
get(ai) -> 2
|
|
get(ad) -> 3
|
|
get(as) -> 4
|
|
|
|
#implicit conversions
|
|
get(1) -> 2
|
|
get(1.0) -> 3
|
|
get("hello") -> Error, explicit constructor
|
|
|
|
Also, as in C++, now implicit conversions are supported in
|
|
variable assigments, and if you have:
|
|
|
|
A ga;
|
|
struct Bar {
|
|
A a;
|
|
};
|
|
|
|
you can do:
|
|
|
|
cvar.ga = A(1)
|
|
cvar.ga = 1
|
|
cvar.ga = 1.0
|
|
cvar.ga = A("hello")
|
|
cvar.ga = "hello" -> error, explicit constructor
|
|
|
|
b = Bar()
|
|
b.a = A("hello")
|
|
b.a = 1
|
|
b.a = 1.0
|
|
b.a = "hello" -> error, explicit constructor
|
|
|
|
Note that the last case, assigning a member var directly,
|
|
also requires the 'naturalvar' option.
|
|
|
|
This support now makes the old '%implicit' macro, which
|
|
was found in 'implicit.i' and it was fragile in many ways,
|
|
obsolete, and you should use the new '%implicitconv'
|
|
directive instead.
|
|
|
|
Note that we follow the C++ conventions, ie, in the
|
|
following the implicit conversion is allowed:
|
|
|
|
int get(A a) {return a.ii;}
|
|
int get(const A& a) {return a.ii;}
|
|
|
|
but not in these cases:
|
|
|
|
int get(A *a) {return a->ii;}
|
|
int get(A& a) {return a.ii;}
|
|
|
|
Also, it works for director methods that return a by value
|
|
result, ie, the following will work:
|
|
|
|
virtual A get_a() = 0;
|
|
|
|
def get_a(self):
|
|
return 1
|
|
|
|
but not in this case:
|
|
|
|
virtual const A& get_a() = 0;
|
|
virtual A& get_a() = 0;
|
|
virtual A* get_a() = 0;
|
|
|
|
Notes:
|
|
|
|
- the implicitconv mechanism is implemented by directly
|
|
calling/dispatching the python constructor, triggering a
|
|
call to the __init__method. Hence, if you expanded the
|
|
__init__ method, like in:
|
|
|
|
class A:
|
|
def __init__(self,args):
|
|
<swig code>
|
|
<my code here>
|
|
|
|
then 'my code' will also be executed.
|
|
|
|
- Since the %implicitconv directive is a SWIG feature, if you type:
|
|
|
|
%implicitconv;
|
|
|
|
that will enable implicit conversion for all the classes in
|
|
your module.
|
|
|
|
But if you are worried about performance, maybe that will be
|
|
too much, especially if you have overloaded methods, since
|
|
to resolve the dispatching problem, python will efectively
|
|
try to call all the implicit constructors as needed.
|
|
|
|
- For the same reason, it is highly recommended that you use
|
|
the new 'castmode' when mixing implicit conversion and
|
|
overloading.
|
|
|
|
- [python] The %implicit directive is declared obsolete, and
|
|
you should use %implicitconv instead. If you include
|
|
the implicit.i file, a warning will remind you of this.
|
|
|
|
Note: Since %implicit is fragile, just replacing it by
|
|
%implicitconv could lead to different behavior. Hence, we
|
|
don't automatically switch from to the other, and the user
|
|
must migrate to the new %implicitconv directive manually.
|
|
|
|
|
|
12/26/2005: wsfulton
|
|
[C#]
|
|
Modify std::vector wrappers to use std::vector::value_type as this is
|
|
closer to the real STL declarations for some methods, eg for push_back().
|
|
Fixes some compilation errors for some compilers eg when the templated
|
|
type is a pointer.
|
|
|
|
[Java]
|
|
std::vector improvements - a few more methods are wrapped and specializations are
|
|
no longer required. The specialize_std_vector macro is no longer needed (a
|
|
warning is issued if an attempt is made to use it).
|
|
|
|
12/26/2005: wsfulton
|
|
[Java, C#]
|
|
Add in pointer reference typemaps. This also enables one to easily wrap
|
|
std::vector<T> where T is a pointer.
|
|
|
|
12/24/2005: efuzzyone
|
|
[CFFI] The cffi module for SWIG:
|
|
- Fully supports C, but provides limited supports for C++, in
|
|
particular C++ support for templates and overloading needs to
|
|
be worked upon.
|
|
|
|
12/23/2005: mmatus
|
|
[python] Add the castmode that allows the python
|
|
type casting to occur.
|
|
|
|
For example, if you have 'int foo(int)', now
|
|
|
|
class Ai():
|
|
def __init__(self,x):
|
|
self.x = x
|
|
def __int__(self):
|
|
return self.x
|
|
|
|
foo(1) // Ok
|
|
foo(1.0) // Ok
|
|
foo(1.3) // Error
|
|
a = Ai(4)
|
|
foo(ai) // Ok
|
|
|
|
The castmode, which can be enabled either with the
|
|
'-castmode' option or the %module("castmode") option, uses
|
|
the new cast/rank dispatch mechanism. Hence, now if you
|
|
have 'int foo(int); int foo(double);', the following works
|
|
as expected:
|
|
|
|
foo(1) -> foo(int)
|
|
foo(1.0) -> foo(double)
|
|
ai = Ai(4)
|
|
foo(ai) -> foo(int)
|
|
|
|
Note1: the 'castmode' could disrupt some specialized
|
|
typemaps. In particular, the "implicit.i" library seems to
|
|
have problem with the castmode. But besides that one, the
|
|
entire test-suite compiles fine with and without the
|
|
castmode.
|
|
|
|
Note2: the cast mode can't be combined with the fast
|
|
dispatch mode, ie, the -fastdispatch option has no effect
|
|
when the cast mode is selected. The penalties, however,
|
|
are minimum since the cast dispatch code is already based
|
|
on the same fast dispatch mechanism.
|
|
|
|
See the file overload_dispatch_cast_runme.py file for
|
|
new cases and examples.
|
|
|
|
12/22/2005: mmatus
|
|
Add the cast and rank mechanism to dispatch overloading
|
|
functions. The UTF supports it now, but for each language
|
|
it must be decided how to implement and/or when to use it.
|
|
|
|
[perl] Now perl uses the new cast and rank dispatch
|
|
mechanism, which solves all the past problems known
|
|
in perl, such as the old '+ 1' problem:
|
|
|
|
int foo(int);
|
|
|
|
$n = 1
|
|
$n = $n + 1
|
|
$r = foo(n)
|
|
|
|
also works:
|
|
|
|
foo(1);
|
|
foo("1");
|
|
foo(1.0);
|
|
foo("1.0");
|
|
|
|
but fails
|
|
|
|
foo("l");
|
|
|
|
and when overloading foo(int) and foo(double);
|
|
|
|
foo(1) -> foo(int)
|
|
foo(1.0) -> foo(double)
|
|
foo("1") -> foo(int)
|
|
foo("1.0") -> foo(double)
|
|
foo("l") -> error
|
|
foo($n) -> foo(int) for good perl versions
|
|
foo($n) -> foo(double) for old bad perl versions
|
|
|
|
when overloading foo(int), foo(char*) and foo(double):
|
|
|
|
foo(1) -> foo(int)
|
|
foo(1.0) -> foo(double)
|
|
foo("1") -> foo(char*)
|
|
foo("1.0") -> foo(char*)
|
|
foo("l") -> foo(char*)
|
|
|
|
Note: In perl the old dispatch mechanism was broken,
|
|
so, we don't provide an option to enable the old one
|
|
since, again, it was really really broken.
|
|
|
|
See 'overload_simple_runme.pl' for more cases and tests.
|
|
|
|
PS: all the old known issues are declared resolved, any
|
|
new "problem" that could be discovered is declared,
|
|
a priori, as "features" of the new dispatch mechanism
|
|
(until we find another solution at least).
|
|
|
|
|
|
*** POTENTIAL INCOMPATIBILITY ***
|
|
|
|
As with the introduction of the UTF, some things could
|
|
now start to work as expected, and people used to deal or
|
|
workaround previous bugs related to the dispatch
|
|
mechanism, could see now a difference in perl behavior.
|
|
|
|
12/21/2005: mmatus
|
|
- The '-nodefault' flag (pragma and feature) now generates
|
|
a warning, and recommends to use the explicit
|
|
-nodefaultctor and -nodefaultdtor options.
|
|
|
|
The reason to split the 'nodefault' behavior is that, in
|
|
general, ignoring the default destructor generates memory
|
|
leaks in the target language. Hence, is too risky just to
|
|
disable both the default constructor and destructor
|
|
at the same time.
|
|
|
|
If you need to disable the default destructor, it is
|
|
also recommended you use the directive form:
|
|
|
|
%nodefaultdtor MyVerySpecialClass;
|
|
|
|
for specific classes, and always avoid using the global
|
|
-nodefault and -nodefaultdtor options.
|
|
|
|
12/21/2005: wsfulton
|
|
[Java, C#]
|
|
Fix incorrect code generation when the intermediary classname is changed
|
|
in the module directive from its default. For example:
|
|
|
|
%module(jniclassname="myimclassnewname") "mymodule" // Java
|
|
%module(imclassname="myimclassnewname") "mymodule" // C#
|
|
|
|
Add in new special variable $imclassname. See docs.
|
|
|
|
12/17/2005: mmatus
|
|
[Python]
|
|
- Add the -aliasobj0/-noaliasobj0 options to use with
|
|
-fastunpack and/or -O and old typemaps that use 'obj0'
|
|
directly.
|
|
|
|
So, if you compile your code using -O and get errors about
|
|
the undeclared 'obj0' variable, run again using
|
|
|
|
swig -O -aliasobj0 -python ....
|
|
|
|
For new typemaps, never use 'obj0' directly, if needed,
|
|
use the '$self' name that will be properly expanded to
|
|
'obj0' (nofastunpack) or 'swig_obj[0]' (fastunpack).
|
|
|
|
If you have no idea what I am talking about, better, that
|
|
means you have no typemap with this problem.
|
|
|
|
|
|
12/14/2005: mmatus
|
|
[Python]
|
|
- Add the -fastunpack/-nofastunpack options to enable/disable
|
|
the use of the internal UnpackTuple method, instead of
|
|
calling the one from the python C API.
|
|
|
|
The option -O now also implies -fastunpack.
|
|
|
|
|
|
12/11/2005: mmatus
|
|
[Python]
|
|
- Add the -proxydel/-noproxydel options to enable/disable
|
|
the generation of proxy/shadow __del__ methods, even
|
|
when now they are redundant, since they are empty.
|
|
However, old interfaces could rely on calling them.
|
|
|
|
The default behavior is to generate the __del__ methods
|
|
as in 1.3.27 or older swig versions.
|
|
|
|
The option -O now also implies -noproxydel.
|
|
|
|
12/10/2005: mmatus
|
|
[UTF]
|
|
- Fix unneccessary calls to SWIG_TypeQuery for 'char *'
|
|
and 'wchar_t *', problem found by Clay Culver while
|
|
profiling the PyOgre project.
|
|
|
|
|
|
[Python]
|
|
- Add the -dirvtable/-nodirvtable to enable/disable
|
|
a pseudo virtual table used for directors, avoiding
|
|
the need to resolve the python method at each call.
|
|
|
|
- Add the -safecstrings/-nosafecstrings options to
|
|
enable/disable the use of safe conversions from PyString
|
|
to char *. Python requires you to never change the internal
|
|
buffer directly, and hence 'safectrings' warranties that
|
|
but returning a copy of the internal python string buffer.
|
|
|
|
The default, as in previous releases, is to return a
|
|
pointer to the buffer (nosafecstrings), so, it is the user's
|
|
responsibility to avoid its modification.
|
|
|
|
- Add the -O option to enable all the optimization options
|
|
at once, initially equivalent to
|
|
|
|
-modern -fastdispatch -dirvtable -nosafecstrings -fvirtual
|
|
|
|
12/08/2005: mmatus
|
|
|
|
- Add the -fastdispatch option (fastdispatch feature). This
|
|
enables the "fast dispatch" mechanism for overloaded
|
|
methods provided by Salvador Fandi~no Garc'ia (#930586).
|
|
|
|
The resulting code is smaller and faster since less type
|
|
checking is performed. However, the error messages you
|
|
get when the overloading is not resolved could be
|
|
different from what the traditional method returns.
|
|
|
|
With the old method you always get an error such as
|
|
|
|
"No matching function for overloaded ..."
|
|
|
|
with the new method you can also get errors such as
|
|
|
|
"Type error in argument 1 of type ..."
|
|
|
|
See bug report #930586 for more details.
|
|
|
|
So, this optimization must be explicitly enabled by users.
|
|
|
|
The new mechanism can be used as:
|
|
|
|
swig -fastdispatch
|
|
|
|
or using the feature form
|
|
|
|
%feature("fastdispatch") method;
|
|
or
|
|
%fastdispatch method;
|
|
|
|
|
|
12/06/2005: mmatus
|
|
|
|
- Several memory and speed improvements, specially for
|
|
templates. Now swig is up to 20 faster than before for
|
|
large template interfaces, such as the std_containers.i
|
|
and template_matrix.i files in the python test-suite.
|
|
|
|
Memory footprint is also reduced in consideration of small
|
|
pcs/architectures.
|
|
|
|
- add commandline options -cpperraswarn and -nocpperraswarn" to force
|
|
the swig preprocessor to treat the #error directive as a #warning.
|
|
|
|
the pragmas
|
|
|
|
#pragma SWIG cpperraswarn=1
|
|
#pragma SWIG cpperraswarn=0
|
|
|
|
are equivalent to the command line options, respectively.
|
|
|
|
|
|
12/06/2005: mmatus
|
|
[Python] The generated code is now more portable, especially
|
|
for Windows. Following
|
|
|
|
http://www.python.org/doc/faq/windows.html
|
|
|
|
Py_None is never accessed as a structure, plus other
|
|
tricks mentioned there.
|
|
|
|
12/06/2005: mmatus
|
|
[Python] Added initial support for threads based in the
|
|
proposal by Joseph Winston.
|
|
|
|
The user interface is as follows:
|
|
|
|
1.- the module thread support is enable via the "threads" module
|
|
option, i.e.
|
|
|
|
%module("threads"=1)
|
|
|
|
2.- Equivalent to that, is the new '-threads' swig option
|
|
|
|
swig -threads -python ...
|
|
|
|
3.- You can partially disable thread support for a given
|
|
method using:
|
|
|
|
%feature("nothread") method;
|
|
or
|
|
%nothread method;
|
|
|
|
also, you can disable sections of the thread support,
|
|
for example
|
|
|
|
%feature("nothreadblock") method;
|
|
or
|
|
%nothreadblock method;
|
|
|
|
%feature("nothreadallow") method;
|
|
or
|
|
%nothreadallow method;
|
|
|
|
the first disables the C++/python thread protection, and the
|
|
second disables the python/C++ thread protection.
|
|
|
|
4.- The current thread support is based in the PyGIL
|
|
extension present in python version 2.3 or later, but
|
|
you can provide the thread code for older versions by
|
|
defining the macros in pythreads.swg.
|
|
|
|
If you get a working implementation for older versions,
|
|
please send us a patch.
|
|
|
|
For the curious about performance, here are some numbers
|
|
for the profiletest.i test, which is used to check the speed
|
|
of the wrapped code:
|
|
|
|
nothread 9.6s (no thread code)
|
|
nothreadblock 12.2s (only 'allow' code)
|
|
nothreadallow 13.6s (only 'block' code)
|
|
full thread 15.5s ('allow' + 'block' code)
|
|
|
|
i.e., full thread code decreases the wrapping performance by
|
|
around 60%. If that is important to your application, you
|
|
can tune each method using the different 'nothread',
|
|
'nothreadblock' or 'nothreadallow' features as
|
|
needed. Note that for some methods deactivating the
|
|
'thread block' or 'thread allow' code is not an option,
|
|
so, be careful.
|
|
|
|
|
|
11/26/2005: wsfulton
|
|
SWIG library files use system angle brackets everywhere for %include, eg
|
|
%include "std_common.i"
|
|
becomes
|
|
%include <std_common.i>
|
|
|
|
11/26/2005: wsfulton
|
|
[Java, C#]
|
|
Typesafe enums and proper enums have an extra constructor so that enum item values that
|
|
are initialised by another enum item value can be wrapped without having to use %javaconstvalue/
|
|
%csconstvalue for when using %javaconst(1)/%csconst(1). Suggestion by
|
|
Bob Marinier/Douglas Pearson.
|
|
For example:
|
|
|
|
typedef enum
|
|
{
|
|
xyz,
|
|
last = xyz
|
|
} repeat;
|
|
|
|
11/21/2005: mmatus
|
|
[ruby + python]
|
|
|
|
Fixes for directors + pointers. This is an ugly problem without an easy
|
|
solution. Before we identified this case as problematic:
|
|
|
|
virtual const MyClass& my_method();
|
|
|
|
but it turns out that all the cases where a pointer, array or
|
|
reference is returned, are problematic, even for
|
|
primitive types (as int, double, char*, etc).
|
|
|
|
To try to fix the issue, a new typemap was added,
|
|
'directorfree', which is used to 'free' the resources
|
|
allocated during the 'directorout' phase. At the same
|
|
time, a primitive garbage collector engine was added to
|
|
deal with orphaned addresses, when needed.
|
|
|
|
The situation is much better now, but still it is possible to have
|
|
memory exhaustation if recursion is used.
|
|
|
|
So, still you need to avoid returning pointers, arrays or
|
|
references when using director methods.
|
|
|
|
- Added stdint.i - typemaps for latest C99 integral types found in stdint.h.
|
|
|
|
11/14/2005: wsfulton
|
|
More types added to windows.i, eg UINT8, WORD, BYTE etc.
|
|
Including windows.i will also enable SWIG to parse the __declspec Microsoft
|
|
extension, eg __declspec(dllimport). Also other Windows calling conventions
|
|
such as __stdcall.
|
|
|
|
11/10/2005: wsfulton
|
|
New library file for Windows - windows.i. This file will contain useful type
|
|
information for users who include windows.h. Initial support is for the
|
|
non ISO integral types: __int8, __int16, __int32, __int64 and unsigned versions.
|
|
The unsigned versions previously could not be parsed by SWIG. SF #872013.
|
|
|
|
11/09/2005: wsfulton
|
|
[Java, C#] Portability warning for files which will overwrite each other on case
|
|
insensitive file systems such as FAT32/NTFS. This will occur, for example, when two
|
|
class names are the same barring case. The warning is issued on all platforms and
|
|
can be suppressed with the usual warning suppression techniques. SF bug #1084507.
|
|
|
|
11/09/2005: wsfulton
|
|
./configure --with-python --with-ruby --with-perl5 etc enable these languages,
|
|
ie the --with-xxxx options, where no path is specified, work the same as if
|
|
the option was not specified at all. Based on patches #1335042 #1329048 #1329047.
|
|
|
|
11/09/2005: dancy
|
|
|
|
[Allegrocl]
|
|
Add C++ support to the Allegrocl module. Further
|
|
enhances the C support as well. Some of the
|
|
features:
|
|
|
|
- MUCH better generation of foreign types based on
|
|
the C/C++ types for use in defining the FFI on
|
|
the lisp side. We don't pass everything as a (* :void)
|
|
any longer.
|
|
|
|
- Uses typemaps for better control of type conversions
|
|
and code generation in the generated lisp and c++ wrapper
|
|
code.
|
|
|
|
- CLOS wrapping of pointers returned from foreign space
|
|
makes it easier to differentiate pointers in user code.
|
|
The wrapping objects can be passed directly to FF calls.
|
|
|
|
- Defun wrapping of FF calls, allowing for more lispy
|
|
interface. Conversion, GCing, of lisp objects to
|
|
foreign objects can be done in the wrapping defun via
|
|
the use of typemaps.
|
|
|
|
- overload dispatching implemented on the lisp side
|
|
using generic functions.
|
|
|
|
- Templates and synonymous types supported.
|
|
|
|
11/07/2005: mmatus
|
|
|
|
[Python] Adding proper support for multi-inheritance in
|
|
the python side, ie, if you have two C++ wrapped class, Foo
|
|
and Bar, now:
|
|
|
|
class MyPythonClass(Foo,Bar):
|
|
....
|
|
|
|
will properly work, even with directors, and the
|
|
deallocation of Foo.this and Bar.this will follow
|
|
correctly. Before, a class could only have one 'this'
|
|
instance (unlike C++), only the last base class was
|
|
properly deleted, or detected with directors.
|
|
|
|
Now 'self.this' can be a list, which will contain the C++
|
|
instance pointers for all the base classes.
|
|
|
|
Also, swig.this is responsible for deallocating the C++
|
|
instance(s), and the __del__ method is not emitted unless
|
|
the user preppend/append some code to it.
|
|
|
|
- Swig can now detect memory leaks, ie, if you still
|
|
don't use proxy/shadow classes, and type something like
|
|
|
|
import _example
|
|
f = _example.new_Foo()
|
|
|
|
and forget to call _example.delete_Foo(f), then swig will
|
|
tell you that there is a memory leak.
|
|
|
|
Otherwise, if you always use the proxy classes, you probably
|
|
you will never ever see this warning unless there is
|
|
something wrong inside the swig wrapping code.
|
|
|
|
|
|
*** POTENTIAL INCOMPATIBILITY ***
|
|
|
|
If you overloaded the __del__ method, and call the base
|
|
one without a try block, as in
|
|
|
|
class MyClass(SwigClass):
|
|
|
|
def __del__(self):
|
|
<your code here>
|
|
SwigClass.__del__(self)
|
|
|
|
python could complain that the method SwigClass.__del__ is
|
|
undefined. Try to use instead:
|
|
|
|
def __del__(self):
|
|
<your code here>
|
|
try: SwigClass.__del__(self)
|
|
except: pass
|
|
|
|
or simply
|
|
|
|
def __del__(self):
|
|
<your code here>
|
|
|
|
11/02/2005: mmatus
|
|
|
|
[Python] Adding more fun to STL/STD containers, now you
|
|
can do
|
|
|
|
%template(pyset) std::set<PyObject *>;
|
|
%template(pyvector) std::vector<PyObject *>;
|
|
%template() std::pair<PyObject *,PyObject *>;
|
|
%template(pyvector) std::map<PyObject *,PyObject *>;
|
|
....
|
|
|
|
The same applies to std::list, std::deque, std::multiset, etc.
|
|
|
|
Then, at the python side you can do now:
|
|
|
|
# C++ std::vector as native python sequence
|
|
v = pyvector([1,"hello",(1,2)])
|
|
print v[1]
|
|
>> 'hello'
|
|
print v[2]
|
|
>> (1,2)
|
|
|
|
# C++ std::set as native python sequence
|
|
s = pyset()
|
|
s.insert((1,2))
|
|
s.insert(1)
|
|
s.insert("hello")
|
|
sum=()
|
|
for i in s:
|
|
sum +=(i,)
|
|
print sum
|
|
>>> (1, 'hello', (1, 2))
|
|
|
|
# C++ std::map as native python sequence
|
|
m = pymap()
|
|
m["foo"] = "hello"
|
|
m[1] = (1,2)
|
|
pm = {}
|
|
for k in m:
|
|
pm[k] = m[k]
|
|
print pm
|
|
>>> {1: (1, 2), 'foo': 'hello'}
|
|
|
|
ie, the STD/STL containers work as real native python
|
|
container, with arbitrary item types and so.
|
|
|
|
But since normal C++ containers do not properly ref/unref
|
|
their items, you should use the safer versions:
|
|
|
|
%template(pyset) std::set<swig::PyObject_ptr>;
|
|
%template(pyvector) std::vector<swig::PyObject_ptr>;
|
|
%template() std::pair<swig::PyObject_ptr, swig::PyObject_ptr>;
|
|
%template(pyvector) std::map<swig::PyObject_ptr,swig::PyObject_ptr>;
|
|
....
|
|
|
|
where swig::PyObject_ptr is a PyObject * envelope class provided
|
|
to safely incref/decref the python object.
|
|
|
|
So, now you can use all the STL/STD containers as native
|
|
Python containers.
|
|
|
|
Note 1: std::map, std::set and the other 'ordered'
|
|
containers will properly use PyObject_Compare for sorting,
|
|
when needed.
|
|
|
|
Note 2: all the STL/STD containers have a limit size of
|
|
SIZE_MAX, ie, you can have manage containers larger than
|
|
INT_MAX, the python limit.
|
|
|
|
|
|
11/02/2005: mmatus
|
|
|
|
[Python]
|
|
- add 'iterator()' method for all sequences and additionally
|
|
'key_iterator()' for maps.
|
|
|
|
'iterator()' will always return the native C++ iterator.
|
|
Additionally, in maps, 'key_iterator()' will return a python
|
|
iterator using only the map keys.
|
|
|
|
In general the sequence method __iter__ will call
|
|
'iterator()', returning the native C++ iterator, but in
|
|
maps it will call 'key_iterator()', maintaining
|
|
backward compatibility.
|
|
|
|
Hence, for std::maps, you can play then with the native
|
|
C++ iterator, which value is a (key, value) pair, by
|
|
calling map.iterator(), as with map.begin(), map.end(), etc.
|
|
|
|
The difference is that map.iterator() returns a safe
|
|
'closed' iterator, while map.begin() and map.end() are
|
|
'open' iterators.
|
|
|
|
A 'closed' iterator knows the begin and the end of the
|
|
sequence, and it never can seg. fault. An 'open'
|
|
iterator, as in C++, can seg. fault at the C++ side.
|
|
|
|
# a closed iterator is safe in the following example.
|
|
# the next() method will throw a StopIteration
|
|
# exception as needed
|
|
|
|
i = seq.iterator()
|
|
try:
|
|
while True:
|
|
sum += i.next()
|
|
except: pass
|
|
|
|
# an open iterator always need to be checked,
|
|
# or it will crash at the C++ side
|
|
|
|
current = seq.begin()
|
|
end = seq.end()
|
|
while (current != end):
|
|
sum += current.next()
|
|
|
|
|
|
[Python]
|
|
- Finally, when we call
|
|
|
|
f = Foo()
|
|
|
|
the construction is 'one-way'. Before construction was done
|
|
something like
|
|
|
|
Foo() (python) -> _new_Foo() (C++)
|
|
new_Foo() (C++) -> FooPtr() (python)
|
|
FooPtr() (python) -> Foo() (python)
|
|
|
|
and returning a pointer was done like
|
|
|
|
NewPointerObj() (C++) -> FooPtr() (python)
|
|
FooPtr(python) -> Foo() (python)
|
|
|
|
|
|
ie, we when going back and forward between the C++ and
|
|
python side.
|
|
|
|
Now since there is no FooPtr the construction process is
|
|
|
|
Foo() (python) -> _new_Foo() (C++)
|
|
_new_Foo() (C++) -> NewPointerObj() (C++) (no shadow class)
|
|
|
|
and returning a pointer is done
|
|
|
|
NewPointerObj() (C++) (with shadow class) -> NewInstaceObj() (C++)
|
|
|
|
where NewInstanceObj creates a new instance without
|
|
calling __init__ and it doesn't go 'back' to python, is
|
|
'pure' C API.
|
|
|
|
- With this change, and the other ones in the
|
|
PySwigObject type, which now carries the thisown and
|
|
swig_type_info pointer, the generated code should be as
|
|
fast as boost::Python and/or the other python wrappers
|
|
based in pure Python/C API calls.
|
|
|
|
As a reference, the profiletest_runme.py example, which
|
|
does a simple call function many times, such as this code:
|
|
|
|
import profiletest
|
|
|
|
a = profiletest.A()
|
|
b = profiletest.B()
|
|
for i in range(0,1000000)
|
|
a = b.fn(a)
|
|
|
|
|
|
where fn is defined as 'A* B::fn(A *a) {return a;}',
|
|
produces the following times
|
|
|
|
nomodern modern
|
|
swig-1.3.26 19.70s 5.98s
|
|
swig-CVS 0.99s 0.98s
|
|
|
|
|
|
Clearly, there is a large improvement for the python
|
|
'nomodern' mode. Still, the 'modern' mode is around
|
|
6 times faster than before. For the same test, but
|
|
using the non-shadow version of the module, we get
|
|
|
|
_profiletest (non-shadow)
|
|
swig-1.3.26 0.80s
|
|
swig-CVS 0.60s
|
|
|
|
Hence, now for practical purposes, the proxy overhead
|
|
is insignificant.
|
|
|
|
Note that the performance numbers we are showing is for
|
|
a simple module (two types) and a simple function (one
|
|
argument). For real situations, for modules with many
|
|
more types and/or functions with many more parameters,
|
|
you will see even better results.
|
|
|
|
|
|
10/31/2005: mmatus
|
|
[Python]
|
|
|
|
- Finally, no more ClassPtr proxy classes. You will see
|
|
only a clean Class proxy class in the .py file.
|
|
|
|
- No more 'real' thisown attribute either, the PySwigObject now
|
|
carries the ownership info.
|
|
|
|
You can also do something like
|
|
|
|
print self.this.own()
|
|
>>> True
|
|
|
|
self.this.disown()
|
|
self.this.own(0)
|
|
print self.this.own()
|
|
>>> False
|
|
|
|
self.this.acquire()
|
|
self.this.own(1)
|
|
print self.this.own()
|
|
>>> True
|
|
|
|
Still the old way,
|
|
|
|
print self.thisown
|
|
>>> True
|
|
|
|
self.thisown = 0
|
|
print self.thisown
|
|
>>> False
|
|
|
|
self.thisown = 1
|
|
print self.thisown
|
|
>>> True
|
|
|
|
is supported, and python dispatches the proper method
|
|
calls as needed.
|
|
|
|
|
|
- Support for iterators in STL/STD containers, for example, if you have
|
|
|
|
%template<set_string> std::set<std::string>;
|
|
|
|
you can use the C++ iterators as:
|
|
|
|
s = set_string()
|
|
|
|
s.append("c")
|
|
s.append("a")
|
|
s.append("b")
|
|
|
|
b = s.begin()
|
|
e = s.end()
|
|
sum = ""
|
|
while (b != e):
|
|
sum += b.next()
|
|
print sum
|
|
|
|
>>> "abc"
|
|
|
|
advance the iterator as in C++
|
|
|
|
current = s.begin()
|
|
current += 1
|
|
print current.value()
|
|
>>> "b"
|
|
|
|
now using the reverse operators
|
|
|
|
b = s.rbegin()
|
|
e = s.rend()
|
|
sum = ""
|
|
while (b != e):
|
|
sum += b.next()
|
|
print sum
|
|
|
|
>>> "cba"
|
|
|
|
or the 'previous' method
|
|
|
|
b = s.begin()
|
|
e = s.end()
|
|
sum = ""
|
|
while (b != e):
|
|
sum += e.previous()
|
|
print sum
|
|
|
|
>>> "cba"
|
|
|
|
or just as in a python fashion
|
|
|
|
for i in s:
|
|
sum += i
|
|
|
|
Note 1: Iterators in C++ are very powerful, but
|
|
dangerous too. And in python you can shoot yourself in the foot
|
|
just like in C++, so, be careful.
|
|
|
|
Note 2: the iterators are 'light', ie, they do not
|
|
convert sequence elements until you request to do so, via
|
|
next(), value() or previous(). If you just increment/decrement one
|
|
no conversion is performed, for example:
|
|
|
|
|
|
b = s.begin()
|
|
b += 1
|
|
b.incr()
|
|
b.incr(2)
|
|
b.decr(2)
|
|
b.decr()
|
|
b -= 1
|
|
|
|
only the iterator is modified, and not value wrapper
|
|
is generated. Other typical C++ operations are also
|
|
available, such as:
|
|
|
|
print s.end() - s.begin()
|
|
>>> 3
|
|
f = s.begin() + 1
|
|
print f.value()
|
|
>>> "b"
|
|
l = s.end() - 1
|
|
print l.value()
|
|
>>> "c"
|
|
|
|
etc. Of course, the 'find', 'insert', 'erase', and
|
|
so on methods also supports iterators now, ie:
|
|
|
|
i = s.begin()
|
|
i += 1
|
|
s.erase(i)
|
|
for i in s:
|
|
sum += i
|
|
print sum
|
|
>>> "ac"
|
|
|
|
*** POTENTIAL INCOMPATIBILITY ***
|
|
|
|
There is no more 'thisown' attribute. If you use it, python
|
|
will translate the following code as follows:
|
|
|
|
if (self.thisown): ==> if (self.this.own()):
|
|
self.thisown = 1 ==> self.this.own(1)
|
|
self.thisown = 0 ==> self.this.own(0)
|
|
|
|
Still, maybe in some unusual cases the translation will not be
|
|
100% correct, so if you have a problem, please report it
|
|
and/or use the new 'self.this.own()' accessor.
|
|
|
|
|
|
*** POTENTIAL INCOMPATIBILITY ***
|
|
|
|
There is no more ClassPtr classes in the python code. Hence,
|
|
if in the past you needed to resort to some kind of trickery
|
|
with them, or overcome their presence, it is no longer
|
|
required, but the extra code you added could now break
|
|
things.
|
|
|
|
If needed, you can use the option -classptr, i.e.,
|
|
|
|
swig -classptr -python ...
|
|
|
|
to generate the old ClassPtr classes.
|
|
|
|
|
|
10/30/2005: mkoeppe
|
|
[Guile] Make declared and defined linkage of SWIG_init consistent.
|
|
Reported by Steven G. Johnson (SF patch 1315498).
|
|
|
|
10/26/2005: mmatus
|
|
|
|
- Added the attribute.i file to the global library director.
|
|
Now it can be used from other languages that do not use
|
|
the unified typemap library as well.
|
|
|
|
So, if you have something like:
|
|
|
|
%include attribute.i
|
|
|
|
%attribute(A, int, a, get_a, set_a);
|
|
|
|
struct A
|
|
{
|
|
int get_a() const;
|
|
void set_a(int aa);
|
|
};
|
|
|
|
%attribute_ref(B, int, c);
|
|
|
|
struct B
|
|
{
|
|
int& c();
|
|
};
|
|
|
|
then in the target language the 'A.a' and 'B.c' attributes will
|
|
be visible, ie, you can access them as plain variables:
|
|
|
|
f = A()
|
|
f.a = 3
|
|
g = B()
|
|
g.c = 3
|
|
|
|
h = f.a + g.c
|
|
|
|
and the proper get/set methods will be dispatched. See
|
|
attribute.i for more info.
|
|
|
|
- More cleanups around and adding more test-cases. The
|
|
DISOWN typemap now is tested and working in all the
|
|
languages that use the unified typemap library, ie, tcl,
|
|
ruby, perl and python.
|
|
|
|
|
|
10/25/2005: mmatus
|
|
|
|
- Perl, complete the DISOWN typemap.
|
|
|
|
- added the attribute.i file to the unified typemap
|
|
library (before was only usable from python).
|
|
|
|
- unify the names for the setter and getter methods in
|
|
perl,tcl,ruby and python, so, the attribute.i library
|
|
can work across them.
|
|
|
|
- see the li_attribute.i test-case or the library file
|
|
|
|
Lib/typemaps/attribute.swg
|
|
|
|
for more info about how to use it.
|
|
|
|
|
|
|
|
|
|
10/24/2005: mmatus
|
|
|
|
- Perl now uses the unified typemap library.
|
|
|
|
- Changes in ruby to use the $track option in typemaps.
|
|
|
|
- Changes in the unified typemap library to follow the
|
|
convention that all macros that are not used in the
|
|
C/C++ side starts with %, such as
|
|
|
|
%delete
|
|
%new_array
|
|
|
|
etc.
|
|
|
|
- Documenting fragments, see fragments.swg.
|
|
|
|
- Cleaner way to use the unified typemap library, include
|
|
just <typemaps/swigtypes.swg>.
|
|
|
|
Check some of the supported languages: perl, tcl, ruby,
|
|
python.
|
|
|
|
Always start with the head file, such as
|
|
|
|
python/python.swg
|
|
tcl/tcl8.swg
|
|
ruby/ruby.swg
|
|
perl5/perl5.swg
|
|
|
|
and the principal file that invokes the unified library, such as
|
|
|
|
python/pytypemaps.swg
|
|
tcl/tcltypemaps.swg
|
|
ruby/rubytypemaps.swg
|
|
perl/perltypemaps.swg
|
|
|
|
The file that provide the specialization for each
|
|
language are the one that provides the basic types:
|
|
|
|
python/pyprimtypes.swg
|
|
ruby/rubyprimtypes.swg
|
|
tcl/tclprimtypes.swg
|
|
perl5/perlprimtypes.swg
|
|
|
|
and the string manipulation:
|
|
|
|
python/pystrings.swg
|
|
ruby/rubystrings.swg
|
|
tcl/tclstrings.swg
|
|
perl5/perlstrings.swg
|
|
|
|
|
|
The rest of the files, such as carray.i, are mostly one
|
|
line files that include the proper typemap library
|
|
version.
|
|
|
|
*** POTENTIAL INCOMPATIBILITY in Perl ***
|
|
|
|
Some missing/wrong typemaps could start working properly,
|
|
and change the old expected behavior in Perl.
|
|
|
|
10/23/2005: wuzzeb
|
|
Chicken:
|
|
+ pointers to member functions finally work properly
|
|
+ add test of member function pointers to cpp_basic.i
|
|
|
|
10/20/2005: dancy
|
|
[allegrocl] Added C++ support. Large update, many changes. See
|
|
newly added Allegro Common Lisp section in lisp.html
|
|
|
|
10/20/2005: mmatus
|
|
Ruby, Tcl, Python:
|
|
|
|
- Uniform way to fail (label fail:), now finally
|
|
SWIG_exception works across the three languages and all
|
|
the typemaps.
|
|
|
|
- Add proper cleanup code to ruby
|
|
|
|
- More valgrind fixes
|
|
|
|
- Simplify the inline use, it seems a small interface of
|
|
20,000 lines (plus many many templates) can break
|
|
gcc -O3 easily.
|
|
|
|
- Finalize the typemaps library. All the old *.i files
|
|
(carray.i, cpointer.i, exception.i) had been implemented
|
|
in the new typemaps library.
|
|
|
|
|
|
10/19/2005: wuzzeb
|
|
Update the Runtime Typemap documentation in Typemaps.html
|
|
|
|
10/18/2005: wuzzeb
|
|
Chicken:
|
|
- Correctly handle %ignored classes
|
|
- Correctly convert long, long long, unsigned long, etc
|
|
to chicken primitives. (Thanks to Felix Winkelmann)
|
|
- Using argout parameters when the return value was a
|
|
wrapped pointer caused a memory corruption. The chicken
|
|
garbage collector moved a pointer out from under us.
|
|
This is now fixed by running all the proxy creation
|
|
functions as continuations after the wrapper function
|
|
returns. As part of this, we no longer need the
|
|
chickenfastproxy flag on output typemaps.
|
|
- using -proxy and -nocollection together works now
|
|
Before, it was not exporting the destructor in the proxy
|
|
wrapper.
|
|
|
|
10/18/2005: mmatus
|
|
|
|
Added the Unified Typemap Library (UTL). It unifies the typemaps for
|
|
|
|
python, ruby, tcl
|
|
|
|
and in the process, fixes several problems in each of the three
|
|
languages to work in a "canonical" way now established in
|
|
the typemap library
|
|
|
|
SWIG/Lib/typempas
|
|
|
|
The current status of the unification is that everything
|
|
compiles and runs inside the test-suite and examples
|
|
directories. And for the first time we have three
|
|
languages than pass the primitive_types.i case.
|
|
|
|
Also, we have a uniform way to treat the errors, for example
|
|
if you do something like
|
|
|
|
>>> from primitive_types import *
|
|
>>> print val_uchar(10)
|
|
10
|
|
>>> print val_uchar(1000)
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
OverflowError: in argument 1 of type 'unsigned char'
|
|
|
|
you get the same exception in all the three languages.
|
|
|
|
And well, many more good things will come from this
|
|
unification, for example, proper support of the STL/STD classes
|
|
for all the languages, and hopefully, we can keep
|
|
adding other languages.
|
|
|
|
The hardest part, writing a common typemap library
|
|
that suites the three different languages, is done,
|
|
and adding another language should now be easy.
|
|
|
|
Still the global unification is not complete, the STL/STD
|
|
part is next, and probably as well as adding one or two more
|
|
languages.
|
|
|
|
If you are curious, look at the python, ruby and/or tcl
|
|
directories to see what is needed to support the new
|
|
common typemaps library. Still, the final way to
|
|
integrate a new language could change as we move to
|
|
integrate the STD/STL.
|
|
|
|
*** POTENTIAL INCOMPATIBILITY in Ruby/Tcl ***
|
|
|
|
Some missing/wrong typemaps could start working properly,
|
|
and change the old behavior, specially in ruby and tcl.
|
|
|