Version 1.3.28 (unreleased). =========================== 01/30/2006: wsfulton std::string and std::wstring member variables and global variables now use %naturalvar by default, meaning they will now be wrapped as expected in all languages. Previously these were wrapped as a pointer rather than a target language string. It is no longer necessary to add the following workaround to wrap these as strings: %apply const std::string & { std::string *} *** POTENTIAL INCOMPATIBILITY *** 01/28/2006: mkoeppe [Guile -scm] Add typemaps for handling of member function pointers. 01/24/2006: mmatus - Better support for the %naturalvar directive, now it works with the scripting languages as well as Java/C#. Now, it can also be applied to class types: %naturalvar std::string; %include that will tell swig to use the the 'natural' wrapping mechanism to all std::string global and member variables. - Add support for the %allowexcept feature along the scripting languages, which allows the %exception feature to be applied to the variable access methods. Also, add the %exceptionvar directive to specify a distintic exception mechanism only for variables. - Add more docs for the %delobject directive to mark a method as a destructor, 'disowning' the first argument. For example: %newobject create_foo; %delobject destroy_foo; Foo *create_foo() { return new Foo(); } void destroy_foo(Foo *foo) { delete foo; } or in a member method as: %delobject Foo::destroy; class Foo { public: void destroy() { delete this;} private: ~Foo(); }; 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 (thanks to Jason Rego for this observation) 01/16/2006: mmatus (Change disabled... will be back in CVS soon) 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) { ; } 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:)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("%()",match="cdecl") ""; %rename("%()",match="enumitem") ""; %rename("%()",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 -> 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): 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 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 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): SwigClass.__del__(self) python could complain that the method SwigClass.__del__ is undefined. Try to use instead: def __del__(self): try: SwigClass.__del__(self) except: pass or simply def __del__(self): 11/02/2005: mmatus [Python] Adding more fun to STL/STD containers, now you can do %template(pyset) std::set; %template(pyvector) std::vector; %template() std::pair; %template(pyvector) std::map; .... 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; %template(pyvector) std::vector; %template() std::pair; %template(pyvector) std::map; .... 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 std::set; 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 . 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 "", 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.